5
5
#define _NBL_BUILTIN_HLSL_MEMBER_TEST_MACROS_INCLUDED_
6
6
7
7
#include <nbl/builtin/hlsl/type_traits.hlsl>
8
+ #include <boost/preprocessor.hpp>
8
9
9
10
#ifdef __HLSL_VERSION
10
11
@@ -74,60 +75,31 @@ NBL_GENERATE_MEMBER_TESTER(z)
74
75
NBL_GENERATE_MEMBER_TESTER (w)
75
76
76
77
77
- // Even though it should work for some reason tests fail
78
- // proof it works : https://godbolt.org/z/EzPWGnTPb
78
+ #define NBL_REPEAT (fn, n) BOOST_PP_REPEAT (n, fn, n)
79
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>()
80
+ #define NBL_TYPE_DECLARE (z, n, x) BOOST_PP_COMMA_IF (x) typename Arg##n
81
+ #define NBL_TYPE_DECLARE_DEFAULT (z, n, x) BOOST_PP_COMMA_IF (x) typename Arg##n=void
82
+ #define NBL_TYPE_FWD (z, n, x) BOOST_PP_COMMA_IF (x) Arg##n
83
+ #define NBL_DECLVAL_DECLARE (z, n, x) impl::declval<Arg##n>() BOOST_PP_COMMA_IF (BOOST_PP_NOT_EQUAL (BOOST_PP_INC (n), x))
85
84
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 \
85
+ #define GENERATE_STATIC_METHOD_TESTER_SPEC (z, n, x) \
86
+ template<class T NBL_REPEAT (NBL_TYPE_DECLARE, n)> \
87
+ struct has_static_method_##x<T NBL_REPEAT (NBL_TYPE_FWD, n), typename make_void<decltype (T::x (NBL_REPEAT (NBL_DECLVAL_DECLARE, n)))>::type> : true_type \
104
88
{ \
105
- using return_type = decltype (T::x (FOR_EACH (DECLVAL_DECLARE , n))); \
89
+ using return_type = decltype (T::x (NBL_REPEAT (NBL_DECLVAL_DECLARE , n))); \
106
90
NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
107
91
};
108
92
109
- #define GENERATE_STATIC_METHOD_TESTER (x) \
110
- template<typename T, FOR_EACH (TYPE_DECLARE_DEFAULT, 4 ), class =void > \
93
+ #define GENERATE_STATIC_METHOD_TESTER (x, n ) \
94
+ template<typename T NBL_REPEAT (NBL_TYPE_DECLARE_DEFAULT, n ), class =void > \
111
95
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
- };
96
+ BOOST_PP_REPEAT (n, GENERATE_STATIC_METHOD_TESTER_SPEC, x)
125
97
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> \
98
+ #define GENERATE_METHOD_TESTER_SPEC (z , n, x ) \
99
+ template<class T NBL_REPEAT (NBL_TYPE_DECLARE , n)> \
100
+ struct has_method_##x<T NBL_REPEAT (NBL_TYPE_FWD , n), typename make_void<decltype (impl::declval<T>().x (NBL_REPEAT (NBL_DECLVAL_DECLARE , n)))>::type> : impl::if_2_else_1<impl::has_static_method_##x<T NBL_REPEAT (NBL_TYPE_FWD , n)>::value> \
129
101
{ \
130
- using return_type = decltype (impl::declval<T>().x (FOR_EACH (DECLVAL_DECLARE , n))); \
102
+ using return_type = decltype (impl::declval<T>().x (NBL_REPEAT (NBL_DECLVAL_DECLARE , n))); \
131
103
NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
132
104
};
133
105
@@ -147,14 +119,10 @@ struct has_method_##x<T, FOR_EACH(TYPE_FWD, n), typename make_void<decltype(impl
147
119
#define GENERATE_METHOD_TESTER (x) \
148
120
namespace nbl { \
149
121
namespace hlsl { \
150
- namespace impl { GENERATE_STATIC_METHOD_TESTER (x) } \
151
- template<typename T, FOR_EACH (TYPE_DECLARE_DEFAULT , 4 ), class =void > \
122
+ namespace impl { GENERATE_STATIC_METHOD_TESTER (x, 4 ) } \
123
+ template<typename T NBL_REPEAT (NBL_TYPE_DECLARE_DEFAULT , 4 ), class =void > \
152
124
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 ) \
125
+ BOOST_PP_REPEAT (4 , GENERATE_METHOD_TESTER_SPEC, x) \
158
126
}}
159
127
160
128
0 commit comments