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
@@ -16,19 +17,11 @@ namespace hlsl
1617namespace impl
1718{
1819
19- template<class T, bool C>
20- struct is_const_helper : bool_constant<C>
21- {
22- using type = T;
23- NBL_CONSTEXPR_STATIC_INLINE bool is_constant = is_const<T>::value;
24- };
25-
2620enum e_member_presence
2721{
28- absent = 0 ,
29- non_static = 1 ,
30- as_static = 2 ,
31- static_constexpr = 3 ,
22+ is_present = 1 <<0 ,
23+ is_static = 1 <<1 ,
24+ is_const = 1 <<2 ,
3225};
3326
3427template<class T>
@@ -54,16 +47,17 @@ namespace hlsl \
5447{ \
5548namespace impl { \
5649template<class T, class =void > \
57- struct is_static_member_##a: false_type {NBL_CONSTEXPR_STATIC_INLINE bool is_constant = false ; }; \
50+ struct is_static_member_##a: false_type { }; \
5851template<class T> \
59- struct is_static_member_##a<T,typename enable_if<!is_same<decltype (T::a),void >::value,void >::type>: is_const_helper< decltype (T::a), true > { }; \
52+ struct is_static_member_##a<T,typename enable_if<!is_same<decltype (T::a),void >::value,void >::type> : true_type { }; \
6053template<class T, class =void > \
61- struct is_member_##a: false_type {NBL_CONSTEXPR_STATIC_INLINE bool is_constant = false ; }; \
54+ struct is_member_##a: false_type { using type = void ; }; \
6255template<class T> \
63- struct is_member_##a<T,typename enable_if<!is_same<decltype (declval<T>().a),void >::value,void >::type> : is_const_helper< decltype (declval<T>().a), true >{ }; \
56+ struct is_member_##a<T,typename enable_if<!is_same<decltype (declval<T>().a),void >::value,void >::type> : true_type { using type = decltype (declval<T>().a); }; \
6457} \
6558template<class T> \
66- struct has_member_##a { NBL_CONSTEXPR_STATIC_INLINE e_member_presence value = (e_member_presence)(impl::is_member_##a<T>::value + impl::is_static_member_##a<T>::value + impl::is_static_member_##a<T>::is_constant); }; \
59+ struct has_member_##a { NBL_CONSTEXPR_STATIC_INLINE e_member_presence value = (e_member_presence)(impl::is_member_##a<T>::value + 2 *impl::is_static_member_##a<T>::value + 4 *is_const<typename impl::is_member_##a<T>::type>::value); }; \
60+ template<class T, class F> struct has_member_##a##_with_type : bool_constant<has_member_##a<T>::value && is_same<typename impl::is_member_##a<T>::type, F>::value> {}; \
6761} \
6862}
6963
@@ -74,60 +68,30 @@ NBL_GENERATE_MEMBER_TESTER(z)
7468NBL_GENERATE_MEMBER_TESTER (w)
7569
7670
77- // Even though it should work for some reason tests fail
78- // proof it works : https://godbolt.org/z/EzPWGnTPb
7971
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- };
72+ #define NBL_TYPE_DECLARE (z, n, x) BOOST_PP_COMMA_IF (x) typename Arg##n
73+ #define NBL_TYPE_DECLARE_DEFAULT (z, n, x) BOOST_PP_COMMA_IF (x) typename Arg##n=void
74+ #define NBL_TYPE_FWD (z, n, x) BOOST_PP_COMMA_IF (x) Arg##n
75+ #define NBL_DECLVAL_DECLARE (z, n, x) impl::declval<Arg##n>() BOOST_PP_COMMA_IF (BOOST_PP_NOT_EQUAL (BOOST_PP_INC (n), x))
10076
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 \
77+ #define GENERATE_STATIC_METHOD_TESTER_SPEC (z , n, x ) \
78+ template<class T BOOST_PP_REPEAT (n, NBL_TYPE_DECLARE , n)> \
79+ struct has_static_method_##x<T BOOST_PP_REPEAT (n, NBL_TYPE_FWD, n), typename make_void<decltype (T::x (BOOST_PP_REPEAT (n, NBL_DECLVAL_DECLARE , n)))>::type> : true_type \
10480{ \
105- using return_type = decltype (T::x (FOR_EACH (DECLVAL_DECLARE , n))); \
81+ using return_type = decltype (T::x (BOOST_PP_REPEAT (n, NBL_DECLVAL_DECLARE , n))); \
10682 NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
10783};
10884
109- #define GENERATE_STATIC_METHOD_TESTER (x) \
110- template<typename T, FOR_EACH (TYPE_DECLARE_DEFAULT, 4 ), class =void > \
85+ #define GENERATE_STATIC_METHOD_TESTER (x, n ) \
86+ template<typename T BOOST_PP_REPEAT (n, NBL_TYPE_DECLARE_DEFAULT, n ), class =void > \
11187struct 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- };
88+ BOOST_PP_REPEAT (n, GENERATE_STATIC_METHOD_TESTER_SPEC, x)
12589
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> \
90+ #define GENERATE_METHOD_TESTER_SPEC (z , n, x ) \
91+ template<class T BOOST_PP_REPEAT (n, NBL_TYPE_DECLARE , n)> \
92+ struct has_method_##x<T BOOST_PP_REPEAT (n, NBL_TYPE_FWD, n), typename make_void<decltype (impl::declval<T>().x (BOOST_PP_REPEAT (n, NBL_DECLVAL_DECLARE, n)))>::type> : impl::if_2_else_1<impl::has_static_method_##x<T BOOST_PP_REPEAT (n, NBL_TYPE_FWD , n)>::value> \
12993{ \
130- using return_type = decltype (impl::declval<T>().x (FOR_EACH (DECLVAL_DECLARE , n))); \
94+ using return_type = decltype (impl::declval<T>().x (BOOST_PP_REPEAT (n, NBL_DECLVAL_DECLARE , n))); \
13195 NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
13296};
13397
@@ -147,14 +111,10 @@ struct has_method_##x<T, FOR_EACH(TYPE_FWD, n), typename make_void<decltype(impl
147111#define GENERATE_METHOD_TESTER (x) \
148112namespace nbl { \
149113namespace hlsl { \
150- namespace impl { GENERATE_STATIC_METHOD_TESTER (x) } \
151- template<typename T, FOR_EACH (TYPE_DECLARE_DEFAULT , 4 ), class =void > \
114+ namespace impl { GENERATE_STATIC_METHOD_TESTER (x, 4 ) } \
115+ template<typename T BOOST_PP_REPEAT ( 4 , NBL_TYPE_DECLARE_DEFAULT , 4 ), class =void > \
152116struct 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 ) \
117+ BOOST_PP_REPEAT (4 , GENERATE_METHOD_TESTER_SPEC, x) \
158118}}
159119
160120
0 commit comments