Zserio C++17 runtime library  1.1.0
Built for Zserio 2.18.1
Optional.h
Go to the documentation of this file.
1 #ifndef ZSERIO_OPTIONAL_H_INC
2 #define ZSERIO_OPTIONAL_H_INC
3 
4 #include <optional>
5 
8 #include "zserio/HashCodeUtil.h"
9 #include "zserio/Traits.h"
10 #include "zserio/View.h"
11 
12 namespace zserio
13 {
14 
15 template <typename ALLOC, typename T>
16 class BasicOptional;
17 
18 namespace detail
19 {
20 
21 template <typename T, bool = (sizeof(T) > 3 * sizeof(void*))>
22 struct is_optional_big : std::false_type
23 {};
24 
25 template <typename T>
26 struct is_optional_big<T, true> : std::true_type
27 {};
28 
29 template <typename T, typename = void>
30 struct is_recursive : std::false_type
31 {};
32 
33 template <typename T>
34 struct is_recursive<T, std::void_t<typename T::IS_RECURSIVE>> : std::true_type
35 {};
36 
37 template <typename T, bool = is_recursive<T>::value>
38 struct is_optional_heap_allocated_impl : is_optional_big<T>::type
39 {};
40 
41 template <typename T>
42 struct is_optional_heap_allocated_impl<T, true> : std::true_type
43 {};
44 
45 template <typename T>
46 struct is_optional_heap_allocated : is_optional_heap_allocated_impl<T>
47 {};
48 
49 template <typename T>
50 struct is_optional_heap_allocated<View<T>> : std::false_type
51 {};
52 
53 template <typename T>
54 constexpr bool is_optional_heap_allocated_v = is_optional_heap_allocated<T>::value;
55 
56 template <typename T, bool heap = is_optional_heap_allocated_v<T>>
57 struct optional_element
58 {
59  using type = T;
60 };
61 
62 template <typename T>
63 struct optional_element<T, true>
64 {
65  using type = T*;
66 };
67 
68 template <typename T>
69 struct is_optional : std::false_type
70 {};
71 
72 template <typename A, typename T>
73 struct is_optional<BasicOptional<A, T>> : std::true_type
74 {};
75 
76 template <typename T>
77 constexpr bool is_optional_v = is_optional<T>::value;
78 
79 } // namespace detail
80 
85 {
86 public:
88 
89  ~BadOptionalAccess() override;
90 };
91 
106 template <typename ALLOC, typename T>
107 class BasicOptional : public AllocatorHolder<ALLOC>
108 {
109  using AllocTraits = std::allocator_traits<ALLOC>;
111 
112 public:
114  using allocator_type = ALLOC;
115  using OptionalType = std::optional<typename detail::optional_element<T>::type>;
116 
120  constexpr BasicOptional() noexcept :
121  BasicOptional(ALLOC())
122  {}
123 
127  constexpr BasicOptional(std::nullopt_t, const ALLOC& allocator = {}) noexcept :
128  BasicOptional(allocator)
129  {}
130 
137  constexpr BasicOptional(const T& value, const ALLOC& allocator = {}) :
138  BasicOptional(std::in_place, allocator, value)
139  {}
140 
147  constexpr BasicOptional(T&& value, const ALLOC& allocator = {}) :
148  BasicOptional(std::in_place, allocator, std::move(value))
149  {}
150 
156  explicit constexpr BasicOptional(const ALLOC& allocator) :
157  AllocatorHolder<ALLOC>(allocator)
158  {}
159 
168  template <typename... ARGS, typename TT = T,
169  std::enable_if_t<!detail::is_optional_heap_allocated_v<TT>>* = nullptr,
170  std::enable_if_t<!is_first_allocator<ARGS...>::value>* = nullptr>
171  explicit constexpr BasicOptional(std::in_place_t, ARGS&&... args) :
172  m_data(std::in_place, std::forward<ARGS>(args)...)
173  {}
174 
184  template <typename... ARGS, typename TT = T,
185  std::enable_if_t<!detail::is_optional_heap_allocated_v<TT>>* = nullptr>
186  constexpr BasicOptional(std::in_place_t, const ALLOC& allocator, ARGS&&... args) :
187  AllocatorHolder<ALLOC>(allocator),
188  m_data(std::in_place, std::forward<ARGS>(args)...)
189  {}
190 
200  template <typename... ARGS, typename TT = T,
201  std::enable_if_t<detail::is_optional_heap_allocated_v<TT>>* = nullptr>
202  constexpr BasicOptional(std::in_place_t, const ALLOC& allocator, ARGS&&... args) :
203  AllocatorHolder<ALLOC>(allocator),
204  m_data(std::in_place, allocateValue(std::forward<ARGS>(args)...))
205  {}
206 
215  template <typename... ARGS, typename TT = T,
216  std::enable_if_t<detail::is_optional_heap_allocated_v<TT>>* = nullptr,
217  std::enable_if_t<!is_first_allocator<ARGS...>::value>* = nullptr>
218  explicit constexpr BasicOptional(std::in_place_t, ARGS&&... args) :
219  m_data(std::in_place, allocateValue(std::forward<ARGS>(args)...))
220  {}
221 
226  {
227  clear();
228  }
229 
235  constexpr BasicOptional(const BasicOptional& other) :
236  AllocatorHolder<ALLOC>(
237  AllocTraits::select_on_container_copy_construction(other.get_allocator_ref()))
238  {
239  copy(other);
240  }
241 
247  template <typename U>
248  constexpr BasicOptional(const BasicOptional<ALLOC, U>& other) :
249  AllocatorHolder<ALLOC>(
250  AllocTraits::select_on_container_copy_construction(other.get_allocator_ref()))
251  {
252  copy(other);
253  }
254 
263  constexpr BasicOptional(const BasicOptional& other, const ALLOC& allocator) :
264  AllocatorHolder<ALLOC>(allocator)
265  {
266  copy(other);
267  }
268 
277  template <typename A, typename U>
278  constexpr BasicOptional(const BasicOptional<A, U>& other, const ALLOC& allocator) :
279  AllocatorHolder<ALLOC>(allocator)
280  {
281  copy(other);
282  }
283 
293  constexpr BasicOptional& operator=(const BasicOptional& other)
294  {
295  if (this != &other)
296  {
297  clear();
298  if constexpr (AllocTraits::propagate_on_container_copy_assignment::value)
299  {
301  }
302  copy(other);
303  }
304 
305  return *this;
306  }
307 
317  template <typename A, typename U>
319  {
320  clear();
321  if constexpr (AllocTraits::propagate_on_container_copy_assignment::value)
322  {
324  }
325  copy(other);
326 
327  return *this;
328  }
329 
335  BasicOptional& operator=(std::nullopt_t)
336  {
337  reset();
338  return *this;
339  }
340 
348  template <typename U = T,
349  std::enable_if_t<!detail::is_optional_v<std::decay_t<U>> &&
350  !(std::is_same_v<T, std::decay_t<U>> && std::is_scalar_v<U>)>* = nullptr>
351  BasicOptional& operator=(U&& value)
352  {
353  emplace(std::forward<U>(value));
354  return *this;
355  }
356 
365  AllocatorHolder<ALLOC>(std::move(other.get_allocator_ref()))
366  {
367  move(std::move(other));
368  }
369 
378  BasicOptional(BasicOptional&& other, const ALLOC& allocator) :
379  AllocatorHolder<ALLOC>(allocator)
380  {
381  move(std::move(other));
382  }
383 
392  {
393  if (this != &other)
394  {
395  clear();
396  if constexpr (AllocTraits::propagate_on_container_move_assignment::value)
397  {
398  set_allocator(std::move(other.get_allocator_ref()));
399  }
400  move(std::move(other));
401  }
402 
403  return *this;
404  }
405 
411  template <typename U>
413  AllocatorHolder<ALLOC>(std::move(other.get_allocator_ref()))
414  {
415  move(std::move(other));
416  }
417 
424  template <typename U>
425  constexpr BasicOptional(BasicOptional<ALLOC, U>&& other, const ALLOC& allocator) :
426  AllocatorHolder<ALLOC>(allocator)
427  {
428  move(std::move(other));
429  }
430 
438  template <typename U>
440  {
441  static_assert(!std::is_same_v<T, U>);
442 
443  clear();
444  if constexpr (AllocTraits::propagate_on_container_move_assignment::value)
445  {
446  set_allocator(std::move(other.get_allocator_ref()));
447  }
448  move(std::move(other));
449  return *this;
450  }
451 
457  constexpr bool has_value() const noexcept
458  {
459  if (!m_data.has_value())
460  {
461  return false;
462  }
463  if constexpr (detail::is_optional_heap_allocated_v<T>)
464  {
465  if (!m_data.value())
466  {
467  return false;
468  }
469  }
470  return true;
471  }
472 
476  void reset()
477  {
478  clear();
479  m_data.reset();
480  }
481 
487  void swap(BasicOptional& other)
488  {
489  m_data.swap(other.m_data);
490  if constexpr (AllocTraits::propagate_on_container_swap::value)
491  {
492  using std::swap;
494  }
495  }
496 
502  constexpr explicit operator bool() const noexcept
503  {
504  return has_value();
505  }
506 
514  template <typename... ARGS>
515  T& emplace(ARGS&&... args)
516  {
517  clear();
518  if constexpr (detail::is_optional_heap_allocated_v<T>)
519  {
520  T* ptr = allocateValue(std::forward<ARGS>(args)...);
521  return *m_data.emplace(ptr);
522  }
523  else
524  {
525  return m_data.emplace(std::forward<ARGS>(args)...);
526  }
527  }
528 
536  constexpr T& value() &
537  {
538  if (!has_value())
539  {
540  throw BadOptionalAccess("Optional is empty");
541  }
542  if constexpr (detail::is_optional_heap_allocated_v<T>)
543  {
544  return *m_data.value();
545  }
546  else
547  {
548  return m_data.value();
549  }
550  }
551 
559  constexpr T&& value() &&
560  {
561  return std::move(value());
562  }
563 
571  constexpr const T& value() const&
572  {
573  if (!has_value())
574  {
575  throw BadOptionalAccess("Optional is empty");
576  }
577  if constexpr (detail::is_optional_heap_allocated_v<T>)
578  {
579  return *m_data.value();
580  }
581  else
582  {
583  return m_data.value();
584  }
585  }
586 
594  constexpr const T&& value() const&&
595  {
596  return std::move(value());
597  }
598 
606  T& operator*() &
607  {
608  return value();
609  }
610 
618  T&& operator*() &&
619  {
620  return std::move(value());
621  }
622 
630  const T& operator*() const&
631  {
632  return value();
633  }
634 
642  const T&& operator*() const&&
643  {
644  return std::move(value());
645  }
646 
655  {
656  return &value();
657  }
658 
666  const T* operator->() const
667  {
668  return &value();
669  }
670 
678  template <typename U>
679  T value_or(U&& def)
680  {
681  if (!has_value())
682  {
683  return static_cast<T>(std::forward<U>(def));
684  }
685  return value();
686  }
687 
695  template <typename U>
696  T value_or(U&& def) const
697  {
698  if (!has_value())
699  {
700  return static_cast<T>(std::forward<U>(def));
701  }
702  return value();
703  }
704 
705 private:
706  // enables move(BasicOptional<ALLOC, U>&&) implementation to access m_data
707  template <typename A, typename U>
708  friend class BasicOptional;
709 
710  template <typename... ARGS>
711  T* allocateValue(ARGS&&... args)
712  {
713  using MyAllocType = RebindAlloc<ALLOC, T>;
714  using MyAllocTraits = std::allocator_traits<MyAllocType>;
715  MyAllocType typedAlloc = get_allocator_ref();
716  auto ptr = MyAllocTraits::allocate(typedAlloc, 1);
717  try
718  {
719  MyAllocTraits::construct(typedAlloc, std::addressof(*ptr), std::forward<ARGS>(args)...);
720  }
721  catch (...)
722  {
723  MyAllocTraits::deallocate(typedAlloc, ptr, 1);
724  throw;
725  }
726  return ptr;
727  }
728 
729  // same as for std::Optional throwing dtors are not supported see
730  // https://stackoverflow.com/questions/78602733/should-stdOptional-be-nothrow-destructible-when-its-alternative-has-potentially
731  void destroyValue(T* ptr)
732  {
733  if (ptr)
734  {
735  using MyAllocType = RebindAlloc<ALLOC, T>;
736  using MyAllocTraits = std::allocator_traits<MyAllocType>;
737  MyAllocType typedAlloc = get_allocator_ref();
738  MyAllocTraits::destroy(typedAlloc, ptr);
739  MyAllocTraits::deallocate(typedAlloc, ptr, 1);
740  }
741  }
742 
743  template <typename A, typename U>
744  void copy(const BasicOptional<A, U>& other)
745  {
746  // assumes this holder is cleared
747 
748  if (!other.has_value())
749  {
750  reset();
751  }
752  else
753  {
754  emplace(other.value());
755  }
756  }
757 
758  void move(BasicOptional&& other)
759  {
760  // assumes this holder is cleared
761 
762  if (!other.has_value())
763  {
764  reset();
765  }
766  else
767  {
768  if constexpr (detail::is_optional_heap_allocated_v<T>)
769  {
770  if (get_allocator_ref() == other.get_allocator_ref())
771  {
772  // non-standard optimization to reuse memory from the same resource
773  // note that other will be unset after move in this case
774  auto& ptr = other.m_data.value();
775  m_data.emplace(ptr);
776  ptr = nullptr;
777  }
778  else
779  {
780  auto& value = *other.m_data.value();
781  T* ptr = allocateValue(std::move(value));
782  m_data.emplace(ptr);
783  }
784  }
785  else // not on heap
786  {
787  auto& value = other.m_data.value();
788  m_data.emplace(std::move(value));
789  }
790  }
791  }
792 
793  template <typename U>
794  void move(BasicOptional<ALLOC, U>&& other)
795  {
796  // assumes this holder is cleared
797  static_assert(!std::is_same_v<T, U>);
798 
799  if (!other.has_value())
800  {
801  reset();
802  }
803  else
804  {
805  if constexpr (detail::is_optional_heap_allocated_v<T> && detail::is_optional_heap_allocated_v<U>)
806  {
807  auto& value = *other.m_data.value();
808  T* ptr = allocateValue(std::move(value));
809  m_data.emplace(ptr);
810  }
811  else if constexpr (detail::is_optional_heap_allocated_v<T>) // only T on heap
812  {
813  auto& value = other.m_data.value();
814  T* ptr = allocateValue(std::move(value));
815  m_data.emplace(ptr);
816  }
817  else if constexpr (detail::is_optional_heap_allocated_v<U>) // only U is on heap
818  {
819  auto& value = *other.m_data.value();
820  m_data.emplace(std::move(value));
821  }
822  else // both not on heap
823  {
824  auto& value = other.m_data.value();
825  m_data.emplace(std::move(value));
826  }
827  }
828  }
829 
830  void clear()
831  {
832  if (!has_value())
833  {
834  return;
835  }
836  if constexpr (detail::is_optional_heap_allocated_v<T>)
837  {
838  auto& ptr = m_data.value();
839  destroyValue(ptr);
840  ptr = nullptr;
841  }
842  }
843 
844  OptionalType m_data;
845 };
846 
847 // Using declarations
848 
849 template <typename T>
851 
860 template <typename ALLOC, typename T>
861 uint32_t calcHashCode(uint32_t seed, const BasicOptional<ALLOC, T>& opt)
862 {
863  uint32_t result = seed;
864  if (opt)
865  {
866  result = calcHashCode(result, *opt);
867  }
868  return result;
869 }
870 
878 template <typename T>
879 constexpr auto make_optional(T&& value)
880 {
881  return Optional<std::decay_t<T>>(std::forward<T>(value));
882 }
883 
891 template <typename T, typename... ARGS>
892 constexpr Optional<T> make_optional(ARGS&&... args)
893 {
894  return Optional<T>(std::in_place, std::forward<ARGS>(args)...);
895 }
896 
905 template <typename A1, typename T, typename A2, typename U>
906 constexpr bool operator==(const BasicOptional<A1, T>& first, const BasicOptional<A2, U>& second)
907 {
908  if (first.has_value() && second.has_value())
909  {
910  return first.value() == second.value();
911  }
912  return first.has_value() == second.has_value();
913 }
914 
922 template <typename A, typename T>
923 constexpr bool operator==(const BasicOptional<A, T>& opt, std::nullopt_t)
924 {
925  return !opt.has_value();
926 }
927 
935 template <typename A, typename T>
936 constexpr bool operator==(std::nullopt_t, const BasicOptional<A, T>& opt)
937 {
938  return !opt.has_value();
939 }
940 
949 template <typename A, typename T, typename U>
950 constexpr bool operator==(const BasicOptional<A, T>& opt, const U& value)
951 {
952  return opt.has_value() && opt.value() == value;
953 }
954 
963 template <typename A, typename T, typename U>
964 constexpr bool operator==(const U& value, const BasicOptional<A, T>& opt)
965 {
966  return opt.has_value() && opt.value() == value;
967 }
968 
977 template <typename A1, typename T, typename A2, typename U>
978 constexpr bool operator!=(const BasicOptional<A1, T>& first, const BasicOptional<A2, U>& second)
979 {
980  return !(first == second);
981 }
982 
990 template <typename A, typename T>
991 constexpr bool operator!=(const BasicOptional<A, T>& opt, std::nullopt_t)
992 {
993  return !(opt == std::nullopt);
994 }
995 
1003 template <typename A, typename T>
1004 constexpr bool operator!=(std::nullopt_t, const BasicOptional<A, T>& opt)
1005 {
1006  return !(std::nullopt == opt);
1007 }
1008 
1017 template <typename A, typename T, typename U>
1018 constexpr bool operator!=(const BasicOptional<A, T>& opt, const U& value)
1019 {
1020  return !(opt == value);
1021 }
1022 
1031 template <typename A, typename T, typename U>
1032 constexpr bool operator!=(const U& value, const BasicOptional<A, T>& opt)
1033 {
1034  return !(value == opt);
1035 }
1036 
1045 template <typename A1, typename T, typename A2, typename U>
1046 constexpr bool operator<(const BasicOptional<A1, T>& first, const BasicOptional<A2, U>& second)
1047 {
1048  if (first.has_value() && second.has_value())
1049  {
1050  return first.value() < second.value();
1051  }
1052  return first.has_value() < second.has_value();
1053 }
1054 
1062 template <typename A, typename T>
1063 constexpr bool operator<(const BasicOptional<A, T>&, std::nullopt_t)
1064 {
1065  return false;
1066 }
1067 
1075 template <typename A, typename T>
1076 constexpr bool operator<(std::nullopt_t, const BasicOptional<A, T>& opt)
1077 {
1078  return opt.has_value();
1079 }
1080 
1089 template <typename A, typename T, typename U>
1090 constexpr bool operator<(const BasicOptional<A, T>& opt, const U& value)
1091 {
1092  return !opt.has_value() || opt.value() < value;
1093 }
1094 
1103 template <typename A, typename T, typename U>
1104 constexpr bool operator<(const U& value, const BasicOptional<A, T>& opt)
1105 {
1106  return opt.has_value() && value < opt.value();
1107 }
1108 
1117 template <typename A1, typename T, typename A2, typename U>
1118 constexpr bool operator>(const BasicOptional<A1, T>& first, const BasicOptional<A2, U>& second)
1119 {
1120  if (first.has_value() && second.has_value())
1121  {
1122  return first.value() > second.value();
1123  }
1124  return first.has_value() > second.has_value();
1125 }
1126 
1134 template <typename A, typename T>
1135 constexpr bool operator>(const BasicOptional<A, T>& opt, std::nullopt_t)
1136 {
1137  return opt.has_value();
1138 }
1139 
1147 template <typename A, typename T>
1148 constexpr bool operator>(std::nullopt_t, const BasicOptional<A, T>&)
1149 {
1150  return false;
1151 }
1152 
1161 template <typename A, typename T, typename U>
1162 constexpr bool operator>(const BasicOptional<A, T>& opt, const U& value)
1163 {
1164  return opt.has_value() && opt.value() > value;
1165 }
1166 
1175 template <typename A, typename T, typename U>
1176 constexpr bool operator>(const U& value, const BasicOptional<A, T>& opt)
1177 {
1178  return !opt.has_value() || value > opt.value();
1179 }
1180 
1189 template <typename A1, typename T, typename A2, typename U>
1190 constexpr bool operator<=(const BasicOptional<A1, T>& first, const BasicOptional<A2, U>& second)
1191 {
1192  return !(first > second);
1193 }
1194 
1202 template <typename A, typename T>
1203 constexpr bool operator<=(const BasicOptional<A, T>& opt, std::nullopt_t)
1204 {
1205  return !(opt > std::nullopt);
1206 }
1207 
1215 template <typename A, typename T>
1216 constexpr bool operator<=(std::nullopt_t, const BasicOptional<A, T>& opt)
1217 {
1218  return !(std::nullopt > opt);
1219 }
1220 
1229 template <typename A, typename T, typename U>
1230 constexpr bool operator<=(const BasicOptional<A, T>& opt, const U& value)
1231 {
1232  return !(opt > value);
1233 }
1234 
1243 template <typename A, typename T, typename U>
1244 constexpr bool operator<=(const U& value, const BasicOptional<A, T>& opt)
1245 {
1246  return !(value > opt);
1247 }
1248 
1257 template <typename A1, typename T, typename A2, typename U>
1258 constexpr bool operator>=(const BasicOptional<A1, T>& first, const BasicOptional<A2, U>& second)
1259 {
1260  return !(first < second);
1261 }
1262 
1270 template <typename A, typename T>
1271 constexpr bool operator>=(const BasicOptional<A, T>& opt, std::nullopt_t)
1272 {
1273  return !(opt < std::nullopt);
1274 }
1275 
1283 template <typename A, typename T>
1284 constexpr bool operator>=(std::nullopt_t, const BasicOptional<A, T>& opt)
1285 {
1286  return !(std::nullopt < opt);
1287 }
1288 
1297 template <typename A, typename T, typename U>
1298 constexpr bool operator>=(const BasicOptional<A, T>& opt, const U& value)
1299 {
1300  return !(opt < value);
1301 }
1302 
1311 template <typename A, typename T, typename U>
1312 constexpr bool operator>=(const U& value, const BasicOptional<A, T>& opt)
1313 {
1314  return !(value < opt);
1315 }
1316 
1317 } // namespace zserio
1318 
1319 namespace std
1320 {
1321 
1322 template <typename ALLOC, typename T>
1323 struct hash<zserio::BasicOptional<ALLOC, T>>
1324 {
1326  {
1327  return zserio::calcHashCode(zserio::HASH_SEED, opt);
1328  }
1329 };
1330 
1331 } // namespace std
1332 
1333 #endif // ZSERIO_OPTIONAL_H_INC
allocator_type & get_allocator_ref()
void set_allocator(const allocator_type &allocator)
constexpr BasicOptional(BasicOptional< ALLOC, U > &&other, const ALLOC &allocator)
Definition: Optional.h:425
constexpr BasicOptional(const T &value, const ALLOC &allocator={})
Definition: Optional.h:137
constexpr BasicOptional(const ALLOC &allocator)
Definition: Optional.h:156
void swap(BasicOptional &other)
Definition: Optional.h:487
constexpr T && value() &&
Definition: Optional.h:559
const T & operator*() const &
Definition: Optional.h:630
constexpr BasicOptional() noexcept
Definition: Optional.h:120
BasicOptional(BasicOptional &&other)
Definition: Optional.h:364
T value_or(U &&def)
Definition: Optional.h:679
T & emplace(ARGS &&... args)
Definition: Optional.h:515
T && operator*() &&
Definition: Optional.h:618
constexpr BasicOptional(BasicOptional< ALLOC, U > &&other)
Definition: Optional.h:412
constexpr const T & value() const &
Definition: Optional.h:571
constexpr BasicOptional(const BasicOptional &other, const ALLOC &allocator)
Definition: Optional.h:263
BasicOptional & operator=(std::nullopt_t)
Definition: Optional.h:335
const T * operator->() const
Definition: Optional.h:666
constexpr BasicOptional(std::in_place_t, const ALLOC &allocator, ARGS &&... args)
Definition: Optional.h:186
constexpr BasicOptional(std::in_place_t, ARGS &&... args)
Definition: Optional.h:171
BasicOptional & operator=(const BasicOptional< A, U > &other)
Definition: Optional.h:318
std::optional< typename detail::optional_element< T >::type > OptionalType
Definition: Optional.h:115
BasicOptional(BasicOptional &&other, const ALLOC &allocator)
Definition: Optional.h:378
constexpr BasicOptional & operator=(const BasicOptional &other)
Definition: Optional.h:293
friend class BasicOptional
Definition: Optional.h:708
constexpr BasicOptional(const BasicOptional &other)
Definition: Optional.h:235
T value_or(U &&def) const
Definition: Optional.h:696
constexpr T & value() &
Definition: Optional.h:536
constexpr BasicOptional(const BasicOptional< A, U > &other, const ALLOC &allocator)
Definition: Optional.h:278
constexpr BasicOptional(std::nullopt_t, const ALLOC &allocator={}) noexcept
Definition: Optional.h:127
BasicOptional & operator=(BasicOptional &&other)
Definition: Optional.h:391
constexpr BasicOptional(T &&value, const ALLOC &allocator={})
Definition: Optional.h:147
const T && operator*() const &&
Definition: Optional.h:642
constexpr bool has_value() const noexcept
Definition: Optional.h:457
BasicOptional & operator=(BasicOptional< ALLOC, U > &&other)
Definition: Optional.h:439
constexpr const T && value() const &&
Definition: Optional.h:594
constexpr BasicOptional(const BasicOptional< ALLOC, U > &other)
Definition: Optional.h:248
CppRuntimeException(const char *message="")
Definition: BitBuffer.h:602
bool operator>(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
Definition: BitBuffer.h:525
bool operator==(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
Definition: BitBuffer.h:507
typename std::allocator_traits< ALLOC >::template rebind_alloc< T > RebindAlloc
Definition: RebindAlloc.h:10
bool operator<(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
Definition: BitBuffer.h:519
uint32_t calcHashCode(uint32_t seedValue, const ArrayView< T, ARRAY_TRAITS > &array)
Definition: ArrayView.h:882
View(T, ARGS &&...) -> View< T >
constexpr auto make_optional(T &&value)
Definition: Optional.h:879
bool operator<=(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
Definition: BitBuffer.h:531
bool operator>=(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
Definition: BitBuffer.h:537
bool operator!=(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
Definition: BitBuffer.h:513
size_t operator()(const zserio::BasicOptional< ALLOC, T > &opt) const
Definition: Optional.h:1325