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