2121#ifndef GPUCA_GPUCODE_COMPILEKERNELS
2222#include < type_traits>
2323#endif
24+ #else // OpenCL C++ and Metal, neither of which provides <type_traits>
25+ // Spelled for MSL, which OpenCL C++ also accepts, so both backends share one implementation:
26+ // enum values because program scope variables must be constant (MSL 4.1 spec, sec. 4.2), and
27+ // is_pointer / is_member_pointer forward rather than inherit because MSL has no derived classes
28+ // (sec. 1.5.4). Bare T* / T& need no address space: a partial specialization matches them all.
29+ #ifdef __METAL__
30+ #define GPUCA_TT_PROGRAMSCOPE constant
2431#else
32+ #define GPUCA_TT_PROGRAMSCOPE // not empty-by-default: in OpenCL 'constant' would mean __constant
33+ #endif
2534namespace std
2635{
2736template <bool B, class T , class F >
@@ -37,14 +46,14 @@ using conditional_t = typename conditional<B, T, F>::type;
3746
3847template <class T , class U >
3948struct is_same {
40- static constexpr bool value = false ;
49+ enum { value = false } ;
4150};
4251template <class T >
4352struct is_same <T, T> {
44- static constexpr bool value = true ;
53+ enum { value = true } ;
4554};
4655template <class T , class U >
47- static constexpr bool is_same_v = is_same<T, U>::value;
56+ GPUCA_TT_PROGRAMSCOPE static constexpr bool is_same_v = is_same<T, U>::value;
4857
4958template <bool B, class T = void >
5059struct enable_if {
@@ -97,14 +106,15 @@ using remove_volatile_t = typename remove_volatile<T>::type;
97106
98107template <class T >
99108struct is_pointer_t {
100- static constexpr bool value = false ;
109+ enum { value = false } ;
101110};
102111template <class T >
103112struct is_pointer_t <T*> {
104- static constexpr bool value = true ;
113+ enum { value = true } ;
105114};
106115template <class T >
107- struct is_pointer : is_pointer_t <typename std::remove_cv<T>::type> {
116+ struct is_pointer {
117+ enum { value = is_pointer_t <typename std::remove_cv<T>::type>::value };
108118};
109119
110120template <class T >
@@ -124,19 +134,21 @@ using remove_reference_t = typename remove_reference<T>::type;
124134
125135template <class T >
126136struct is_member_pointer_helper {
127- static constexpr bool value = false ;
137+ enum { value = false } ;
128138};
129139template <class T , class U >
130140struct is_member_pointer_helper <T U::*> {
131- static constexpr bool value = true ;
141+ enum { value = true } ;
132142};
133143template <class T >
134- struct is_member_pointer : is_member_pointer_helper<typename std::remove_cv<T>::type> {
144+ struct is_member_pointer {
145+ enum { value = is_member_pointer_helper<typename std::remove_cv<T>::type>::value };
135146};
136147template <class T >
137- static constexpr bool is_member_pointer_v = is_member_pointer<T>::value;
148+ GPUCA_TT_PROGRAMSCOPE static constexpr bool is_member_pointer_v = is_member_pointer<T>::value;
138149
139150} // namespace std
151+ #undef GPUCA_TT_PROGRAMSCOPE
140152#endif
141153
142154#endif
0 commit comments