1010#include <nbl/builtin/hlsl/type_traits.hlsl>
1111
1212
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
2138
2239
2340// to define a concept using `concept Name = SomeContexprBoolCondition<T>;`
3754// condition, use instead of the closing `>` of a function template
3855#define NBL_FUNC_REQUIRES (...) > requires (__VA_ARGS__)
3956
40- #include <concepts>
4157
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))) \
4766{
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>
4881
4982// Alias some of the std concepts in nbl. As this is C++20 only, we don't need to use
5083// the macros here.
@@ -90,22 +123,11 @@ concept vectorial = is_vector<T>::value;
90123template <typename T>
91124concept matricial = is_matrix<T>::value;
92125
93- }
94- }
95- }
96-
97126#else
98127
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-
106128
107129// 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
109131
110132// for struct definitions, use instead of closing `>` on the primary template parameter list
111133#define NBL_PRIMARY_REQUIRES (...) ,typename __requires=::nbl::hlsl::enable_if_t<(__VA_ARGS__),void > >
@@ -121,7 +143,39 @@ concept matricial = is_matrix<T>::value;
121143// condition, use instead of the closing `>` of a function template
122144#define NBL_FUNC_REQUIRES (...) ,std::enable_if_t<(__VA_ARGS__),bool > = true >
123145
124- #endif
125146
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+ }
126180
127181#endif
0 commit comments