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