1#ifndef ANDROID_PDX_RPC_ENUMERATION_H_
2#define ANDROID_PDX_RPC_ENUMERATION_H_
3
4#include <pdx/rpc/sequence.h>
5
6namespace android {
7namespace pdx {
8namespace rpc {
9
10// Utility for manipulating lists of types. Provides operations to lookup an
11// element by type or index.
12
13namespace detail {
14
15// Helper type that captures type and index for each element of a type
16// enumeration.
17template <std::size_t I, typename T>
18struct 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.
24template <typename Is, typename... Ts>
25struct 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.
31template <std::size_t... Is, typename... Ts>
32struct 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.
37template <typename T, std::size_t I>
38static IndexedElement<I, T> SelectElementByType(IndexedElement<I, T>);
39
40// Helper function that causes the compiler to deduce an IndexedElement<I, T>
41// given I.
42template <std::size_t I, typename T>
43static 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.
49template <typename T, typename... Ts>
50using 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.
57template <std::size_t I, typename... Ts>
58using 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