1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_TYPE_OPERATORS_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_TYPE_OPERATORS_H_ 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <array> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <map> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <type_traits> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <unordered_map> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <vector> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/channel_handle.h> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/file_handle.h> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/array_wrapper.h> 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/buffer_wrapper.h> 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/copy_cv_reference.h> 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/pointer_wrapper.h> 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/string_wrapper.h> 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace rpc { 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Simplifies type expressions. 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T> 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing Decay = typename std::decay<T>::type; 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares the underlying type of A and B. 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B> 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing IsEquivalent = typename std::is_same<Decay<A>, Decay<B>>::type; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Logical AND over template parameter pack. 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T> 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct And : std::false_type {}; 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B> 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct And<A, B> : std::integral_constant<bool, A::value && B::value> {}; 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename... Rest> 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct And<A, B, Rest...> : And<A, And<B, Rest...>> {}; 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Determines whether A is convertible to B (serializes to the same format) 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// using these rules: 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 1. std:vector<T, Any...> is convertible to ArrayWrapper<T>. 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 2. ArrayWrapper<T> is convertible to std:vector<T, Any...>. 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 3. std::basic_string<T, Any...> is convertible to StringWrapper<T>. 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 4. StringWrapper<T> is convertible to std::basic_string<T, Any...>. 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 5. BufferWrapper<T*> is convertible to BufferWrapper<std::vector<T, 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Any...>>. 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 6. BufferWrapper<std::vector<T, ...>> is convertible to BufferWrapper<T*>. 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 7. The value type T of A and B must match. 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares A and B for convertibility. This base type determines convertibility 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// by equivalence of the underlying types of A and B. Specializations of this 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// type handle the rules for which complex types are convertible. 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B> 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible : IsEquivalent<A, B> {}; 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares TT<A, ...> and TT<B, ...>; these are convertible if A and B are 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertible. 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <template <typename, typename...> class TT, typename A, typename B, 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename... AnyA, typename... AnyB> 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<TT<A, AnyA...>, TT<B, AnyB...>> 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsConvertible<Decay<A>, Decay<B>> {}; 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares TT<KeyA, ValueA, ...> and TT<KeyB, ValueB, ...>; these are 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertible if KeyA and KeyB are 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertible and ValueA and ValueB are convertible. 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <template <typename, typename, typename...> class TT, typename KeyA, 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename ValueA, typename KeyB, typename ValueB, typename... AnyA, 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename... AnyB> 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<TT<KeyA, ValueA, AnyA...>, TT<KeyB, ValueB, AnyB...>> 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>, 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IsConvertible<Decay<ValueA>, Decay<ValueB>>> {}; 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares two std::pairs to see if the corresponding elements are convertible. 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename C, typename D> 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::pair<A, B>, std::pair<C, D>> 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : And<IsConvertible<Decay<A>, Decay<C>>, 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IsConvertible<Decay<B>, Decay<D>>> {}; 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares std::pair with a two-element std::tuple to see if the corresponding 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// elements are convertible. 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename C, typename D> 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::pair<A, B>, std::tuple<C, D>> 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : And<IsConvertible<Decay<A>, Decay<C>>, 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IsConvertible<Decay<B>, Decay<D>>> {}; 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename C, typename D> 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::tuple<A, B>, std::pair<C, D>> 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : And<IsConvertible<Decay<A>, Decay<C>>, 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IsConvertible<Decay<B>, Decay<D>>> {}; 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares two std::tuples to see if the corresponding elements are 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertible. 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... A, typename... B> 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::tuple<A...>, std::tuple<B...>> 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : And<IsConvertible<Decay<A>, Decay<B>>...> {}; 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares std::vector, std::array, and ArrayWrapper; these are convertible if 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// the value types are convertible. 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename... Any> 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::vector<A, Any...>, ArrayWrapper<B>> 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsConvertible<Decay<A>, Decay<B>> {}; 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename... Any> 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<ArrayWrapper<A>, std::vector<B, Any...>> 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsConvertible<Decay<A>, Decay<B>> {}; 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename... Any, std::size_t Size> 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::vector<A, Any...>, std::array<B, Size>> 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsConvertible<Decay<A>, Decay<B>> {}; 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename... Any, std::size_t Size> 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::array<A, Size>, std::vector<B, Any...>> 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsConvertible<Decay<A>, Decay<B>> {}; 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, std::size_t Size> 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<ArrayWrapper<A>, std::array<B, Size>> 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsConvertible<Decay<A>, Decay<B>> {}; 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, std::size_t Size> 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::array<A, Size>, ArrayWrapper<B>> 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsConvertible<Decay<A>, Decay<B>> {}; 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares std::map and std::unordered_map; these are convertible if the keys 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// are convertible and the values are convertible. 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename KeyA, typename ValueA, typename KeyB, typename ValueB, 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename... AnyA, typename... AnyB> 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::map<KeyA, ValueA, AnyA...>, 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unordered_map<KeyB, ValueB, AnyB...>> 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>, 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IsConvertible<Decay<ValueA>, Decay<ValueB>>> {}; 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename KeyA, typename ValueA, typename KeyB, typename ValueB, 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename... AnyA, typename... AnyB> 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::unordered_map<KeyA, ValueA, AnyA...>, 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::map<KeyB, ValueB, AnyB...>> 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>, 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IsConvertible<Decay<ValueA>, Decay<ValueB>>> {}; 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares BufferWrapper<A*> and BufferWrapper<std::vector<B>>; these are 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertible if A and B are equivalent. Allocator types are not relevant to 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertibility. 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename Allocator> 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<BufferWrapper<A*>, 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper<std::vector<B, Allocator>>> 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsEquivalent<A, B> {}; 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename Allocator> 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<BufferWrapper<std::vector<A, Allocator>>, 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper<B*>> : IsEquivalent<A, B> {}; 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename AllocatorA, typename AllocatorB> 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<BufferWrapper<std::vector<A, AllocatorA>>, 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper<std::vector<B, AllocatorB>>> 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsEquivalent<A, B> {}; 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B> 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<BufferWrapper<A*>, BufferWrapper<B*>> 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsEquivalent<A, B> {}; 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares std::basic_string<A, ...> and StringWrapper<B>; these are 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertible if A and B are equivalent. 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename... Any> 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<std::basic_string<A, Any...>, StringWrapper<B>> 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsEquivalent<A, B> {}; 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B, typename... Any> 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<StringWrapper<A>, std::basic_string<B, Any...>> 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : IsEquivalent<A, B> {}; 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Compares PointerWrapper<A> and B; these are convertible if A and B are 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// convertible. 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B> 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<PointerWrapper<A>, B> : IsConvertible<Decay<A>, Decay<B>> { 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B> 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<A, PointerWrapper<B>> : IsConvertible<Decay<A>, Decay<B>> { 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// LocalHandle is convertible to RemoteHandle on the service side. This means 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// that a RemoteHandle may be supplied by a service when the protocol calls for 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// a LocalHandle return value. The other way around is not safe and can leak 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// file descriptors. The ServicePayload class enforces this policy by only 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// supporting RemoteHandle for pushed handles. 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <> 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<LocalHandle, RemoteHandle> : std::true_type {}; 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <> 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<LocalHandle, BorrowedHandle> : std::true_type {}; 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <> 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<LocalChannelHandle, RemoteChannelHandle> : std::true_type { 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <> 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IsConvertible<LocalChannelHandle, BorrowedChannelHandle> 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : std::true_type {}; 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Conditionally "rewrites" type A as type B, including cv-reference qualifiers, 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// iff A is convertible to B. 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename A, typename B> 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing ConditionalRewrite = 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename std::conditional<IsConvertible<Decay<A>, Decay<B>>::value, 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CopyCVReferenceType<A, B>, A>::type; 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace rpc 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_PDX_RPC_TYPE_OPERATORS_H_ 196