10
10
#include <nbl/builtin/hlsl/type_traits.hlsl>
11
11
12
12
13
- #ifndef __HLSL_VERSION
14
-
15
- // TODO: old stuff, see how much we can remove
16
- #define NBL_CONCEPT_TYPE_PARAMS (...) template <__VA_ARGS__>
17
- #define NBL_CONCEPT_SIGNATURE (NAME, ...) concept NAME = requires (__VA_ARGS__)
18
- #define NBL_CONCEPT_BODY (...) { __VA_ARGS__ };
19
- #define NBL_CONCEPT_ASSIGN (NAME, ...) concept NAME = __VA_ARGS__;
20
- #define NBL_REQUIRES (...) requires __VA_ARGS__
13
+ namespace nbl
14
+ {
15
+ namespace hlsl
16
+ {
17
+ namespace concepts
18
+ {
19
+ // common implementation juice
20
+ #include <boost/preprocessor/seq/elem.hpp>
21
+ #define NBL_IMPL_CONCEPT_FULL_TPLT (z, n, unused) BOOST_PP_SEQ_ELEM (n,NBL_CONCEPT_TPLT_PRM_KINDS) BOOST_PP_SEQ_ELEM (n,NBL_CONCEPT_TPLT_PRM_NAMES)
22
+ #include <boost/preprocessor/repetition/enum.hpp>
23
+ #define NBL_CONCEPT_FULL_TPLT () BOOST_PP_ENUM (BOOST_PP_SEQ_SIZE (NBL_CONCEPT_TPLT_PRM_NAMES),NBL_IMPL_CONCEPT_FULL_TPLT,DUMMY)
24
+ #include <boost/preprocessor/seq/enum.hpp>
25
+ #define NBL_CONCEPT_TPLT_PARAMS () BOOST_PP_SEQ_ENUM (NBL_CONCEPT_TPLT_PRM_NAMES)
26
+ #include <boost/preprocessor/tuple/elem.hpp>
27
+ #include <boost/preprocessor/control/expr_if.hpp>
28
+ #include <boost/preprocessor/seq/for_each_i.hpp>
29
+ //
30
+ #define NBL_CONCEPT_REQ_TYPE 0
31
+ #define NBL_CONCEPT_REQ_EXPR 1
32
+ //
33
+ #define NBL_CONCEPT_REQ_EXPR_RET_TYPE 2
34
+
35
+
36
+ //! Now diverge
37
+ #ifndef __cpp_concepts
21
38
22
39
23
40
// to define a concept using `concept Name = SomeContexprBoolCondition<T>;`
37
54
// condition, use instead of the closing `>` of a function template
38
55
#define NBL_FUNC_REQUIRES (...) > requires (__VA_ARGS__)
39
56
40
- #include <concepts>
41
57
42
- namespace nbl
43
- {
44
- namespace hlsl
45
- {
46
- namespace concepts
58
+ //
59
+ #define NBL_CONCEPT_PARAM_T (ID,...) ID
60
+ //
61
+ #define NBL_IMPL_IMPL_CONCEPT_BEGIN (A,...) __VA_ARGS__ A
62
+ #define NBL_IMPL_CONCEPT_BEGIN (z,n,data) NBL_IMPL_IMPL_CONCEPT_BEGIN NBL_CONCEPT_PARAM_##n
63
+ // TODO: are empty local parameter lists valid? a.k.a. just a `()`
64
+ #define NBL_CONCEPT_BEGIN (LOCAL_PARAM_COUNT) template<NBL_CONCEPT_FULL_TPLT ()> \
65
+ concept NBL_CONCEPT_NAME = requires BOOST_PP_EXPR_IF (LOCAL_PARAM_COUNT,(BOOST_PP_ENUM (LOCAL_PARAM_COUNT,NBL_IMPL_CONCEPT_BEGIN,DUMMY))) \
47
66
{
67
+ //
68
+ #define NBL_IMPL_CONCEPT_REQ_TYPE (...) typename __VA_ARGS__;
69
+ #define NBL_IMPL_CONCEPT_REQ_EXPR (...) __VA_ARGS__;
70
+ #define NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE (E,C,...) {E}; C<decltype E,__VA_ARGS__ >;
71
+ //
72
+ #define NBL_IMPL_CONCEPT (NBL_IMPL_CONCEPT_REQ_TYPE,NBL_IMPL_CONCEPT_REQ_EXPR,NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE)
73
+ //
74
+ #define NBL_IMPL_CONCEPT_END_DEF (r,unused,i,e) NBL_EVAL (BOOST_PP_TUPLE_ELEM (BOOST_PP_SEQ_HEAD (e),NBL_IMPL_CONCEPT) BOOST_PP_SEQ_TAIL (e))
75
+ //
76
+ #define NBL_CONCEPT_END (SEQ) BOOST_PP_SEQ_FOR_EACH_I (NBL_IMPL_CONCEPT_END_DEF, DUMMY, SEQ) \
77
+ }
78
+
79
+
80
+ #include <concepts>
48
81
49
82
// Alias some of the std concepts in nbl. As this is C++20 only, we don't need to use
50
83
// the macros here.
@@ -90,22 +123,11 @@ concept vectorial = is_vector<T>::value;
90
123
template <typename T>
91
124
concept matricial = is_matrix<T>::value;
92
125
93
- }
94
- }
95
- }
96
-
97
126
#else
98
127
99
- // TODO: old stuff, see how much we can remove
100
- // No C++20 support. Do nothing.
101
- #define NBL_CONCEPT_TYPE_PARAMS (...)
102
- #define NBL_CONCEPT_SIGNATURE (NAME, ...)
103
- #define NBL_CONCEPT_BODY (...)
104
- #define NBL_REQUIRES (...)
105
-
106
128
107
129
// to define a concept using `concept Name = SomeContexprBoolCondition<T>;`
108
- #define NBL_BOOL_CONCEPT NBL_CONSTEXPR_STATIC_INLINE bool
130
+ #define NBL_BOOL_CONCEPT NBL_CONSTEXPR bool
109
131
110
132
// for struct definitions, use instead of closing `>` on the primary template parameter list
111
133
#define NBL_PRIMARY_REQUIRES (...) ,typename __requires=::nbl::hlsl::enable_if_t<(__VA_ARGS__),void > >
@@ -121,7 +143,39 @@ concept matricial = is_matrix<T>::value;
121
143
// condition, use instead of the closing `>` of a function template
122
144
#define NBL_FUNC_REQUIRES (...) ,std::enable_if_t<(__VA_ARGS__),bool > = true >
123
145
124
- #endif
125
146
147
+ //
148
+ #define NBL_CONCEPT_BEGIN (LOCAL_PARAM_COUNT) namespace BOOST_PP_CAT (__concept__,NBL_CONCEPT_NAME) \
149
+ {
150
+ //
151
+ #define NBL_CONCEPT_PARAM_T (ID,...) ::nbl::hlsl::impl::declval<__VA_ARGS__ >()
152
+ //
153
+ #define NBL_IMPL_CONCEPT_REQ_TYPE (...) ::nbl::hlsl::make_void_t<typename __VA_ARGS__ >
154
+ #define NBL_IMPL_CONCEPT_REQ_EXPR (...) ::nbl::hlsl::make_void_t<decltype (__VA_ARGS__)>
155
+ #define NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE (E,C,...) C<decltype E ,__VA_ARGS__ >
156
+ //
157
+ #define NBL_IMPL_CONCEPT_SFINAE (typename=void ,typename=void ,bool =true )
158
+ #define NBL_IMPL_CONCEPT_SFINAE_SPEC (NBL_IMPL_CONCEPT_REQ_TYPE,NBL_IMPL_CONCEPT_REQ_EXPR,NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE)
159
+ //
160
+ #define NBL_IMPL_CONCEPT_END_DEF (r,unused,i,e) template<NBL_CONCEPT_FULL_TPLT (), BOOST_PP_TUPLE_ELEM (BOOST_PP_SEQ_HEAD (e),NBL_IMPL_CONCEPT_SFINAE)> \
161
+ struct BOOST_PP_CAT (__requirement,i) : ::nbl::hlsl::false_type {}; \
162
+ template<NBL_CONCEPT_FULL_TPLT ()> \
163
+ struct BOOST_PP_CAT (__requirement,i)<NBL_CONCEPT_TPLT_PARAMS (), \
164
+ NBL_EVAL (BOOST_PP_TUPLE_ELEM (BOOST_PP_SEQ_HEAD (e),NBL_IMPL_CONCEPT_SFINAE_SPEC) BOOST_PP_SEQ_TAIL (e)) \
165
+ > : ::nbl::hlsl::true_type {};
166
+ //
167
+ #define NBL_IMPL_CONCEPT_END_GET (r,unused,i,e) BOOST_PP_EXPR_IF (i,&&) BOOST_PP_CAT (__concept__,NBL_CONCEPT_NAME)::BOOST_PP_CAT (__requirement,i)<NBL_CONCEPT_TPLT_PARAMS ()>::value
168
+ //
169
+ #define NBL_CONCEPT_END (SEQ) BOOST_PP_SEQ_FOR_EACH_I (NBL_IMPL_CONCEPT_END_DEF, DUMMY, SEQ) \
170
+ } \
171
+ template<NBL_CONCEPT_FULL_TPLT ()> \
172
+ NBL_CONSTEXPR bool NBL_CONCEPT_NAME = BOOST_PP_SEQ_FOR_EACH_I (NBL_IMPL_CONCEPT_END_GET, DUMMY, SEQ)
173
+
174
+ // TODO: counterparts of all the other concepts
175
+
176
+ #endif
177
+ }
178
+ }
179
+ }
126
180
127
181
#endif
0 commit comments