Home | History | Annotate | Download | only in rpc
      1 #ifndef ANDROID_PDX_RPC_ENUMERATION_H_
      2 #define ANDROID_PDX_RPC_ENUMERATION_H_
      3 
      4 #include <pdx/rpc/sequence.h>
      5 
      6 namespace android {
      7 namespace pdx {
      8 namespace rpc {
      9 
     10 // Utility for manipulating lists of types. Provides operations to lookup an
     11 // element by type or index.
     12 
     13 namespace detail {
     14 
     15 // Helper type that captures type and index for each element of a type
     16 // enumeration.
     17 template <std::size_t I, typename T>
     18 struct IndexedElement {
     19   using Type = T;
     20   static constexpr std::size_t Index = I;
     21 };
     22 
     23 // Helper type that captures an IndexSequence and corresponding list of types.
     24 template <typename Is, typename... Ts>
     25 struct ElementIndexer;
     26 
     27 // Partial specialization that generates an instantiation of IndexElement<I, T>
     28 // for each element of a type enumeration using inheritance. Once a type
     29 // enumeration is instantiated this way the compiler is able to deduce either I
     30 // or T from the other using the method below.
     31 template <std::size_t... Is, typename... Ts>
     32 struct ElementIndexer<IndexSequence<Is...>, Ts...> : IndexedElement<Is, Ts>... {
     33 };
     34 
     35 // Helper function that causes the compiler to deduce an IndexedElement<I, T>
     36 // given T.
     37 template <typename T, std::size_t I>
     38 static IndexedElement<I, T> SelectElementByType(IndexedElement<I, T>);
     39 
     40 // Helper function that causes the compiler to deduce an IndexedElement<I, T>
     41 // given I.
     42 template <std::size_t I, typename T>
     43 static IndexedElement<I, T> SelectElementByIndex(IndexedElement<I, T>);
     44 
     45 }  // namespace detail
     46 
     47 // Deduces the IndexedElement<I, T> given T and a type sequence Ts. This may be
     48 // used to determine the index of T within Ts at compile time.
     49 template <typename T, typename... Ts>
     50 using ElementForType = decltype(detail::SelectElementByType<T>(
     51     detail::ElementIndexer<typename IndexSequenceFor<Ts...>::type, Ts...>{}));
     52 
     53 // Deduces the IndexedElement<I, T> given I and a type sequence Ts. This may be
     54 // used to determine the type of the element at index I within Ts at compile
     55 // time. Tuple operations may also be used to accomplish the same task, however
     56 // this implementation is provided here for symmetry.
     57 template <std::size_t I, typename... Ts>
     58 using ElementForIndex = decltype(detail::SelectElementByIndex<I>(
     59     detail::ElementIndexer<typename IndexSequenceFor<Ts...>::type, Ts...>{}));
     60 
     61 }  // namespace rpc
     62 }  // namespace pdx
     63 }  // namespace android
     64 
     65 #endif  // ANDROID_PDX_RPC_ENUMERATION_H_
     66