xref: /aosp_15_r20/external/swiftshader/src/Reactor/Traits.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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