55#define _NBL_BUILTIN_HLSL_MEMBER_TEST_MACROS_INCLUDED_
66
77#include <nbl/builtin/hlsl/type_traits.hlsl>
8+ #include <boost/preprocessor.hpp>
89
910#ifdef __HLSL_VERSION
1011
@@ -74,60 +75,31 @@ NBL_GENERATE_MEMBER_TESTER(z)
7475NBL_GENERATE_MEMBER_TESTER (w)
7576
7677
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)
7979
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))
8584
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 \
10488{ \
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))); \
10690 NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
10791};
10892
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 > \
11195struct 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)
12597
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> \
129101{ \
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))); \
131103 NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
132104};
133105
@@ -147,14 +119,10 @@ struct has_method_##x<T, FOR_EACH(TYPE_FWD, n), typename make_void<decltype(impl
147119#define GENERATE_METHOD_TESTER (x) \
148120namespace nbl { \
149121namespace 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 > \
152124struct 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) \
158126}}
159127
160128
0 commit comments