1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved. 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*03ce13f7SAndroid Build Coastguard Worker // 7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*03ce13f7SAndroid Build Coastguard Worker // 9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License. 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker #ifndef rr_Traits_hpp 16*03ce13f7SAndroid Build Coastguard Worker #define rr_Traits_hpp 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include <stdint.h> 19*03ce13f7SAndroid Build Coastguard Worker #include <type_traits> 20*03ce13f7SAndroid Build Coastguard Worker 21*03ce13f7SAndroid Build Coastguard Worker namespace rr { 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker // Forward declarations 24*03ce13f7SAndroid Build Coastguard Worker class Value; 25*03ce13f7SAndroid Build Coastguard Worker 26*03ce13f7SAndroid Build Coastguard Worker class Void; 27*03ce13f7SAndroid Build Coastguard Worker class Bool; 28*03ce13f7SAndroid Build Coastguard Worker class Byte; 29*03ce13f7SAndroid Build Coastguard Worker class SByte; 30*03ce13f7SAndroid Build Coastguard Worker class Short; 31*03ce13f7SAndroid Build Coastguard Worker class UShort; 32*03ce13f7SAndroid Build Coastguard Worker class Int; 33*03ce13f7SAndroid Build Coastguard Worker class UInt; 34*03ce13f7SAndroid Build Coastguard Worker class Long; 35*03ce13f7SAndroid Build Coastguard Worker class Half; 36*03ce13f7SAndroid Build Coastguard Worker class Float; 37*03ce13f7SAndroid Build Coastguard Worker class Float4; 38*03ce13f7SAndroid Build Coastguard Worker 39*03ce13f7SAndroid Build Coastguard Worker template<class T> 40*03ce13f7SAndroid Build Coastguard Worker class Pointer; 41*03ce13f7SAndroid Build Coastguard Worker template<class T> 42*03ce13f7SAndroid Build Coastguard Worker class LValue; 43*03ce13f7SAndroid Build Coastguard Worker template<class T> 44*03ce13f7SAndroid Build Coastguard Worker class RValue; 45*03ce13f7SAndroid Build Coastguard Worker 46*03ce13f7SAndroid Build Coastguard Worker // IsDefined<T>::value is true if T is a valid type, otherwise false. 47*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Enable = void> 48*03ce13f7SAndroid Build Coastguard Worker struct IsDefined 49*03ce13f7SAndroid Build Coastguard Worker { 50*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = false; 51*03ce13f7SAndroid Build Coastguard Worker }; 52*03ce13f7SAndroid Build Coastguard Worker 53*03ce13f7SAndroid Build Coastguard Worker template<typename T> 54*03ce13f7SAndroid Build Coastguard Worker struct IsDefined<T, std::enable_if_t<(sizeof(T) > 0)>> 55*03ce13f7SAndroid Build Coastguard Worker { 56*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 57*03ce13f7SAndroid Build Coastguard Worker }; 58*03ce13f7SAndroid Build Coastguard Worker 59*03ce13f7SAndroid Build Coastguard Worker template<> 60*03ce13f7SAndroid Build Coastguard Worker struct IsDefined<void> 61*03ce13f7SAndroid Build Coastguard Worker { 62*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 63*03ce13f7SAndroid Build Coastguard Worker }; 64*03ce13f7SAndroid Build Coastguard Worker 65*03ce13f7SAndroid Build Coastguard Worker // CToReactorT<T> resolves to the corresponding Reactor type for the given C 66*03ce13f7SAndroid Build Coastguard Worker // template type T. 67*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename ENABLE = void> 68*03ce13f7SAndroid Build Coastguard Worker struct CToReactor; 69*03ce13f7SAndroid Build Coastguard Worker template<typename T> 70*03ce13f7SAndroid Build Coastguard Worker using CToReactorT = typename CToReactor<T>::type; 71*03ce13f7SAndroid Build Coastguard Worker 72*03ce13f7SAndroid Build Coastguard Worker // CToReactor specializations for POD types. 73*03ce13f7SAndroid Build Coastguard Worker template<> 74*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<void> 75*03ce13f7SAndroid Build Coastguard Worker { 76*03ce13f7SAndroid Build Coastguard Worker using type = Void; 77*03ce13f7SAndroid Build Coastguard Worker }; 78*03ce13f7SAndroid Build Coastguard Worker template<> 79*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<bool> 80*03ce13f7SAndroid Build Coastguard Worker { 81*03ce13f7SAndroid Build Coastguard Worker using type = Bool; 82*03ce13f7SAndroid Build Coastguard Worker static Bool cast(bool); 83*03ce13f7SAndroid Build Coastguard Worker }; 84*03ce13f7SAndroid Build Coastguard Worker template<> 85*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<uint8_t> 86*03ce13f7SAndroid Build Coastguard Worker { 87*03ce13f7SAndroid Build Coastguard Worker using type = Byte; 88*03ce13f7SAndroid Build Coastguard Worker static Byte cast(uint8_t); 89*03ce13f7SAndroid Build Coastguard Worker }; 90*03ce13f7SAndroid Build Coastguard Worker template<> 91*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<int8_t> 92*03ce13f7SAndroid Build Coastguard Worker { 93*03ce13f7SAndroid Build Coastguard Worker using type = SByte; 94*03ce13f7SAndroid Build Coastguard Worker static SByte cast(int8_t); 95*03ce13f7SAndroid Build Coastguard Worker }; 96*03ce13f7SAndroid Build Coastguard Worker template<> 97*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<int16_t> 98*03ce13f7SAndroid Build Coastguard Worker { 99*03ce13f7SAndroid Build Coastguard Worker using type = Short; 100*03ce13f7SAndroid Build Coastguard Worker static Short cast(int16_t); 101*03ce13f7SAndroid Build Coastguard Worker }; 102*03ce13f7SAndroid Build Coastguard Worker template<> 103*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<uint16_t> 104*03ce13f7SAndroid Build Coastguard Worker { 105*03ce13f7SAndroid Build Coastguard Worker using type = UShort; 106*03ce13f7SAndroid Build Coastguard Worker static UShort cast(uint16_t); 107*03ce13f7SAndroid Build Coastguard Worker }; 108*03ce13f7SAndroid Build Coastguard Worker template<> 109*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<int32_t> 110*03ce13f7SAndroid Build Coastguard Worker { 111*03ce13f7SAndroid Build Coastguard Worker using type = Int; 112*03ce13f7SAndroid Build Coastguard Worker static Int cast(int32_t); 113*03ce13f7SAndroid Build Coastguard Worker }; 114*03ce13f7SAndroid Build Coastguard Worker template<> 115*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<uint32_t> 116*03ce13f7SAndroid Build Coastguard Worker { 117*03ce13f7SAndroid Build Coastguard Worker using type = UInt; 118*03ce13f7SAndroid Build Coastguard Worker static UInt cast(uint32_t); 119*03ce13f7SAndroid Build Coastguard Worker }; 120*03ce13f7SAndroid Build Coastguard Worker template<> 121*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<float> 122*03ce13f7SAndroid Build Coastguard Worker { 123*03ce13f7SAndroid Build Coastguard Worker using type = Float; 124*03ce13f7SAndroid Build Coastguard Worker static Float cast(float); 125*03ce13f7SAndroid Build Coastguard Worker }; 126*03ce13f7SAndroid Build Coastguard Worker template<> 127*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<float[4]> 128*03ce13f7SAndroid Build Coastguard Worker { 129*03ce13f7SAndroid Build Coastguard Worker using type = Float4; 130*03ce13f7SAndroid Build Coastguard Worker static Float4 cast(float[4]); 131*03ce13f7SAndroid Build Coastguard Worker }; 132*03ce13f7SAndroid Build Coastguard Worker 133*03ce13f7SAndroid Build Coastguard Worker // TODO: Long has no constructor that takes a uint64_t 134*03ce13f7SAndroid Build Coastguard Worker template<> 135*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<uint64_t> 136*03ce13f7SAndroid Build Coastguard Worker { 137*03ce13f7SAndroid Build Coastguard Worker using type = Long; /* static Long cast(uint64_t); */ 138*03ce13f7SAndroid Build Coastguard Worker }; 139*03ce13f7SAndroid Build Coastguard Worker 140*03ce13f7SAndroid Build Coastguard Worker // HasReactorType<T>::value resolves to true iff there exists a 141*03ce13f7SAndroid Build Coastguard Worker // CToReactorT specialization for type T. 142*03ce13f7SAndroid Build Coastguard Worker template<typename T> 143*03ce13f7SAndroid Build Coastguard Worker using HasReactorType = IsDefined<CToReactorT<T>>; 144*03ce13f7SAndroid Build Coastguard Worker 145*03ce13f7SAndroid Build Coastguard Worker // CToReactorPtr<T>::type resolves to the corresponding Reactor Pointer<> 146*03ce13f7SAndroid Build Coastguard Worker // type for T*. 147*03ce13f7SAndroid Build Coastguard Worker // For T types that have a CToReactorT<> specialization, 148*03ce13f7SAndroid Build Coastguard Worker // CToReactorPtr<T>::type resolves to Pointer< CToReactorT<T> >, otherwise 149*03ce13f7SAndroid Build Coastguard Worker // CToReactorPtr<T>::type resolves to Pointer<Byte>. 150*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename ENABLE = void> 151*03ce13f7SAndroid Build Coastguard Worker struct CToReactorPtr 152*03ce13f7SAndroid Build Coastguard Worker { 153*03ce13f7SAndroid Build Coastguard Worker using type = Pointer<Byte>; 154*03ce13f7SAndroid Build Coastguard Worker static inline type cast(const T *v); // implemented in Traits.inl 155*03ce13f7SAndroid Build Coastguard Worker }; 156*03ce13f7SAndroid Build Coastguard Worker 157*03ce13f7SAndroid Build Coastguard Worker // CToReactorPtr specialization for T types that have a CToReactorT<> 158*03ce13f7SAndroid Build Coastguard Worker // specialization. 159*03ce13f7SAndroid Build Coastguard Worker template<typename T> 160*03ce13f7SAndroid Build Coastguard Worker struct CToReactorPtr<T, std::enable_if_t<HasReactorType<T>::value>> 161*03ce13f7SAndroid Build Coastguard Worker { 162*03ce13f7SAndroid Build Coastguard Worker using type = Pointer<CToReactorT<T>>; 163*03ce13f7SAndroid Build Coastguard Worker static inline type cast(const T *v); // implemented in Traits.inl 164*03ce13f7SAndroid Build Coastguard Worker }; 165*03ce13f7SAndroid Build Coastguard Worker 166*03ce13f7SAndroid Build Coastguard Worker // CToReactorPtr specialization for void*. 167*03ce13f7SAndroid Build Coastguard Worker // Maps to Pointer<Byte> instead of Pointer<Void>. 168*03ce13f7SAndroid Build Coastguard Worker template<> 169*03ce13f7SAndroid Build Coastguard Worker struct CToReactorPtr<void, void> 170*03ce13f7SAndroid Build Coastguard Worker { 171*03ce13f7SAndroid Build Coastguard Worker using type = Pointer<Byte>; 172*03ce13f7SAndroid Build Coastguard Worker static inline type cast(const void *v); // implemented in Traits.inl 173*03ce13f7SAndroid Build Coastguard Worker }; 174*03ce13f7SAndroid Build Coastguard Worker 175*03ce13f7SAndroid Build Coastguard Worker // CToReactorPtr specialization for function pointer types. 176*03ce13f7SAndroid Build Coastguard Worker // Maps to Pointer<Byte>. 177*03ce13f7SAndroid Build Coastguard Worker // Drops the 'const' qualifier from the cast() method to avoid warnings 178*03ce13f7SAndroid Build Coastguard Worker // about const having no meaning for function types. 179*03ce13f7SAndroid Build Coastguard Worker template<typename T> 180*03ce13f7SAndroid Build Coastguard Worker struct CToReactorPtr<T, std::enable_if_t<std::is_function<T>::value>> 181*03ce13f7SAndroid Build Coastguard Worker { 182*03ce13f7SAndroid Build Coastguard Worker using type = Pointer<Byte>; 183*03ce13f7SAndroid Build Coastguard Worker static inline type cast(T *v); // implemented in Traits.inl 184*03ce13f7SAndroid Build Coastguard Worker }; 185*03ce13f7SAndroid Build Coastguard Worker 186*03ce13f7SAndroid Build Coastguard Worker template<typename T> 187*03ce13f7SAndroid Build Coastguard Worker using CToReactorPtrT = typename CToReactorPtr<T>::type; 188*03ce13f7SAndroid Build Coastguard Worker 189*03ce13f7SAndroid Build Coastguard Worker // CToReactor specialization for pointer types. 190*03ce13f7SAndroid Build Coastguard Worker // For T types that have a CToReactorT<> specialization, 191*03ce13f7SAndroid Build Coastguard Worker // CToReactorT<T*>::type resolves to Pointer< CToReactorT<T> >, otherwise 192*03ce13f7SAndroid Build Coastguard Worker // CToReactorT<T*>::type resolves to Pointer<Byte>. 193*03ce13f7SAndroid Build Coastguard Worker template<typename T> 194*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<T, std::enable_if_t<std::is_pointer<T>::value>> 195*03ce13f7SAndroid Build Coastguard Worker { 196*03ce13f7SAndroid Build Coastguard Worker using elem = typename std::remove_pointer<T>::type; 197*03ce13f7SAndroid Build Coastguard Worker using type = CToReactorPtrT<elem>; 198*03ce13f7SAndroid Build Coastguard Worker static inline type cast(T v); // implemented in Traits.inl 199*03ce13f7SAndroid Build Coastguard Worker }; 200*03ce13f7SAndroid Build Coastguard Worker 201*03ce13f7SAndroid Build Coastguard Worker // CToReactor specialization for enum types. 202*03ce13f7SAndroid Build Coastguard Worker template<typename T> 203*03ce13f7SAndroid Build Coastguard Worker struct CToReactor<T, std::enable_if_t<std::is_enum<T>::value>> 204*03ce13f7SAndroid Build Coastguard Worker { 205*03ce13f7SAndroid Build Coastguard Worker using underlying = typename std::underlying_type<T>::type; 206*03ce13f7SAndroid Build Coastguard Worker using type = CToReactorT<underlying>; 207*03ce13f7SAndroid Build Coastguard Worker static type cast(T v); // implemented in Traits.inl 208*03ce13f7SAndroid Build Coastguard Worker }; 209*03ce13f7SAndroid Build Coastguard Worker 210*03ce13f7SAndroid Build Coastguard Worker // IsRValue::value is true if T is of type RValue<X>, where X is any type. 211*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Enable = void> 212*03ce13f7SAndroid Build Coastguard Worker struct IsRValue 213*03ce13f7SAndroid Build Coastguard Worker { 214*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = false; 215*03ce13f7SAndroid Build Coastguard Worker }; 216*03ce13f7SAndroid Build Coastguard Worker template<typename T> 217*03ce13f7SAndroid Build Coastguard Worker struct IsRValue<T, std::enable_if_t<IsDefined<typename T::rvalue_underlying_type>::value>> 218*03ce13f7SAndroid Build Coastguard Worker { 219*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 220*03ce13f7SAndroid Build Coastguard Worker }; 221*03ce13f7SAndroid Build Coastguard Worker 222*03ce13f7SAndroid Build Coastguard Worker // IsLValue::value is true if T is of, or derives from type LValue<T>. 223*03ce13f7SAndroid Build Coastguard Worker template<typename T> 224*03ce13f7SAndroid Build Coastguard Worker struct IsLValue 225*03ce13f7SAndroid Build Coastguard Worker { 226*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = std::is_base_of<LValue<T>, T>::value; 227*03ce13f7SAndroid Build Coastguard Worker }; 228*03ce13f7SAndroid Build Coastguard Worker 229*03ce13f7SAndroid Build Coastguard Worker // IsReference::value is true if T is of type Reference<X>, where X is any type. 230*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Enable = void> 231*03ce13f7SAndroid Build Coastguard Worker struct IsReference 232*03ce13f7SAndroid Build Coastguard Worker { 233*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = false; 234*03ce13f7SAndroid Build Coastguard Worker }; 235*03ce13f7SAndroid Build Coastguard Worker template<typename T> 236*03ce13f7SAndroid Build Coastguard Worker struct IsReference<T, std::enable_if_t<IsDefined<typename T::reference_underlying_type>::value>> 237*03ce13f7SAndroid Build Coastguard Worker { 238*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 239*03ce13f7SAndroid Build Coastguard Worker }; 240*03ce13f7SAndroid Build Coastguard Worker 241*03ce13f7SAndroid Build Coastguard Worker // ReactorTypeT<T> returns the LValue Reactor type for T. 242*03ce13f7SAndroid Build Coastguard Worker // T can be a C-type, RValue or LValue. 243*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename ENABLE = void> 244*03ce13f7SAndroid Build Coastguard Worker struct ReactorType; 245*03ce13f7SAndroid Build Coastguard Worker template<typename T> 246*03ce13f7SAndroid Build Coastguard Worker using ReactorTypeT = typename ReactorType<T>::type; 247*03ce13f7SAndroid Build Coastguard Worker template<typename T> 248*03ce13f7SAndroid Build Coastguard Worker struct ReactorType<T, std::enable_if_t<IsDefined<CToReactorT<T>>::value>> 249*03ce13f7SAndroid Build Coastguard Worker { 250*03ce13f7SAndroid Build Coastguard Worker using type = CToReactorT<T>; castrr::ReactorType251*03ce13f7SAndroid Build Coastguard Worker static type cast(T v) { return CToReactor<T>::cast(v); } 252*03ce13f7SAndroid Build Coastguard Worker }; 253*03ce13f7SAndroid Build Coastguard Worker template<typename T> 254*03ce13f7SAndroid Build Coastguard Worker struct ReactorType<T, std::enable_if_t<IsRValue<T>::value>> 255*03ce13f7SAndroid Build Coastguard Worker { 256*03ce13f7SAndroid Build Coastguard Worker using type = typename T::rvalue_underlying_type; castrr::ReactorType257*03ce13f7SAndroid Build Coastguard Worker static type cast(T v) { return type(v); } 258*03ce13f7SAndroid Build Coastguard Worker }; 259*03ce13f7SAndroid Build Coastguard Worker template<typename T> 260*03ce13f7SAndroid Build Coastguard Worker struct ReactorType<T, std::enable_if_t<IsLValue<T>::value>> 261*03ce13f7SAndroid Build Coastguard Worker { 262*03ce13f7SAndroid Build Coastguard Worker using type = T; castrr::ReactorType263*03ce13f7SAndroid Build Coastguard Worker static type cast(T v) { return type(v); } 264*03ce13f7SAndroid Build Coastguard Worker }; 265*03ce13f7SAndroid Build Coastguard Worker template<typename T> 266*03ce13f7SAndroid Build Coastguard Worker struct ReactorType<T, std::enable_if_t<IsReference<T>::value>> 267*03ce13f7SAndroid Build Coastguard Worker { 268*03ce13f7SAndroid Build Coastguard Worker using type = T; castrr::ReactorType269*03ce13f7SAndroid Build Coastguard Worker static type cast(T v) { return type(v); } 270*03ce13f7SAndroid Build Coastguard Worker }; 271*03ce13f7SAndroid Build Coastguard Worker 272*03ce13f7SAndroid Build Coastguard Worker // Reactor types that can be used as a return type for a function. 273*03ce13f7SAndroid Build Coastguard Worker template<typename T> 274*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsReturn 275*03ce13f7SAndroid Build Coastguard Worker { 276*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = false; 277*03ce13f7SAndroid Build Coastguard Worker }; 278*03ce13f7SAndroid Build Coastguard Worker template<> 279*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsReturn<Void> 280*03ce13f7SAndroid Build Coastguard Worker { 281*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 282*03ce13f7SAndroid Build Coastguard Worker }; 283*03ce13f7SAndroid Build Coastguard Worker template<> 284*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsReturn<Int> 285*03ce13f7SAndroid Build Coastguard Worker { 286*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 287*03ce13f7SAndroid Build Coastguard Worker }; 288*03ce13f7SAndroid Build Coastguard Worker template<> 289*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsReturn<UInt> 290*03ce13f7SAndroid Build Coastguard Worker { 291*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 292*03ce13f7SAndroid Build Coastguard Worker }; 293*03ce13f7SAndroid Build Coastguard Worker template<> 294*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsReturn<Float> 295*03ce13f7SAndroid Build Coastguard Worker { 296*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 297*03ce13f7SAndroid Build Coastguard Worker }; 298*03ce13f7SAndroid Build Coastguard Worker template<typename T> 299*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsReturn<Pointer<T>> 300*03ce13f7SAndroid Build Coastguard Worker { 301*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 302*03ce13f7SAndroid Build Coastguard Worker }; 303*03ce13f7SAndroid Build Coastguard Worker 304*03ce13f7SAndroid Build Coastguard Worker // Reactor types that can be used as a parameter types for a function. 305*03ce13f7SAndroid Build Coastguard Worker template<typename T> 306*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsParameter 307*03ce13f7SAndroid Build Coastguard Worker { 308*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = false; 309*03ce13f7SAndroid Build Coastguard Worker }; 310*03ce13f7SAndroid Build Coastguard Worker template<> 311*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsParameter<Int> 312*03ce13f7SAndroid Build Coastguard Worker { 313*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 314*03ce13f7SAndroid Build Coastguard Worker }; 315*03ce13f7SAndroid Build Coastguard Worker template<> 316*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsParameter<UInt> 317*03ce13f7SAndroid Build Coastguard Worker { 318*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 319*03ce13f7SAndroid Build Coastguard Worker }; 320*03ce13f7SAndroid Build Coastguard Worker template<> 321*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsParameter<Float> 322*03ce13f7SAndroid Build Coastguard Worker { 323*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 324*03ce13f7SAndroid Build Coastguard Worker }; 325*03ce13f7SAndroid Build Coastguard Worker template<typename T> 326*03ce13f7SAndroid Build Coastguard Worker struct CanBeUsedAsParameter<Pointer<T>> 327*03ce13f7SAndroid Build Coastguard Worker { 328*03ce13f7SAndroid Build Coastguard Worker static constexpr bool value = true; 329*03ce13f7SAndroid Build Coastguard Worker }; 330*03ce13f7SAndroid Build Coastguard Worker 331*03ce13f7SAndroid Build Coastguard Worker // AssertParameterTypeIsValid statically asserts that all template parameter 332*03ce13f7SAndroid Build Coastguard Worker // types can be used as a Reactor function parameter. 333*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename... other> 334*03ce13f7SAndroid Build Coastguard Worker struct AssertParameterTypeIsValid : AssertParameterTypeIsValid<other...> 335*03ce13f7SAndroid Build Coastguard Worker { 336*03ce13f7SAndroid Build Coastguard Worker static_assert(CanBeUsedAsParameter<T>::value, "Invalid parameter type"); 337*03ce13f7SAndroid Build Coastguard Worker }; 338*03ce13f7SAndroid Build Coastguard Worker template<typename T> 339*03ce13f7SAndroid Build Coastguard Worker struct AssertParameterTypeIsValid<T> 340*03ce13f7SAndroid Build Coastguard Worker { 341*03ce13f7SAndroid Build Coastguard Worker static_assert(CanBeUsedAsParameter<T>::value, "Invalid parameter type"); 342*03ce13f7SAndroid Build Coastguard Worker }; 343*03ce13f7SAndroid Build Coastguard Worker 344*03ce13f7SAndroid Build Coastguard Worker // AssertFunctionSignatureIsValid statically asserts that the Reactor 345*03ce13f7SAndroid Build Coastguard Worker // function signature is valid. 346*03ce13f7SAndroid Build Coastguard Worker template<typename Return, typename... Arguments> 347*03ce13f7SAndroid Build Coastguard Worker class AssertFunctionSignatureIsValid; 348*03ce13f7SAndroid Build Coastguard Worker template<typename Return> 349*03ce13f7SAndroid Build Coastguard Worker class AssertFunctionSignatureIsValid<Return(Void)> 350*03ce13f7SAndroid Build Coastguard Worker {}; 351*03ce13f7SAndroid Build Coastguard Worker template<typename Return, typename... Arguments> 352*03ce13f7SAndroid Build Coastguard Worker class AssertFunctionSignatureIsValid<Return(Arguments...)> 353*03ce13f7SAndroid Build Coastguard Worker { 354*03ce13f7SAndroid Build Coastguard Worker static_assert(CanBeUsedAsReturn<Return>::value, "Invalid return type"); 355*03ce13f7SAndroid Build Coastguard Worker static_assert(sizeof(AssertParameterTypeIsValid<Arguments...>) >= 0, ""); 356*03ce13f7SAndroid Build Coastguard Worker }; 357*03ce13f7SAndroid Build Coastguard Worker 358*03ce13f7SAndroid Build Coastguard Worker } // namespace rr 359*03ce13f7SAndroid Build Coastguard Worker 360*03ce13f7SAndroid Build Coastguard Worker #endif // rr_Traits_hpp 361