1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <type_traits>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/type_operators.h>
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx {
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace rpc {
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility type to capture return and argument types of a function signature.
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Examples:
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//     typedef SignatureType<int(int)> SignatureType;
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//     using SignatureType = SignatureType<int(int)>;
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing SignatureType = T;
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility class to extract return and argument types from function types.
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Provides nested types for return value, arguments, and full signature. Also
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// provides accessor types for individual arguments, argument-arity, and type
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// substitution.
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct FunctionTraits;
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Return_, typename... Args_>
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct FunctionTraits<Return_(Args_...)> {
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using Return = Return_;
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using Args = std::tuple<Args_...>;
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using Signature = SignatureType<Return_(Args_...)>;
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  enum : std::size_t { Arity = sizeof...(Args_) };
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  template <std::size_t Index>
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using Arg = typename std::tuple_element<Index, Args>::type;
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  template <typename... Params>
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using RewriteArgs =
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      SignatureType<Return_(ConditionalRewrite<Args_, Params>...)>;
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  template <typename ReturnType, typename... Params>
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using RewriteSignature =
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      SignatureType<ConditionalRewrite<Return_, ReturnType>(
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          ConditionalRewrite<Args_, Params>...)>;
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
46e19fc9ebfa0c7098ded7463f45bfbdde5ce3e130Corey Tabaka  template <template <typename> class Wrapper, typename ReturnType,
47e19fc9ebfa0c7098ded7463f45bfbdde5ce3e130Corey Tabaka            typename... Params>
48e19fc9ebfa0c7098ded7463f45bfbdde5ce3e130Corey Tabaka  using RewriteSignatureWrapReturn =
49e19fc9ebfa0c7098ded7463f45bfbdde5ce3e130Corey Tabaka      SignatureType<Wrapper<ConditionalRewrite<Return_, ReturnType>>(
50e19fc9ebfa0c7098ded7463f45bfbdde5ce3e130Corey Tabaka          ConditionalRewrite<Args_, Params>...)>;
51e19fc9ebfa0c7098ded7463f45bfbdde5ce3e130Corey Tabaka
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  template <typename ReturnType>
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using RewriteReturn =
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      SignatureType<ConditionalRewrite<Return_, ReturnType>(Args_...)>;
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace rpc
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace pdx
59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif  //  ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
62