AWS IoT Device SDK C++ v2  1.35.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  (void)value;
408  using PlaintT = typename std::remove_reference<AlternativeT>::type;
409  value.~PlaintT();
410  }
411  };
412 
413  void Destroy()
414  {
415  AWS_FATAL_ASSERT(m_index != -1);
416  Visit(Destroyer());
417 
418  m_index = -1;
419  }
420 
421  struct CopyMoveConstructor
422  {
423  template <typename AlternativeT> void operator()(AlternativeT &&value, AlternativeT &&other) const
424  {
425  using PlaintT = typename std::remove_reference<AlternativeT>::type;
426  new (&value) PlaintT(std::move<AlternativeT>(other));
427  }
428 
429  template <typename AlternativeT, typename ConstAlternativeT>
430  void operator()(AlternativeT &&value, ConstAlternativeT &other) const
431  {
432  using PlaintT = typename std::remove_reference<AlternativeT>::type;
433  using PlaintOtherT =
434  typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
435  static_assert(std::is_same<PlaintT, PlaintOtherT>::value, "Incompatible types");
436 
437  new (&value) PlaintT(other);
438  }
439  };
440 
441  struct CopyMoveAssigner
442  {
443  template <typename AlternativeT> void operator()(AlternativeT &&value, AlternativeT &&other) const
444  {
445  value = std::move(other);
446  }
447 
448  template <typename AlternativeT, typename ConstAlternativeT>
449  void operator()(AlternativeT &&value, ConstAlternativeT &other) const
450  {
451  using PlaintT = typename std::remove_reference<AlternativeT>::type;
452  using PlaintOtherT =
453  typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
454  static_assert(std::is_same<PlaintT, PlaintOtherT>::value, "Incompatible types");
455 
456  value = other;
457  }
458  };
459 
460  template <IndexT Index, typename... Args> struct VisitorUtil;
461 
462  template <IndexT Index, typename First, typename Second, typename... Rest>
463  struct VisitorUtil<Index, First, Second, Rest...>
464  {
465  template <typename VisitorStruct> static void Visit(Variant *pThis, VisitorStruct &&visitor)
466  {
467  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
468 
469  if (Index == pThis->m_index)
470  {
471  using AlternativeT = typename ThisVariantAlternative<Index>::type;
472  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
473  visitor(*value);
474  }
475  else
476  {
477  VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::Visit(
478  pThis, std::forward<VisitorStruct>(visitor));
479  }
480  }
481 
482  template <typename VisitorStruct>
483  static void VisitBinary(Variant<Ts...> *pThis, Variant<Ts...> &&other, VisitorStruct &&visitor)
484  {
485  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
486 
487  if (Index == pThis->m_index)
488  {
489  using AlternativeT = typename ThisVariantAlternative<Index>::type;
490  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
491  visitor(*value, other.get<AlternativeT>());
492  }
493  else
494  {
495  VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
496  pThis, std::forward<Variant<Ts...>>(other), std::forward<VisitorStruct>(visitor));
497  }
498  }
499 
500  template <typename VisitorStruct>
501  static void VisitBinary(Variant<Ts...> *pThis, const Variant<Ts...> &other, VisitorStruct &&visitor)
502  {
503  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
504 
505  if (Index == pThis->m_index)
506  {
507  using AlternativeT = typename ThisVariantAlternative<Index>::type;
508  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
509  const AlternativeT &otherValue = other.get<AlternativeT>();
510  visitor(*value, otherValue);
511  }
512  else
513  {
514  VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
515  pThis, other, std::forward<VisitorStruct>(visitor));
516  }
517  }
518  };
519 
520  template <IndexT Index, typename Last> struct VisitorUtil<Index, Last>
521  {
522  template <typename VisitorStruct> static void Visit(Variant *pThis, VisitorStruct &&visitor)
523  {
524  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
525 
526  if (Index == pThis->m_index)
527  {
528  using AlternativeT = typename ThisVariantAlternative<Index>::type;
529  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
530  visitor(*value);
531  }
532  else
533  {
534  AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
535  }
536  }
537 
538  template <typename VisitorStruct>
539  static void VisitBinary(Variant<Ts...> *pThis, Variant<Ts...> &&other, VisitorStruct &&visitor)
540  {
541  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
542 
543  if (Index == pThis->m_index)
544  {
545  using AlternativeT = typename ThisVariantAlternative<Index>::type;
546  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
547  visitor(*value, other.get<AlternativeT>());
548  }
549  else
550  {
551  AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
552  }
553  }
554 
555  template <typename VisitorStruct>
556  static void VisitBinary(Variant<Ts...> *pThis, const Variant<Ts...> &other, VisitorStruct &&visitor)
557  {
558  static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
559 
560  if (Index == pThis->m_index)
561  {
562  using AlternativeT = typename ThisVariantAlternative<Index>::type;
563  AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
564  const AlternativeT &otherValue = other.get<AlternativeT>();
565  visitor(*value, otherValue);
566  }
567  else
568  {
569  AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
570  }
571  }
572  };
573  };
574 
575  /* Helper template to get an actual type from an Index */
576  template <std::size_t Index, typename... Ts> class VariantAlternative
577  {
578  public:
579  // uses std::tuple as a helper struct to provide index-based access of a parameter pack
580  using type = typename std::tuple_element<Index, std::tuple<Ts...>>::type;
581 
583 
585  };
586 
587  template <typename T> class VariantSize
588  {
589  constexpr static const std::size_t Value = T::AlternativeCount;
590  };
591  } // namespace Crt
592 } // 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< R, E >::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:580
Aws::Crt::VariantAlternative::VariantAlternative
VariantAlternative(const Variant< Ts... > &)
Definition: Variant.h:582
Aws::Crt::Variant::Variant
Variant(Variant &&other)
Definition: Variant.h:154
Aws::Crt::Variant::~Variant
~Variant()
Definition: Variant.h:385
Aws::Crt::Variant< R, E >::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< R, E >::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:584
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:588
Aws::Crt::VariantAlternative
Definition: Variant.h:577
Aws::Crt::Variant::Variant
Variant(Aws::Crt::InPlaceTypeT< T >, Args &&...args)
Definition: Variant.h:192