Home | History | Annotate | Download | only in rpc
      1 #ifndef ANDROID_PDX_RPC_VARIANT_H_
      2 #define ANDROID_PDX_RPC_VARIANT_H_
      3 
      4 #include <cstdint>
      5 #include <tuple>
      6 #include <type_traits>
      7 
      8 namespace android {
      9 namespace pdx {
     10 namespace rpc {
     11 
     12 // Type tag denoting an empty variant.
     13 struct EmptyVariant {};
     14 
     15 namespace detail {
     16 
     17 // Type for matching tagged overloads.
     18 template <typename T>
     19 struct TypeTag {};
     20 
     21 // Determines the type of the I-th element of Types....
     22 template <std::size_t I, typename... Types>
     23 using TypeForIndex = std::tuple_element_t<I, std::tuple<Types...>>;
     24 
     25 // Determines the type tag for the I-th element of Types....
     26 template <std::size_t I, typename... Types>
     27 using TypeTagForIndex = TypeTag<TypeForIndex<I, Types...>>;
     28 
     29 // Enable if T(Args...) is well formed.
     30 template <typename R, typename T, typename... Args>
     31 using EnableIfConstructible =
     32     typename std::enable_if<std::is_constructible<T, Args...>::value, R>::type;
     33 // Enable if T(Args...) is not well formed.
     34 template <typename R, typename T, typename... Args>
     35 using EnableIfNotConstructible =
     36     typename std::enable_if<!std::is_constructible<T, Args...>::value, R>::type;
     37 
     38 // Determines whether T is an element of Types...;
     39 template <typename... Types>
     40 struct HasType : std::false_type {};
     41 template <typename T, typename U>
     42 struct HasType<T, U> : std::is_same<std::decay_t<T>, std::decay_t<U>> {};
     43 template <typename T, typename First, typename... Rest>
     44 struct HasType<T, First, Rest...>
     45     : std::integral_constant<bool, HasType<T, First>::value ||
     46                                        HasType<T, Rest...>::value> {};
     47 
     48 // Defines set operations on a set of Types...
     49 template <typename... Types>
     50 struct Set {
     51   // Default specialization catches the empty set, which is always a subset.
     52   template <typename...>
     53   struct IsSubset : std::true_type {};
     54   template <typename T>
     55   struct IsSubset<T> : HasType<T, Types...> {};
     56   template <typename First, typename... Rest>
     57   struct IsSubset<First, Rest...>
     58       : std::integral_constant<bool, IsSubset<First>::value &&
     59                                          IsSubset<Rest...>::value> {};
     60 };
     61 
     62 // Determines the number of elements of Types... that are constructible from
     63 // From.
     64 template <typename... Types>
     65 struct ConstructibleCount;
     66 template <typename From, typename To>
     67 struct ConstructibleCount<From, To>
     68     : std::integral_constant<std::size_t,
     69                              std::is_constructible<To, From>::value> {};
     70 template <typename From, typename First, typename... Rest>
     71 struct ConstructibleCount<From, First, Rest...>
     72     : std::integral_constant<std::size_t,
     73                              std::is_constructible<First, From>::value +
     74                                  ConstructibleCount<From, Rest...>::value> {};
     75 
     76 // Enable if T is an element of Types...
     77 template <typename R, typename T, typename... Types>
     78 using EnableIfElement =
     79     typename std::enable_if<HasType<T, Types...>::value, R>::type;
     80 // Enable if T is not an element of Types...
     81 template <typename R, typename T, typename... Types>
     82 using EnableIfNotElement =
     83     typename std::enable_if<!HasType<T, Types...>::value, R>::type;
     84 
     85 // Enable if T is convertible to an element of Types... T is considered
     86 // convertible IIF a single element of Types... is assignable from T and T is
     87 // not a direct element of Types...
     88 template <typename R, typename T, typename... Types>
     89 using EnableIfConvertible =
     90     typename std::enable_if<!HasType<T, Types...>::value &&
     91                                 ConstructibleCount<T, Types...>::value == 1,
     92                             R>::type;
     93 
     94 // Enable if T is assignable to an element of Types... T is considered
     95 // assignable IFF a single element of Types... is constructible from T or T is a
     96 // direct element of Types.... Note that T is REQUIRED to be an element of
     97 // Types... when multiple elements are constructible from T to prevent ambiguity
     98 // in conversion.
     99 template <typename R, typename T, typename... Types>
    100 using EnableIfAssignable =
    101     typename std::enable_if<HasType<T, Types...>::value ||
    102                                 ConstructibleCount<T, Types...>::value == 1,
    103                             R>::type;
    104 
    105 // Selects a type for SFINAE constructor selection.
    106 template <bool CondA, typename SelectA, typename SelectB>
    107 using Select = std::conditional_t<CondA, SelectA, SelectB>;
    108 
    109 // Recursive union type.
    110 template <typename... Types>
    111 union Union;
    112 
    113 // Specialization handling a singular type, terminating template recursion.
    114 template <typename Type>
    115 union Union<Type> {
    116   Union() {}
    117   ~Union() {}
    118 
    119   template <typename T>
    120   Union(std::int32_t index, std::int32_t* index_out, TypeTag<Type>, T&& value)
    121       : first_(std::forward<T>(value)) {
    122     *index_out = index;
    123   }
    124   template <typename T, typename = EnableIfAssignable<void, T, Type>>
    125   Union(std::int32_t index, std::int32_t* index_out, T&& value)
    126       : first_(std::forward<T>(value)) {
    127     *index_out = index;
    128   }
    129 
    130   Type& get(TypeTag<Type>) { return first_; }
    131   const Type& get(TypeTag<Type>) const { return first_; }
    132   EmptyVariant get(TypeTag<EmptyVariant>) const { return {}; }
    133   constexpr std::int32_t index(TypeTag<Type>) const { return 0; }
    134 
    135   template <typename... Args>
    136   std::int32_t Construct(TypeTag<Type>, Args&&... args) {
    137     new (&first_) Type(std::forward<Args>(args)...);
    138     return 0;
    139   }
    140   template <typename... Args>
    141   EnableIfConstructible<std::int32_t, Type, Args...> Construct(Args&&... args) {
    142     new (&first_) Type(std::forward<Args>(args)...);
    143     return 0;
    144   }
    145 
    146   void Destruct(std::int32_t target_index) {
    147     if (target_index == index(TypeTag<Type>{})) {
    148       (&get(TypeTag<Type>{}))->~Type();
    149     }
    150   }
    151 
    152   template <typename T>
    153   bool Assign(TypeTag<Type>, std::int32_t target_index, T&& value) {
    154     if (target_index == 0) {
    155       first_ = std::forward<T>(value);
    156       return true;
    157     } else {
    158       return false;
    159     }
    160   }
    161   template <typename T>
    162   EnableIfConstructible<bool, Type, T> Assign(std::int32_t target_index,
    163                                               T&& value) {
    164     if (target_index == 0) {
    165       first_ = std::forward<T>(value);
    166       return true;
    167     } else {
    168       return false;
    169     }
    170   }
    171   template <typename T>
    172   EnableIfNotConstructible<bool, Type, T> Assign(std::int32_t /*target_index*/,
    173                                                  T&& /*value*/) {
    174     return false;
    175   }
    176 
    177   template <typename Op>
    178   decltype(auto) Visit(std::int32_t target_index, Op&& op) {
    179     if (target_index == index(TypeTag<Type>{}))
    180       return std::forward<Op>(op)(get(TypeTag<Type>{}));
    181     else
    182       return std::forward<Op>(op)(get(TypeTag<EmptyVariant>{}));
    183   }
    184   template <typename Op>
    185   decltype(auto) Visit(std::int32_t target_index, Op&& op) const {
    186     if (target_index == index(TypeTag<Type>{}))
    187       return std::forward<Op>(op)(get(TypeTag<Type>{}));
    188     else
    189       return std::forward<Op>(op)(get(TypeTag<EmptyVariant>{}));
    190   }
    191 
    192   template <typename... Args>
    193   bool Become(std::int32_t target_index, Args&&... args) {
    194     if (target_index == index(TypeTag<Type>{})) {
    195       Construct(TypeTag<Type>{}, std::forward<Args>(args)...);
    196       return true;
    197     } else {
    198       return false;
    199     }
    200   }
    201 
    202  private:
    203   Type first_;
    204 };
    205 
    206 // Specialization that recursively unions types from the paramater pack.
    207 template <typename First, typename... Rest>
    208 union Union<First, Rest...> {
    209   Union() {}
    210   ~Union() {}
    211 
    212   template <typename T>
    213   Union(std::int32_t index, std::int32_t* index_out, TypeTag<First>, T&& value)
    214       : first_(std::forward<T>(value)) {
    215     *index_out = index;
    216   }
    217   template <typename T, typename U>
    218   Union(std::int32_t index, std::int32_t* index_out, TypeTag<T>, U&& value)
    219       : rest_(index + 1, index_out, TypeTag<T>{}, std::forward<U>(value)) {}
    220 
    221   struct FirstType {};
    222   struct RestType {};
    223   template <typename T>
    224   using SelectConstructor =
    225       Select<ConstructibleCount<T, First>::value == 1, FirstType, RestType>;
    226 
    227   template <typename T>
    228   Union(std::int32_t index, std::int32_t* index_out, T&& value)
    229       : Union(index, index_out, std::forward<T>(value),
    230               SelectConstructor<T>{}) {}
    231 
    232   template <typename T>
    233   Union(std::int32_t index, std::int32_t* index_out, T&& value, FirstType)
    234       : first_(std::forward<T>(value)) {
    235     *index_out = index;
    236   }
    237   template <typename T>
    238   Union(std::int32_t index, std::int32_t* index_out, T&& value, RestType)
    239       : rest_(index + 1, index_out, std::forward<T>(value)) {}
    240 
    241   First& get(TypeTag<First>) { return first_; }
    242   const First& get(TypeTag<First>) const { return first_; }
    243   constexpr std::int32_t index(TypeTag<First>) const { return 0; }
    244 
    245   template <typename T>
    246   T& get(TypeTag<T>) {
    247     return rest_.template get(TypeTag<T>{});
    248   }
    249   template <typename T>
    250   const T& get(TypeTag<T>) const {
    251     return rest_.template get(TypeTag<T>{});
    252   }
    253   template <typename T>
    254   constexpr std::int32_t index(TypeTag<T>) const {
    255     return 1 + rest_.template index(TypeTag<T>{});
    256   }
    257 
    258   template <typename... Args>
    259   std::int32_t Construct(TypeTag<First>, Args&&... args) {
    260     new (&first_) First(std::forward<Args>(args)...);
    261     return 0;
    262   }
    263   template <typename T, typename... Args>
    264   std::int32_t Construct(TypeTag<T>, Args&&... args) {
    265     return 1 +
    266            rest_.template Construct(TypeTag<T>{}, std::forward<Args>(args)...);
    267   }
    268 
    269   template <typename... Args>
    270   EnableIfConstructible<std::int32_t, First, Args...> Construct(
    271       Args&&... args) {
    272     new (&first_) First(std::forward<Args>(args)...);
    273     return 0;
    274   }
    275   template <typename... Args>
    276   EnableIfNotConstructible<std::int32_t, First, Args...> Construct(
    277       Args&&... args) {
    278     return 1 + rest_.template Construct(std::forward<Args>(args)...);
    279   }
    280 
    281   void Destruct(std::int32_t target_index) {
    282     if (target_index == index(TypeTag<First>{})) {
    283       (get(TypeTag<First>{})).~First();
    284     } else {
    285       rest_.Destruct(target_index - 1);
    286     }
    287   }
    288 
    289   template <typename T>
    290   bool Assign(TypeTag<First>, std::int32_t target_index, T&& value) {
    291     if (target_index == 0) {
    292       first_ = std::forward<T>(value);
    293       return true;
    294     } else {
    295       return false;
    296     }
    297   }
    298   template <typename T, typename U>
    299   bool Assign(TypeTag<T>, std::int32_t target_index, U&& value) {
    300     return rest_.Assign(TypeTag<T>{}, target_index - 1, std::forward<U>(value));
    301   }
    302   template <typename T>
    303   EnableIfConstructible<bool, First, T> Assign(std::int32_t target_index,
    304                                                T&& value) {
    305     if (target_index == 0) {
    306       first_ = std::forward<T>(value);
    307       return true;
    308     } else {
    309       return rest_.Assign(target_index - 1, std::forward<T>(value));
    310     }
    311   }
    312   template <typename T>
    313   EnableIfNotConstructible<bool, First, T> Assign(std::int32_t target_index,
    314                                                   T&& value) {
    315     return rest_.Assign(target_index - 1, std::forward<T>(value));
    316   }
    317 
    318   // Recursively traverses the union and calls Op on the active value when the
    319   // active type is found. If the union is empty Op is called on EmptyVariant.
    320   // TODO(eieio): This could be refactored into an array or jump table. It's
    321   // unclear whether this would be more efficient for practical variant arity.
    322   template <typename Op>
    323   decltype(auto) Visit(std::int32_t target_index, Op&& op) {
    324     if (target_index == index(TypeTag<First>{}))
    325       return std::forward<Op>(op)(get(TypeTag<First>{}));
    326     else
    327       return rest_.Visit(target_index - 1, std::forward<Op>(op));
    328   }
    329   template <typename Op>
    330   decltype(auto) Visit(std::int32_t target_index, Op&& op) const {
    331     if (target_index == index(TypeTag<First>{}))
    332       return std::forward<Op>(op)(get(TypeTag<First>{}));
    333     else
    334       return rest_.Visit(target_index - 1, std::forward<Op>(op));
    335   }
    336 
    337   template <typename... Args>
    338   bool Become(std::int32_t target_index, Args&&... args) {
    339     if (target_index == index(TypeTag<First>{})) {
    340       Construct(TypeTag<First>{}, std::forward<Args>(args)...);
    341       return true;
    342     } else {
    343       return rest_.Become(target_index - 1, std::forward<Args>(args)...);
    344     }
    345   }
    346 
    347  private:
    348   First first_;
    349   Union<Rest...> rest_;
    350 };
    351 
    352 }  // namespace detail
    353 
    354 template <typename... Types>
    355 class Variant {
    356  private:
    357   // Convenience types.
    358   template <typename T>
    359   using TypeTag = detail::TypeTag<T>;
    360   template <typename T>
    361   using DecayedTypeTag = TypeTag<std::decay_t<T>>;
    362   template <std::size_t I>
    363   using TypeForIndex = detail::TypeForIndex<I, Types...>;
    364   template <std::size_t I>
    365   using TypeTagForIndex = detail::TypeTagForIndex<I, Types...>;
    366   template <typename T>
    367   using HasType = detail::HasType<T, Types...>;
    368   template <typename R, typename T>
    369   using EnableIfElement = detail::EnableIfElement<R, T, Types...>;
    370   template <typename R, typename T>
    371   using EnableIfConvertible = detail::EnableIfConvertible<R, T, Types...>;
    372   template <typename R, typename T>
    373   using EnableIfAssignable = detail::EnableIfAssignable<R, T, Types...>;
    374 
    375   struct Direct {};
    376   struct Convert {};
    377   template <typename T>
    378   using SelectConstructor = detail::Select<HasType<T>::value, Direct, Convert>;
    379 
    380   // Constructs by type tag when T is an direct element of Types...
    381   template <typename T>
    382   explicit Variant(T&& value, Direct)
    383       : value_(0, &index_, DecayedTypeTag<T>{}, std::forward<T>(value)) {}
    384   // Conversion constructor when T is not a direct element of Types...
    385   template <typename T>
    386   explicit Variant(T&& value, Convert)
    387       : value_(0, &index_, std::forward<T>(value)) {}
    388 
    389  public:
    390   // Variants are default construcible, regardless of whether the elements are
    391   // default constructible. Default consruction yields an empty Variant.
    392   Variant() {}
    393   explicit Variant(EmptyVariant) {}
    394   ~Variant() { Destruct(); }
    395 
    396   // Copy and move construction from Variant types. Each element of OtherTypes
    397   // must be convertible to an element of Types.
    398   template <typename... OtherTypes>
    399   explicit Variant(const Variant<OtherTypes...>& other) {
    400     other.Visit([this](const auto& value) { Construct(value); });
    401   }
    402   template <typename... OtherTypes>
    403   explicit Variant(Variant<OtherTypes...>&& other) {
    404     other.Visit([this](auto&& value) { Construct(std::move(value)); });
    405   }
    406 
    407   // Construction from non-Variant types.
    408   template <typename T, typename = EnableIfAssignable<void, T>>
    409   explicit Variant(T&& value)
    410       : Variant(std::forward<T>(value), SelectConstructor<T>{}) {}
    411 
    412   // Performs assignment from type T belonging to Types. This overload takes
    413   // priority to prevent implicit conversion in cases where T is implicitly
    414   // convertible to multiple elements of Types.
    415   template <typename T>
    416   EnableIfElement<Variant&, T> operator=(T&& value) {
    417     Assign(DecayedTypeTag<T>{}, std::forward<T>(value));
    418     return *this;
    419   }
    420 
    421   // Performs assignment from type T not belonging to Types. This overload
    422   // matches in cases where conversion is the only viable option.
    423   template <typename T>
    424   EnableIfConvertible<Variant&, T> operator=(T&& value) {
    425     Assign(std::forward<T>(value));
    426     return *this;
    427   }
    428 
    429   // Handles assignment from the empty type. This overload supports assignment
    430   // in visitors using generic lambdas.
    431   Variant& operator=(EmptyVariant) {
    432     Assign(EmptyVariant{});
    433     return *this;
    434   }
    435 
    436   // Assignment from Variant types. Each element of OtherTypes must be
    437   // convertible to an element of Types. Forwards through non-Variant assignment
    438   // operators to apply conversion checks.
    439   template <typename... OtherTypes>
    440   Variant& operator=(const Variant<OtherTypes...>& other) {
    441     other.Visit([this](const auto& value) { *this = value; });
    442     return *this;
    443   }
    444   template <typename... OtherTypes>
    445   Variant& operator=(Variant<OtherTypes...>&& other) {
    446     other.Visit([this](auto&& value) { *this = std::move(value); });
    447     return *this;
    448   }
    449 
    450   // Becomes the target type, constructing a new element from the given
    451   // arguments if necessary. No action is taken if the active element is already
    452   // the target type. Otherwise the active element is destroyed and replaced by
    453   // constructing an element of the new type using |Args|. An invalid target
    454   // type index results in an empty Variant.
    455   template <typename... Args>
    456   void Become(std::int32_t target_index, Args&&... args) {
    457     if (target_index != index()) {
    458       Destruct();
    459       index_ = value_.Become(target_index, std::forward<Args>(args)...)
    460                    ? target_index
    461                    : kEmptyIndex;
    462     }
    463   }
    464 
    465   // Invokes |Op| on the active element. If the Variant is empty |Op| is invoked
    466   // on EmptyVariant.
    467   template <typename Op>
    468   decltype(auto) Visit(Op&& op) {
    469     return value_.Visit(index_, std::forward<Op>(op));
    470   }
    471   template <typename Op>
    472   decltype(auto) Visit(Op&& op) const {
    473     return value_.Visit(index_, std::forward<Op>(op));
    474   }
    475 
    476   // Index returned when the Variant is empty.
    477   enum : std::int32_t { kEmptyIndex = -1 };
    478 
    479   // Returns the index of the given type.
    480   template <typename T>
    481   constexpr std::int32_t index_of() const {
    482     static_assert(HasType<T>::value, "T is not an element type of Variant.");
    483     return value_.template index(DecayedTypeTag<T>{});
    484   }
    485 
    486   // Returns the index of the active type. If the Variant is empty -1 is
    487   // returned.
    488   std::int32_t index() const { return index_; }
    489 
    490   // Returns true if the given type is active, false otherwise.
    491   template <typename T>
    492   bool is() const {
    493     static_assert(HasType<T>::value, "T is not an element type of Variant.");
    494     return index() == index_of<T>();
    495   }
    496 
    497   // Returns true if the Variant is empty, false otherwise.
    498   bool empty() const { return index() == kEmptyIndex; }
    499 
    500   // Element accessors. Returns a pointer to the active value if the given
    501   // type/index is active, otherwise nullptr is returned.
    502   template <typename T>
    503   T* get() {
    504     if (is<T>())
    505       return &value_.template get(DecayedTypeTag<T>{});
    506     else
    507       return nullptr;
    508   }
    509   template <typename T>
    510   const T* get() const {
    511     if (is<T>())
    512       return &value_.template get(DecayedTypeTag<T>{});
    513     else
    514       return nullptr;
    515   }
    516   template <std::size_t I>
    517   TypeForIndex<I>* get() {
    518     if (is<TypeForIndex<I>>())
    519       return &value_.template get(TypeTagForIndex<I>{});
    520     else
    521       return nullptr;
    522   }
    523   template <std::size_t I>
    524   const TypeForIndex<I>* get() const {
    525     if (is<TypeForIndex<I>>())
    526       return &value_.template get(TypeTagForIndex<I>{});
    527     else
    528       return nullptr;
    529   }
    530 
    531  private:
    532   std::int32_t index_ = kEmptyIndex;
    533   detail::Union<std::decay_t<Types>...> value_;
    534 
    535   // Constructs an element from the given arguments and sets the Variant to the
    536   // resulting type.
    537   template <typename... Args>
    538   void Construct(Args&&... args) {
    539     index_ = value_.template Construct(std::forward<Args>(args)...);
    540   }
    541   void Construct(EmptyVariant) {}
    542 
    543   // Destroys the active element of the Variant.
    544   void Destruct() { value_.Destruct(index_); }
    545 
    546   // Assigns the Variant when non-empty and the current type matches the target
    547   // type, otherwise destroys the current value and constructs a element of the
    548   // new type. Tagged assignment is used when T is an element of the Variant to
    549   // prevent implicit conversion in cases where T is implicitly convertible to
    550   // multiple element types.
    551   template <typename T, typename U>
    552   void Assign(TypeTag<T>, U&& value) {
    553     if (!value_.template Assign(TypeTag<T>{}, index_, std::forward<U>(value))) {
    554       Destruct();
    555       Construct(TypeTag<T>{}, std::forward<U>(value));
    556     }
    557   }
    558   template <typename T>
    559   void Assign(T&& value) {
    560     if (!value_.template Assign(index_, std::forward<T>(value))) {
    561       Destruct();
    562       Construct(std::forward<T>(value));
    563     }
    564   }
    565   // Handles assignment from an empty Variant.
    566   void Assign(EmptyVariant) { Destruct(); }
    567 };
    568 
    569 // Utility type to extract/convert values from a variant. This class simplifies
    570 // conditional logic to get/move/swap/action values from a variant when one or
    571 // more elements are compatible with the destination type.
    572 //
    573 // Example:
    574 //    Variant<int, bool, std::string> v(10);
    575 //    bool bool_value;
    576 //    if (IfAnyOf<int, bool>::Get(v, &bool_value)) {
    577 //      DoSomething(bool_value);
    578 //    } else {
    579 //      HandleInvalidType();
    580 //    }
    581 //    IfAnyOf<int>::Call(v, [](const auto& value) { DoSomething(value); });
    582 //
    583 template <typename... ValidTypes>
    584 struct IfAnyOf {
    585   // Calls Op on the underlying value of the variant and returns true when the
    586   // variant is a valid type, otherwise does nothing and returns false.
    587   template <typename Op, typename... Types>
    588   static bool Call(Variant<Types...>* variant, Op&& op) {
    589     static_assert(
    590         detail::Set<Types...>::template IsSubset<ValidTypes...>::value,
    591         "ValidTypes may only contain element types from the Variant.");
    592     return variant->Visit(CallOp<Op>{std::forward<Op>(op)});
    593   }
    594   template <typename Op, typename... Types>
    595   static bool Call(const Variant<Types...>* variant, Op&& op) {
    596     static_assert(
    597         detail::Set<Types...>::template IsSubset<ValidTypes...>::value,
    598         "ValidTypes may only contain element types from the Variant.");
    599     return variant->Visit(CallOp<Op>{std::forward<Op>(op)});
    600   }
    601 
    602   // Gets/converts the underlying value of the variant to type T and returns
    603   // true when the variant is a valid type, otherwise does nothing and returns
    604   // false.
    605   template <typename T, typename... Types>
    606   static bool Get(const Variant<Types...>* variant, T* value_out) {
    607     return Call(variant,
    608                 [value_out](const auto& value) { *value_out = value; });
    609   }
    610 
    611   // Moves the underlying value of the variant and returns true when the variant
    612   // is a valid type, otherwise does nothing and returns false.
    613   template <typename T, typename... Types>
    614   static bool Take(Variant<Types...>* variant, T* value_out) {
    615     return Call(variant,
    616                 [value_out](auto&& value) { *value_out = std::move(value); });
    617   }
    618 
    619   // Swaps the underlying value of the variant with |*value_out| and returns
    620   // true when the variant is a valid type, otherwise does nothing and returns
    621   // false.
    622   template <typename T, typename... Types>
    623   static bool Swap(Variant<Types...>* variant, T* value_out) {
    624     return Call(variant,
    625                 [value_out](auto&& value) { std::swap(*value_out, value); });
    626   }
    627 
    628  private:
    629   template <typename Op>
    630   struct CallOp {
    631     Op&& op;
    632     template <typename U>
    633     detail::EnableIfNotElement<bool, U, ValidTypes...> operator()(U&&) {
    634       return false;
    635     }
    636     template <typename U>
    637     detail::EnableIfElement<bool, U, ValidTypes...> operator()(const U& value) {
    638       std::forward<Op>(op)(value);
    639       return true;
    640     }
    641     template <typename U>
    642     detail::EnableIfElement<bool, U, ValidTypes...> operator()(U&& value) {
    643       std::forward<Op>(op)(std::forward<U>(value));
    644       return true;
    645     }
    646   };
    647 };
    648 
    649 }  // namespace rpc
    650 }  // namespace pdx
    651 }  // namespace android
    652 
    653 // Overloads of std::get<T> and std::get<I> for android::pdx::rpc::Variant.
    654 namespace std {
    655 
    656 template <typename T, typename... Types>
    657 inline T& get(::android::pdx::rpc::Variant<Types...>& v) {
    658   return *v.template get<T>();
    659 }
    660 template <typename T, typename... Types>
    661 inline T&& get(::android::pdx::rpc::Variant<Types...>&& v) {
    662   return std::move(*v.template get<T>());
    663 }
    664 template <typename T, typename... Types>
    665 inline const T& get(const ::android::pdx::rpc::Variant<Types...>& v) {
    666   return *v.template get<T>();
    667 }
    668 template <std::size_t I, typename... Types>
    669 inline ::android::pdx::rpc::detail::TypeForIndex<I, Types...>& get(
    670     ::android::pdx::rpc::Variant<Types...>& v) {
    671   return *v.template get<I>();
    672 }
    673 template <std::size_t I, typename... Types>
    674 inline ::android::pdx::rpc::detail::TypeForIndex<I, Types...>&& get(
    675     ::android::pdx::rpc::Variant<Types...>&& v) {
    676   return std::move(*v.template get<I>());
    677 }
    678 template <std::size_t I, typename... Types>
    679 inline const ::android::pdx::rpc::detail::TypeForIndex<I, Types...>& get(
    680     const ::android::pdx::rpc::Variant<Types...>& v) {
    681   return *v.template get<I>();
    682 }
    683 
    684 }  // namespace std
    685 
    686 #endif  // ANDROID_PDX_RPC_VARIANT_H_
    687