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
@@ -16,19 +17,11 @@ namespace hlsl
16
17
namespace impl
17
18
{
18
19
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
-
26
20
enum e_member_presence
27
21
{
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 ,
32
25
};
33
26
34
27
template<class T>
@@ -54,16 +47,17 @@ namespace hlsl \
54
47
{ \
55
48
namespace impl { \
56
49
template<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 { }; \
58
51
template<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 { }; \
60
53
template<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 ; }; \
62
55
template<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); }; \
64
57
} \
65
58
template<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> {}; \
67
61
} \
68
62
}
69
63
@@ -74,60 +68,30 @@ NBL_GENERATE_MEMBER_TESTER(z)
74
68
NBL_GENERATE_MEMBER_TESTER (w)
75
69
76
70
77
- // Even though it should work for some reason tests fail
78
- // proof it works : https://godbolt.org/z/EzPWGnTPb
79
71
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))
100
76
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 \
104
80
{ \
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))); \
106
82
NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
107
83
};
108
84
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 > \
111
87
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
- };
88
+ BOOST_PP_REPEAT (n, GENERATE_STATIC_METHOD_TESTER_SPEC, x)
125
89
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> \
129
93
{ \
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))); \
131
95
NBL_CONSTEXPR_STATIC_INLINE uint arg_count = n; \
132
96
};
133
97
@@ -147,14 +111,10 @@ struct has_method_##x<T, FOR_EACH(TYPE_FWD, n), typename make_void<decltype(impl
147
111
#define GENERATE_METHOD_TESTER (x) \
148
112
namespace nbl { \
149
113
namespace 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 > \
152
116
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 ) \
117
+ BOOST_PP_REPEAT (4 , GENERATE_METHOD_TESTER_SPEC, x) \
158
118
}}
159
119
160
120
0 commit comments