| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ | |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ | |
| 7 | |
| 8 #include <type_traits> | |
| 9 | |
| 10 #include "mojo/public/cpp/bindings/lib/template_util.h" | |
| 11 #include "mojo/public/cpp/bindings/struct_ptr.h" | |
| 12 #include "mojo/public/cpp/system/handle.h" | |
| 13 #include "mojo/public/cpp/system/message_pipe.h" | |
| 14 | |
| 15 namespace mojo { | |
| 16 class String; | |
| 17 | |
| 18 template <typename T> | |
| 19 class Array; | |
| 20 | |
| 21 template <typename Interface> | |
| 22 class InterfaceHandle; | |
| 23 | |
| 24 template <typename Interface> | |
| 25 class InterfaceRequest; | |
| 26 | |
| 27 template <typename K, typename V> | |
| 28 class Map; | |
| 29 | |
| 30 namespace internal { | |
| 31 template <typename T> | |
| 32 class Array_Data; | |
| 33 | |
| 34 #pragma pack(push, 1) | |
| 35 | |
| 36 struct StructHeader { | |
| 37 uint32_t num_bytes; | |
| 38 uint32_t version; | |
| 39 }; | |
| 40 static_assert(sizeof(StructHeader) == 8, "Bad sizeof(StructHeader)"); | |
| 41 | |
| 42 struct ArrayHeader { | |
| 43 uint32_t num_bytes; | |
| 44 uint32_t num_elements; | |
| 45 }; | |
| 46 static_assert(sizeof(ArrayHeader) == 8, "Bad_sizeof(ArrayHeader)"); | |
| 47 | |
| 48 template <typename T> | |
| 49 union StructPointer { | |
| 50 uint64_t offset; | |
| 51 T* ptr; | |
| 52 }; | |
| 53 static_assert(sizeof(StructPointer<char>) == 8, "Bad_sizeof(StructPointer)"); | |
| 54 | |
| 55 template <typename T> | |
| 56 union ArrayPointer { | |
| 57 uint64_t offset; | |
| 58 Array_Data<T>* ptr; | |
| 59 }; | |
| 60 static_assert(sizeof(ArrayPointer<char>) == 8, "Bad_sizeof(ArrayPointer)"); | |
| 61 | |
| 62 union StringPointer { | |
| 63 uint64_t offset; | |
| 64 Array_Data<char>* ptr; | |
| 65 }; | |
| 66 static_assert(sizeof(StringPointer) == 8, "Bad_sizeof(StringPointer)"); | |
| 67 | |
| 68 struct Interface_Data { | |
| 69 MessagePipeHandle handle; | |
| 70 uint32_t version; | |
| 71 }; | |
| 72 static_assert(sizeof(Interface_Data) == 8, "Bad_sizeof(Interface_Data)"); | |
| 73 | |
| 74 template <typename T> | |
| 75 union UnionPointer { | |
| 76 uint64_t offset; | |
| 77 T* ptr; | |
| 78 }; | |
| 79 static_assert(sizeof(UnionPointer<char>) == 8, "Bad_sizeof(UnionPointer)"); | |
| 80 | |
| 81 #pragma pack(pop) | |
| 82 | |
| 83 template <typename T> | |
| 84 void ResetIfNonNull(T* ptr) { | |
| 85 if (ptr) | |
| 86 *ptr = T(); | |
| 87 } | |
| 88 | |
| 89 template <typename T> | |
| 90 T FetchAndReset(T* ptr) { | |
| 91 T temp = *ptr; | |
| 92 *ptr = T(); | |
| 93 return temp; | |
| 94 } | |
| 95 | |
| 96 template <typename H> | |
| 97 struct IsHandle { | |
| 98 enum { value = std::is_base_of<Handle, H>::value }; | |
| 99 }; | |
| 100 | |
| 101 // TODO(vardhan): Replace RemoveStructPtr<> and UnwrapStructPtr<> with | |
| 102 // specializations of std::pointer_traits<> on [Inlined]StructPtr<>. | |
| 103 template <typename T> | |
| 104 struct RemoveStructPtr { | |
| 105 typedef T type; | |
| 106 }; | |
| 107 | |
| 108 template <typename T> | |
| 109 struct RemoveStructPtr<StructPtr<T>> { | |
| 110 typedef T type; | |
| 111 }; | |
| 112 | |
| 113 template <typename T> | |
| 114 struct RemoveStructPtr<InlinedStructPtr<T>> { | |
| 115 typedef T type; | |
| 116 }; | |
| 117 | |
| 118 template <typename T> | |
| 119 struct UnwrapStructPtr { | |
| 120 static T* value(T& x) { return &x; } | |
| 121 }; | |
| 122 | |
| 123 template <typename T> | |
| 124 struct UnwrapStructPtr<StructPtr<T>> { | |
| 125 static T* value(StructPtr<T>& x) { return x.get(); } | |
| 126 }; | |
| 127 | |
| 128 template <typename T> | |
| 129 struct UnwrapStructPtr<InlinedStructPtr<T>> { | |
| 130 static T* value(InlinedStructPtr<T>& x) { return x.get(); } | |
| 131 }; | |
| 132 | |
| 133 template <typename T> | |
| 134 struct UnwrapConstStructPtr { | |
| 135 static const T* value(const T& x) { return &x; } | |
| 136 }; | |
| 137 | |
| 138 template <typename T> | |
| 139 struct UnwrapConstStructPtr<StructPtr<T>> { | |
| 140 static const T* value(const StructPtr<T>& x) { return x.get(); } | |
| 141 }; | |
| 142 | |
| 143 template <typename T> | |
| 144 struct UnwrapConstStructPtr<InlinedStructPtr<T>> { | |
| 145 static const T* value(const InlinedStructPtr<T>& x) { return x.get(); } | |
| 146 }; | |
| 147 | |
| 148 template <typename T> | |
| 149 struct IsStructPtr { | |
| 150 static bool const value = IsSpecializationOf<StructPtr, T>::value || | |
| 151 IsSpecializationOf<InlinedStructPtr, T>::value; | |
| 152 }; | |
| 153 | |
| 154 template <typename T> | |
| 155 struct IsUnionWrapperType { | |
| 156 template <typename U> | |
| 157 static YesType Test(const typename U::Data_::MojomUnionDataType*); | |
| 158 | |
| 159 template <typename U> | |
| 160 static NoType Test(...); | |
| 161 | |
| 162 static const bool value = | |
| 163 sizeof(Test<T>(0)) == sizeof(YesType) && !std::is_const<T>::value; | |
| 164 }; | |
| 165 | |
| 166 template <typename T> | |
| 167 struct IsUnionDataType { | |
| 168 template <typename U> | |
| 169 static YesType Test(const typename U::MojomUnionDataType*); | |
| 170 | |
| 171 template <typename U> | |
| 172 static NoType Test(...); | |
| 173 | |
| 174 static const bool value = | |
| 175 sizeof(Test<T>(0)) == sizeof(YesType) && !std::is_const<T>::value; | |
| 176 }; | |
| 177 | |
| 178 // To introduce a new mojom type, you must define (partial or full) template | |
| 179 // specializations for the following traits templates, which operate on the C++ | |
| 180 // wrapper types representing a mojom type: | |
| 181 // - WrapperTraits: provides a |DataType| typedef which points to the | |
| 182 // serialized data type. | |
| 183 // - ValueTraits: provides an |Equals()| method for comparing the two wrapper | |
| 184 // values of the same type. | |
| 185 // | |
| 186 // Currently, full specializations of WrapperTraits are generated for mojo | |
| 187 // structs in their generated `.mojom.h`. In contrast, WrapperTraits for Unions | |
| 188 // don't need to be auto-generated because their underlying DataType can be | |
| 189 // accessed without dependency issues -- a catch-all WrapperTraits for unions is | |
| 190 // instead defined here. | |
| 191 // TODO(vardhan): Merge ValueTraits and WrapperTraits into one? | |
| 192 // TODO(vardhan): Write a doc about all the Traits templates you need to touch | |
| 193 // when introducing a new mojom type. | |
| 194 // TODO(vardhan): Instead of providing |move_only| & |is_union| template | |
| 195 // parameters, provide a default "typename Enable = void" template parameter, | |
| 196 // and have specializations define their own Enable expressions (similar to how | |
| 197 // ValueTraits is). | |
| 198 template <typename T, | |
| 199 bool move_only = IsMoveOnlyType<T>::value, | |
| 200 bool is_union = | |
| 201 IsUnionWrapperType<typename RemoveStructPtr<T>::type>::value> | |
| 202 struct WrapperTraits; | |
| 203 | |
| 204 // Catch-all for all mojom types not specialized below. | |
| 205 template <typename T> | |
| 206 struct WrapperTraits<T, false, false> { | |
| 207 using DataType = T; | |
| 208 }; | |
| 209 template <typename H> | |
| 210 struct WrapperTraits<ScopedHandleBase<H>, true, false> { | |
| 211 using DataType = H; | |
| 212 }; | |
| 213 template <typename I> | |
| 214 struct WrapperTraits<InterfaceRequest<I>, true, false> { | |
| 215 using DataType = MessagePipeHandle; | |
| 216 }; | |
| 217 template <typename Interface> | |
| 218 struct WrapperTraits<InterfaceHandle<Interface>, true, false> { | |
| 219 using DataType = Interface_Data; | |
| 220 }; | |
| 221 // Unions. | |
| 222 template <typename U> | |
| 223 struct WrapperTraits<StructPtr<U>, true, true> { | |
| 224 using DataType = typename U::Data_; | |
| 225 }; | |
| 226 template <typename U> | |
| 227 struct WrapperTraits<InlinedStructPtr<U>, true, true> { | |
| 228 using DataType = typename U::Data_; | |
| 229 }; | |
| 230 // Catch-all for other pointer types: arrays, maps. | |
| 231 template <typename S> | |
| 232 struct WrapperTraits<S, true, false> { | |
| 233 using DataType = typename S::Data_*; | |
| 234 }; | |
| 235 | |
| 236 template <typename T, typename Enable = void> | |
| 237 struct ValueTraits { | |
| 238 static bool Equals(const T& a, const T& b) { return a == b; } | |
| 239 }; | |
| 240 | |
| 241 template <typename T> | |
| 242 struct ValueTraits<T, | |
| 243 typename std::enable_if< | |
| 244 IsSpecializationOf<Array, T>::value || | |
| 245 IsSpecializationOf<Map, T>::value || | |
| 246 IsSpecializationOf<StructPtr, T>::value || | |
| 247 IsSpecializationOf<InlinedStructPtr, T>::value>::type> { | |
| 248 static bool Equals(const T& a, const T& b) { return a.Equals(b); } | |
| 249 }; | |
| 250 | |
| 251 template <typename T> | |
| 252 struct ValueTraits<ScopedHandleBase<T>> { | |
| 253 static bool Equals(const ScopedHandleBase<T>& a, | |
| 254 const ScopedHandleBase<T>& b) { | |
| 255 return (&a == &b) || (!a.is_valid() && !b.is_valid()); | |
| 256 } | |
| 257 }; | |
| 258 | |
| 259 // |InterfaceHandle|s hold message pipes uniquely, so they can only be equal if | |
| 260 // they're the same object or are both "invalid". | |
| 261 template <typename I> | |
| 262 struct ValueTraits<InterfaceHandle<I>> { | |
| 263 static bool Equals(const InterfaceHandle<I>& a, const InterfaceHandle<I>& b) { | |
| 264 return (&a == &b) || (!a.is_valid() && !b.is_valid()); | |
| 265 } | |
| 266 }; | |
| 267 | |
| 268 // |InterfaceRequest|s hold message pipes uniquely, so they can only be equal if | |
| 269 // they're the same object or are both "invalid". | |
| 270 template <typename I> | |
| 271 struct ValueTraits<InterfaceRequest<I>> { | |
| 272 static bool Equals(const InterfaceRequest<I>& a, | |
| 273 const InterfaceRequest<I>& b) { | |
| 274 return (&a == &b) || (!a.is_pending() && !b.is_pending()); | |
| 275 } | |
| 276 }; | |
| 277 | |
| 278 } // namespace internal | |
| 279 } // namespace mojo | |
| 280 | |
| 281 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ | |
| OLD | NEW |