@@ -19,6 +19,7 @@ namespace impl
19
19
template<class T, bool C>
20
20
struct is_const_helper : bool_constant<C>
21
21
{
22
+ using type = T;
22
23
NBL_CONSTEXPR_STATIC_INLINE bool is_constant = is_const<T>::value;
23
24
};
24
25
@@ -33,6 +34,11 @@ enum e_member_presence
33
34
template<class T>
34
35
T declval (){}
35
36
37
+ template<bool =false >
38
+ struct if_2_else_1 : integral_constant<uint32_t,1 > {};
39
+ template<>
40
+ struct if_2_else_1<true > : integral_constant<uint32_t,2 > {};
41
+
36
42
}
37
43
38
44
typedef impl::e_member_presence e_member_presence;
@@ -67,5 +73,94 @@ NBL_GENERATE_MEMBER_TESTER(y)
67
73
NBL_GENERATE_MEMBER_TESTER (z)
68
74
NBL_GENERATE_MEMBER_TESTER (w)
69
75
76
+
77
+ // Even though it should work for some reason tests fail
78
+ // proof it works : https://godbolt.org/z/EzPWGnTPb
79
+
80
+ #define CAT (x, y) x##y
81
+ #define TYPE_DECLARE (n) typename Arg##n
82
+ #define TYPE_DECLARE_DEFAULT (n) TYPE_DECLARE (n)=void
83
+ #define TYPE_FWD (n) Arg##n
84
+ #define DECLVAL_DECLARE (n) impl::declval<Arg##n>()
85
+
86
+ #define FOR_EACH0 (fn)
87
+ #define FOR_EACH1 (fn) fn (1 )
88
+ #define FOR_EACH2 (fn) fn (2 ), FOR_EACH1 (fn)
89
+ #define FOR_EACH3 (fn) fn (3 ), FOR_EACH2 (fn)
90
+ #define FOR_EACH4 (fn) fn (4 ), FOR_EACH3 (fn)
91
+ #define FOR_EACH (fn, n) CAT (FOR_EACH, n)(fn)
92
+
93
+ #define GENERATE_STATIC_METHOD_TESTER_SPEC0 (x) \
94
+ template<class T> \
95
+ struct has_static_method_##x<T, typename make_void<decltype (T::x ())>::type> : true_type \
96
+ { \
97
+ using return_type = decltype (T::x ()); \
98
+ NBL_CONSTEXPR_STATIC_INLINE uint arg_count = 0 ; \
99
+ };
100
+
101
+ #define GENERATE_STATIC_METHOD_TESTER_SPEC (x, n) \
102
+ template<class T, FOR_EACH (TYPE_DECLARE, n)> \
103
+ struct has_static_method_##x<T, FOR_EACH (TYPE_FWD, n), typename make_void<decltype (T::x (FOR_EACH (DECLVAL_DECLARE, n)))>::type> : true_type \
104
+ { \
105
+ using return_type = decltype (T::x (FOR_EACH (DECLVAL_DECLARE, n))); \
106
+ NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
107
+ };
108
+
109
+ #define GENERATE_STATIC_METHOD_TESTER (x) \
110
+ template<typename T, FOR_EACH (TYPE_DECLARE_DEFAULT, 4 ), class =void > \
111
+ struct has_static_method_##x : false_type {}; \
112
+ GENERATE_STATIC_METHOD_TESTER_SPEC0 (x) \
113
+ GENERATE_STATIC_METHOD_TESTER_SPEC (x, 1 ) \
114
+ GENERATE_STATIC_METHOD_TESTER_SPEC (x, 2 ) \
115
+ GENERATE_STATIC_METHOD_TESTER_SPEC (x, 3 ) \
116
+ GENERATE_STATIC_METHOD_TESTER_SPEC (x, 4 )
117
+
118
+ #define GENERATE_METHOD_TESTER_SPEC0 (x) \
119
+ template<class T> \
120
+ struct has_method_##x<T, typename make_void<decltype (impl::declval<T>().x ())>::type> : impl::if_2_else_1<impl::has_static_method_##x<T>::value> \
121
+ { \
122
+ using return_type = decltype (impl::declval<T>().x ()); \
123
+ NBL_CONSTEXPR_STATIC_INLINE uint arg_count = 0 ; \
124
+ };
125
+
126
+ #define GENERATE_METHOD_TESTER_SPEC (x, n) \
127
+ template<class T, FOR_EACH (TYPE_DECLARE, n)> \
128
+ struct has_method_##x<T, FOR_EACH (TYPE_FWD, n), typename make_void<decltype (impl::declval<T>().x (FOR_EACH (DECLVAL_DECLARE, n)))>::type> : impl::if_2_else_1<impl::has_static_method_##x<T,FOR_EACH (TYPE_FWD, n)>::value> \
129
+ { \
130
+ using return_type = decltype (impl::declval<T>().x (FOR_EACH (DECLVAL_DECLARE, n))); \
131
+ NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
132
+ };
133
+
134
+ /*
135
+ types that are impilicitly convertible to each other mess this check up
136
+
137
+ struct S
138
+ {
139
+ void a(int) { return 0;}
140
+ };
141
+
142
+ has_method_a<S, float>::value will be true
143
+ since float is implicitly convertible to int and
144
+ due to how we check function signatures at the moment
145
+ */
146
+
147
+ #define GENERATE_METHOD_TESTER (x) \
148
+ namespace nbl { \
149
+ namespace hlsl { \
150
+ namespace impl { GENERATE_STATIC_METHOD_TESTER (x) } \
151
+ template<typename T, FOR_EACH (TYPE_DECLARE_DEFAULT, 4 ), class =void > \
152
+ struct has_method_##x : false_type {}; \
153
+ GENERATE_METHOD_TESTER_SPEC0 (x) \
154
+ GENERATE_METHOD_TESTER_SPEC (x, 1 ) \
155
+ GENERATE_METHOD_TESTER_SPEC (x, 2 ) \
156
+ GENERATE_METHOD_TESTER_SPEC (x, 3 ) \
157
+ GENERATE_METHOD_TESTER_SPEC (x, 4 ) \
158
+ }}
159
+
160
+
161
+ GENERATE_METHOD_TESTER (a)
162
+ GENERATE_METHOD_TESTER (b)
163
+
164
+
70
165
#endif
71
166
#endif
0 commit comments