AWS IoT Device SDK C++ v2  1.34.0
AWS IoT Device SDK C++ v2
Variant.h
Go to the documentation of this file.
1 #pragma once
2 
7 #include <aws/common/assert.h>
8 #include <aws/crt/Utility.h>
9 
10 #include <algorithm>
11 #include <type_traits>
12 #include <utility>
13 
14 namespace Aws
15 {
16  namespace Crt
17  {
18  namespace VariantDetail
19  {
20  template <typename T> constexpr const T &ConstExprMax(const T &a, const T &b)
21  {
22  return (a < b) ? b : a;
23  }
24 
25  namespace ParameterPackSize
26  {
27  // Returns a max of sizeof(T) over all T in a template parameter pack
28  template <typename Last> constexpr std::size_t GetMaxSizeOf(std::size_t curMax = 0)
29  {
30  return ConstExprMax(curMax, sizeof(Last));
31  }
32 
33  template <typename First, typename Second, typename... Rest>
34  constexpr std::size_t GetMaxSizeOf(std::size_t curMax = 0)
35  {
36  return ConstExprMax(curMax, GetMaxSizeOf<Second, Rest...>(ConstExprMax(curMax, sizeof(First))));
37  }
38 
39  // some old gcc versions does not work with alignas(Ts..)
40  template <typename Last> constexpr std::size_t AlignAsPack(std::size_t curMax = 0)
41  {
42  return ConstExprMax(curMax, alignof(Last));
43  }
44 
45  template <typename First, typename Second, typename... Rest>
46  constexpr std::size_t AlignAsPack(std::size_t curMax = 0)
47  {
48  return ConstExprMax(curMax, AlignAsPack<Second, Rest...>(ConstExprMax(curMax, alignof(First))));
49  }
50  } // namespace ParameterPackSize
51 
52  namespace Index
53  {
54  using VariantIndex = short;
55 
56  template <typename T, typename Last> constexpr VariantIndex GetIndexOf(VariantIndex curIndex = 0)
57  {
58  return std::is_same<T, Last>::value ? curIndex : -1;
59  }
60 
61  template <typename T, typename First, typename Second, typename... Rest>
62  constexpr VariantIndex GetIndexOf(VariantIndex curIndex = 0)
63  {
64  return std::is_same<T, First>::value ? curIndex : GetIndexOf<T, Second, Rest...>(++curIndex);
65  }
66  } // namespace Index
67 
68  namespace Checker
69  {
70  // Returns True if the template parameter pack Ts has a type T, i.e. ContainsType<T, Ts>() == true if T
71  // is in the list of Ts
72  template <typename T, typename Last> constexpr bool ContainsType()
73  {
74  return std::is_same<T, Last>::value;
75  }
76 
77  template <typename T, typename First, typename Second, typename... Rest> constexpr bool ContainsType()
78  {
79  return std::is_same<T, First>::value || ContainsType<T, Second, Rest...>();
80  }
81 
82  // a case when the template parameter pack is empty (i.e. Variant<>)
83  template <typename T> constexpr bool ContainsType()
84  {
85  return false;
86  }
87 
88  template <typename T, typename... Ts> struct HasType
89  {
90  static const bool value = ContainsType<T, Ts...>();
91  };
92  } // namespace Checker
93 #if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
94  namespace VariantDebug
95  {
96  template <typename... Ts> class VariantDebugBrowser
97  {
98  public:
99  VariantDebugBrowser(char *storage) { InitTuple<0, Ts...>(storage); }
100  std::tuple<typename std::add_pointer<Ts>::type...> as_tuple;
101 
102  private:
103  template <IndexT Index, typename First, typename Second, typename... Rest>
104  void InitTuple(char *storage)
105  {
106  First *value = reinterpret_cast<First *>(storage);
107  std::get<Index>(as_tuple) = value;
108  InitTuple<Index + 1, Second, Rest...>(storage);
109  }
110 
111  template <IndexT Index, typename Last> void InitTuple(char *storage)
112  {
113  Last *value = reinterpret_cast<Last *>(storage);
114  std::get<Index>(as_tuple) = value;
115  }
116  };
117  } // namespace VariantDebug
118 #endif /* defined(AWS_CRT_ENABLE_VARIANT_DEBUG) */
119  } // namespace VariantDetail
120 
121  template <std::size_t Index, typename... Ts> class VariantAlternative;
122 
127  template <typename... Ts> class Variant
128  {
129  private:
130  template <std::size_t Index> using ThisVariantAlternative = VariantAlternative<Index, Ts...>;
131 
132  template <typename OtherT>
133  using EnableIfOtherIsThisVariantAlternative = typename std::
134  enable_if<VariantDetail::Checker::HasType<typename std::decay<OtherT>::type, Ts...>::value, int>::type;
135 
136  public:
138  static constexpr std::size_t AlternativeCount = sizeof...(Ts);
139 
141  {
142  using FirstAlternative = typename ThisVariantAlternative<0>::type;
143  new (m_storage) FirstAlternative();
144  m_index = 0;
145  }
146 
147  Variant(const Variant &other)
148  {
149  AWS_FATAL_ASSERT(other.m_index != -1);
150  m_index = other.m_index;
151  VisitorUtil<0, Ts...>::VisitBinary(this, other, CopyMoveConstructor());
152  }
153 
154  Variant(Variant &&other)
155  {
156  AWS_FATAL_ASSERT(other.m_index != -1);
157  m_index = other.m_index;
158  VisitorUtil<0, Ts...>::VisitBinary(this, std::move(other), CopyMoveConstructor());
159  }
160 
161  template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> Variant(const T &val)
162  {
163  static_assert(
164  VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
165  "This variant does not have such alternative T.");
166  static_assert(
167  sizeof(T) <= STORAGE_SIZE,
168  "Attempting to instantiate a Variant with a type bigger than all alternatives.");
169 
170  using PlainT = typename std::decay<T>::type;
171  new (m_storage) PlainT(val);
172  m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
173  AWS_ASSERT(m_index != -1);
174  }
175 
176  template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> Variant(T &&val)
177  {
178  static_assert(
179  VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
180  "This variant does not have such alternative T.");
181  static_assert(
182  sizeof(T) <= STORAGE_SIZE,
183  "Attempting to instantiate a Variant with a type bigger than all alternatives.");
184 
185  using PlainT = typename std::decay<T>::type;
186  new (m_storage) PlainT(std::forward<T>(val));
187  m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
188  AWS_ASSERT(m_index != -1);
189  }
190 
191  // An overload to initialize with an Alternative T in-place
192  template <typename T, typename... Args> explicit Variant(Aws::Crt::InPlaceTypeT<T>, Args &&...args)
193  {
194  static_assert(
195  VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
196  "This variant does not have such alternative T.");
197  static_assert(
198  sizeof(T) <= STORAGE_SIZE,
199  "Attempting to instantiate a Variant with a type bigger than all alternatives.");
200 
201  using PlainT = typename std::decay<T>::type;
202  new (m_storage) PlainT(std::forward<Args>(args)...);
203  m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
204  AWS_ASSERT(m_index != -1);
205  }
206 
207  Variant &operator=(const Variant &other)
208  {
209  if (this != &other)
210  {
211  AWS_FATAL_ASSERT(other.m_index != -1);
212  if (m_index != other.m_index)
213  {
214  Destroy();
215  m_index = other.m_index;
216  VisitorUtil<0, Ts...>::VisitBinary(this, other, CopyMoveConstructor());
217  }
218  else
219  {
220  VisitorUtil<0, Ts...>::VisitBinary(this, other, CopyMoveAssigner());
221  }
222  }
223  return *this;
224  }
225 
227  {
228  if (this != &other)
229  {
230  AWS_FATAL_ASSERT(other.m_index != -1);
231  if (m_index != other.m_index)
232  {
233  Destroy();
234  m_index = other.m_index;
235  VisitorUtil<0, Ts...>::VisitBinary(this, std::move(other), CopyMoveConstructor());
236  }
237  else
238  {
239  VisitorUtil<0, Ts...>::VisitBinary(this, std::move(other), CopyMoveAssigner());
240  };
241  }
242  return *this;
243  }
244 
245  /* emplace */
246  template <typename T, typename... Args, EnableIfOtherIsThisVariantAlternative<T> = 1>
247  T &emplace(Args &&...args)
248  {
249  static_assert(
250  VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
251  "This variant does not have such alternative T.");
252  static_assert(
253  sizeof(T) <= STORAGE_SIZE,
254  "Attempting to instantiate a Variant with a type bigger than all alternatives.");
255 
256  Destroy();
257 
258  using PlainT = typename std::decay<T>::type;
259  new (m_storage) PlainT(std::forward<Args>(args)...);
260  m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
261  AWS_ASSERT(m_index != -1);
262 
263  T *value = reinterpret_cast<T *>(m_storage);
264  return *value;
265  }
266 
267  template <std::size_t Index, typename... Args>
268  auto emplace(Args &&...args) -> typename ThisVariantAlternative<Index>::type &
269  {
270  static_assert(Index < AlternativeCount, "Unknown alternative index to emplace");
271  using AlternativeT = typename ThisVariantAlternative<Index>::type;
272 
273  return emplace<AlternativeT, Args...>(std::forward<Args>(args)...);
274  }
275 
276  template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> bool holds_alternative() const
277  {
278  AWS_ASSERT(m_index != -1);
279  return m_index == VariantDetail::Index::GetIndexOf<T, Ts...>();
280  }
281 
282  /* non-const get */
283  template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> T &get()
284  {
285  AWS_FATAL_ASSERT(holds_alternative<T>());
286  T *value = reinterpret_cast<T *>(m_storage);
287  return *value;
288  }
289 
290  template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> T *get_if()
291  {
292  if (holds_alternative<T>())
293  {
294  T *value = reinterpret_cast<T *>(m_storage);
295  return value;
296  }
297  else
298  {
299  return nullptr;
300  }
301  }
302 
303  template <std::size_t Index> auto get() -> typename ThisVariantAlternative<Index>::type &
304  {
305  static_assert(Index < AlternativeCount, "Unknown alternative index to get");
306  AWS_FATAL_ASSERT(holds_alternative<Index>());
307  using AlternativeT = typename ThisVariantAlternative<Index>::type;
308  AlternativeT *ret = reinterpret_cast<AlternativeT *>(m_storage);
309  return *ret;
310  }
311 
312  /* const get */
313  template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> const T &get() const
314  {
315  AWS_FATAL_ASSERT(holds_alternative<T>());
316  const T *value = reinterpret_cast<const T *>(m_storage);
317  return *value;
318  }
319 
320  template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> const T *get_if() const
321  {
322  if (holds_alternative<T>())
323  {
324  T *value = reinterpret_cast<T *>(m_storage);
325  return value;
326  }
327  else
328  {
329  return nullptr;
330  }
331  }
332 
333  template <std::size_t Index> auto get() const -> const typename ThisVariantAlternative<Index>::type &
334  {
335  static_assert(Index < AlternativeCount, "Unknown alternative index to get");
336  AWS_ASSERT(Index == m_index);
337  using AlternativeT = typename ThisVariantAlternative<Index>::type;
338  const AlternativeT *ret = reinterpret_cast<const AlternativeT *>(m_storage);
339  return *ret;
340  }
341 
342  /* This is just a templated way to say
343  * "int*" for
344  * a VariantAlternative<0, Variant<int, char, long>()>*/
345  template <std::size_t Index>
347  typename std::add_pointer<typename ThisVariantAlternative<Index>::type>::type;
348 
349  template <std::size_t Index> auto get_if() -> RawAlternativePointerT<Index>
350  {
351  static_assert(Index < AlternativeCount, "Unknown alternative index to get");
352  if (holds_alternative<Index>())
353  {
354  using AlternativePtrT = RawAlternativePointerT<Index>;
355  AlternativePtrT value = reinterpret_cast<AlternativePtrT>(m_storage);
356  return value;
357  }
358  else
359  {
360  return nullptr;
361  }
362  }
363 
364  template <std::size_t Index>
365  using ConstRawAlternativePointerT = typename std::add_pointer<
366  typename std::add_const<typename ThisVariantAlternative<Index>::type>::type>::type;
367 
368  template <std::size_t Index> auto get_if() const -> ConstRawAlternativePointerT<Index>
369  {
370  static_assert(Index < AlternativeCount, "Unknown alternative index to get");
371  if (holds_alternative<Index>())
372  {
373  using AlternativePtrT = ConstRawAlternativePointerT<Index>;
374  AlternativePtrT value = reinterpret_cast<AlternativePtrT>(m_storage);
375  return value;
376  }
377  else
378  {
379  return nullptr;
380  }
381  }
382 
383  std::size_t index() const { return m_index; }
384 
385  ~Variant() { Destroy(); }
386 
387  template <typename VisitorT> void Visit(VisitorT &&visitor)
388  {
389  return VisitorUtil<0, Ts...>::Visit(this, std::forward<VisitorT>(visitor));
390  }
391 
392  private:
393  static constexpr std::size_t STORAGE_SIZE = VariantDetail::ParameterPackSize::GetMaxSizeOf<Ts...>();
394 
395  alignas(VariantDetail::ParameterPackSize::AlignAsPack<Ts...>()) char m_storage[STORAGE_SIZE];
396  IndexT m_index = -1;
397 #if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
398  VariantDetail::VariantDebug::VariantDebugBrowser<Ts...> browser = m_storage;
399 #endif /* defined(AWS_CRT_ENABLE_VARIANT_DEBUG) */
400 
401  template <size_t Index> constexpr bool holds_alternative() const { return Index == m_index; }
402 
403  struct Destroyer
404  {
405  template <typename AlternativeT> void operator()(AlternativeT &&value) const
406  {
407  using PlaintT = typename std::remove_reference<AlternativeT>::type;
408  value.~PlaintT();
409  }
410  };
411 
412  void Destroy()
413  {
414  AWS_FATAL_ASSERT(m_index != -1);
415  Visit(Destroyer());
416 
417  m_index = -1;
418  }
419 
420  struct CopyMoveConstructor
421  {
422  template <typename AlternativeT> void operator()(AlternativeT &&value, AlternativeT &&other) const
423  {
424  using PlaintT = typename std::remove_reference<AlternativeT>::type;
425  new (&value) PlaintT(std::move<AlternativeT>(other));
426  }
427 
428  template <typename AlternativeT, typename ConstAlternativeT>
429  void operator()(AlternativeT &&value, ConstAlternativeT &other) const
430  {
431  using PlaintT = typename std::remove_reference<AlternativeT>::type;
432  using PlaintOtherT =
433  typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
434  static_assert(std::is_same<PlaintT, PlaintOtherT>::value, "Incompatible types");
435 
436  new (&value) PlaintT(other);
437  }
438  };
439 
440  struct CopyMoveAssigner
441  {
442  template <typename AlternativeT> void operator()(AlternativeT &&value, AlternativeT &&other) const
443  {
444  value = std::move(other);
445  }
446 
447  template <typename AlternativeT, typename ConstAlternativeT>
448  void operator()(AlternativeT &&value, ConstAlternativeT &other) const
449  {
450  using PlaintT = typename std::remove_reference<AlternativeT>::type;
451  using PlaintOtherT =
452  typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
453  static_assert(std::is_same<PlaintT, PlaintOtherT>::value, "Incompatible types");
454 
455  value = other;
456  }
457  };
458 
459  template <IndexT Index, typename... Args> struct VisitorUtil;
460 
461  template <IndexT Index, typename First, typename Second, typename... Rest>
462  struct VisitorUtil<Index, First, Second, Rest...>
463  {
464  template <typename VisitorStruct> static void Visit(Variant *pThis, VisitorStruct &&visitor)
465  {
466  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
467 
468  if (Index == pThis->m_index)
469  {
470  using AlternativeT = typename ThisVariantAlternative<Index>::type;
471  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
472  visitor(*value);
473  }
474  else
475  {
476  VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::Visit(
477  pThis, std::forward<VisitorStruct>(visitor));
478  }
479  }
480 
481  template <typename VisitorStruct>
482  static void VisitBinary(Variant<Ts...> *pThis, Variant<Ts...> &&other, VisitorStruct &&visitor)
483  {
484  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
485 
486  if (Index == pThis->m_index)
487  {
488  using AlternativeT = typename ThisVariantAlternative<Index>::type;
489  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
490  visitor(*value, other.get<AlternativeT>());
491  }
492  else
493  {
494  VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
495  pThis, std::forward<Variant<Ts...>>(other), std::forward<VisitorStruct>(visitor));
496  }
497  }
498 
499  template <typename VisitorStruct>
500  static void VisitBinary(Variant<Ts...> *pThis, const Variant<Ts...> &other, VisitorStruct &&visitor)
501  {
502  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
503 
504  if (Index == pThis->m_index)
505  {
506  using AlternativeT = typename ThisVariantAlternative<Index>::type;
507  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
508  const AlternativeT &otherValue = other.get<AlternativeT>();
509  visitor(*value, otherValue);
510  }
511  else
512  {
513  VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
514  pThis, other, std::forward<VisitorStruct>(visitor));
515  }
516  }
517  };
518 
519  template <IndexT Index, typename Last> struct VisitorUtil<Index, Last>
520  {
521  template <typename VisitorStruct> static void Visit(Variant *pThis, VisitorStruct &&visitor)
522  {
523  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
524 
525  if (Index == pThis->m_index)
526  {
527  using AlternativeT = typename ThisVariantAlternative<Index>::type;
528  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
529  visitor(*value);
530  }
531  else
532  {
533  AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
534  }
535  }
536 
537  template <typename VisitorStruct>
538  static void VisitBinary(Variant<Ts...> *pThis, Variant<Ts...> &&other, VisitorStruct &&visitor)
539  {
540  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
541 
542  if (Index == pThis->m_index)
543  {
544  using AlternativeT = typename ThisVariantAlternative<Index>::type;
545  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
546  visitor(*value, other.get<AlternativeT>());
547  }
548  else
549  {
550  AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
551  }
552  }
553 
554  template <typename VisitorStruct>
555  static void VisitBinary(Variant<Ts...> *pThis, const Variant<Ts...> &other, VisitorStruct &&visitor)
556  {
557  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
558 
559  if (Index == pThis->m_index)
560  {
561  using AlternativeT = typename ThisVariantAlternative<Index>::type;
562  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
563  const AlternativeT &otherValue = other.get<AlternativeT>();
564  visitor(*value, otherValue);
565  }
566  else
567  {
568  AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
569  }
570  }
571  };
572  };
573 
574  /* Helper template to get an actual type from an Index */
575  template <std::size_t Index, typename... Ts> class VariantAlternative
576  {
577  public:
578  // uses std::tuple as a helper struct to provide index-based access of a parameter pack
579  using type = typename std::tuple_element<Index, std::tuple<Ts...>>::type;
580 
582 
584  };
585 
586  template <typename T> class VariantSize
587  {
588  constexpr static const std::size_t Value = T::AlternativeCount;
589  };
590  } // namespace Crt
591 } // namespace Aws
Aws::Crt::InPlaceTypeT
Definition: Utility.h:21
Aws::Crt::VariantDetail::ParameterPackSize::GetMaxSizeOf
constexpr std::size_t GetMaxSizeOf(std::size_t curMax=0)
Definition: Variant.h:28
Aws::Crt::Variant::get_if
T * get_if()
Definition: Variant.h:290
Aws::Crt::Variant::Variant
Variant(const Variant &other)
Definition: Variant.h:147
Aws::Crt::Variant::AlternativeCount
static constexpr std::size_t AlternativeCount
Definition: Variant.h:138
Aws::Crt::Variant::get_if
auto get_if() const -> ConstRawAlternativePointerT< Index >
Definition: Variant.h:368
Aws::Crt::Variant::operator=
Variant & operator=(Variant &&other)
Definition: Variant.h:226
Aws::Crt::Variant::operator=
Variant & operator=(const Variant &other)
Definition: Variant.h:207
Aws::Crt::Variant::IndexT
VariantDetail::Index::VariantIndex IndexT
Definition: Variant.h:137
Aws::Crt::Variant::get
auto get() const -> const typename ThisVariantAlternative< Index >::type &
Definition: Variant.h:333
Aws::Crt::VariantAlternative::type
typename std::tuple_element< Index, std::tuple< Ts... > >::type type
Definition: Variant.h:579
Aws::Crt::VariantAlternative::VariantAlternative
VariantAlternative(const Variant< Ts... > &)
Definition: Variant.h:581
Aws::Crt::Variant::Variant
Variant(Variant &&other)
Definition: Variant.h:154
Aws::Crt::Variant::~Variant
~Variant()
Definition: Variant.h:385
Aws::Crt::Variant::ConstRawAlternativePointerT
typename std::add_pointer< typename std::add_const< typename ThisVariantAlternative< Index >::type >::type >::type ConstRawAlternativePointerT
Definition: Variant.h:366
Aws::Crt::Variant::get_if
auto get_if() -> RawAlternativePointerT< Index >
Definition: Variant.h:349
Aws::Crt::Variant::holds_alternative
bool holds_alternative() const
Definition: Variant.h:276
Aws::Crt::Variant::RawAlternativePointerT
typename std::add_pointer< typename ThisVariantAlternative< Index >::type >::type RawAlternativePointerT
Definition: Variant.h:347
Aws::Crt::VariantDetail::Checker::ContainsType
constexpr bool ContainsType()
Definition: Variant.h:72
Aws::Crt::VariantAlternative::VariantAlternative
VariantAlternative(const Variant< Ts... > *)
Definition: Variant.h:583
Aws::Crt::Variant::emplace
auto emplace(Args &&...args) -> typename ThisVariantAlternative< Index >::type &
Definition: Variant.h:268
Aws::Crt::Variant
Definition: Variant.h:128
Aws::Crt::Variant::Variant
Variant()
Definition: Variant.h:140
Aws::Crt::VariantDetail::ParameterPackSize::AlignAsPack
constexpr std::size_t AlignAsPack(std::size_t curMax=0)
Definition: Variant.h:40
Aws::Crt::Variant::get
T & get()
Definition: Variant.h:283
Aws::Crt::Variant::get
auto get() -> typename ThisVariantAlternative< Index >::type &
Definition: Variant.h:303
Aws::Crt::Variant::get
const T & get() const
Definition: Variant.h:313
Aws::Crt::VariantDetail::Index::GetIndexOf
constexpr VariantIndex GetIndexOf(VariantIndex curIndex=0)
Definition: Variant.h:56
Aws
Definition: Allocator.h:11
Aws::Crt::VariantDetail::Checker::HasType::value
static const bool value
Definition: Variant.h:90
Aws::Crt::VariantDetail::ConstExprMax
constexpr const T & ConstExprMax(const T &a, const T &b)
Definition: Variant.h:20
Aws::Crt::Variant::Variant
Variant(const T &val)
Definition: Variant.h:161
Aws::Crt::Variant::get_if
const T * get_if() const
Definition: Variant.h:320
Aws::Crt::Variant::Visit
void Visit(VisitorT &&visitor)
Definition: Variant.h:387
Aws::Crt::Variant::emplace
T & emplace(Args &&...args)
Definition: Variant.h:247
Aws::Crt::VariantDetail::Index::VariantIndex
short VariantIndex
Definition: Variant.h:54
Aws::Crt::VariantDetail::Checker::HasType
Definition: Variant.h:89
Aws::Crt::Variant::Variant
Variant(T &&val)
Definition: Variant.h:176
Utility.h
Aws::Crt::Variant::index
std::size_t index() const
Definition: Variant.h:383
Aws::Crt::VariantSize
Definition: Variant.h:587
Aws::Crt::VariantAlternative
Definition: Variant.h:576
Aws::Crt::Variant::Variant
Variant(Aws::Crt::InPlaceTypeT< T >, Args &&...args)
Definition: Variant.h:192