Commit a05ea8e6 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot

simplify concept_def.h

fbshipit-source-id: ecedf66e7d6e1ea6bcbe1ba68091f6ffdf62c260
parent 048bb99f
...@@ -21,7 +21,7 @@ target_include_directories(pushmi INTERFACE ...@@ -21,7 +21,7 @@ target_include_directories(pushmi INTERFACE
target_compile_features(pushmi INTERFACE cxx_std_14) target_compile_features(pushmi INTERFACE cxx_std_14)
target_compile_options(pushmi INTERFACE target_compile_options(pushmi INTERFACE
#$<$<CXX_COMPILER_ID:GNU>:-std=c++2a> #$<$<CXX_COMPILER_ID:GNU>:-std=c++2a>
#$<$<CXX_COMPILER_ID:GNU>:-fconcepts> $<$<CXX_COMPILER_ID:GNU>:-fconcepts>
$<$<CXX_COMPILER_ID:GNU>:-ftemplate-backtrace-limit=0>) $<$<CXX_COMPILER_ID:GNU>:-ftemplate-backtrace-limit=0>)
add_custom_target(buildSingleHeader COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/buildSingleHeader.cmake WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) add_custom_target(buildSingleHeader COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/buildSingleHeader.cmake WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
......
...@@ -235,8 +235,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -235,8 +235,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_EVAL(X, ...) X(__VA_ARGS__) #define PUSHMI_PP_EVAL(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EVAL2(X, ...) X(__VA_ARGS__) #define PUSHMI_PP_EVAL2(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EVAL3(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EVAL4(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EXPAND(...) __VA_ARGS__ #define PUSHMI_PP_EXPAND(...) __VA_ARGS__
#define PUSHMI_PP_EAT(...) #define PUSHMI_PP_EAT(...)
...@@ -259,74 +257,9 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -259,74 +257,9 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
N \ N \
/**/ /**/
#define PUSHMI_PP_IS_EQUAL(X,Y) \
PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_IS_EQUAL_, X), Y))
#define PUSHMI_PP_IS_EQUAL_00 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_11 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_22 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_33 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_44 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_55 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_66 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_77 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_88 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_99 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1010 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1111 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1212 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1313 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1414 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1515 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1616 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_NOT(X) PUSHMI_PP_CAT(PUSHMI_PP_NOT_, X)
#define PUSHMI_PP_NOT_0 1
#define PUSHMI_PP_NOT_1 0
#define PUSHMI_PP_IIF(BIT) PUSHMI_PP_CAT_(PUSHMI_PP_IIF_, BIT) #define PUSHMI_PP_IIF(BIT) PUSHMI_PP_CAT_(PUSHMI_PP_IIF_, BIT)
#define PUSHMI_PP_IIF_0(TRUE, ...) __VA_ARGS__ #define PUSHMI_PP_IIF_0(TRUE, ...) __VA_ARGS__
#define PUSHMI_PP_IIF_1(TRUE, ...) TRUE #define PUSHMI_PP_IIF_1(TRUE, ...) TRUE
#define PUSHMI_PP_FIRST(X, ...) X
#define PUSHMI_PP_SECOND(X, ...) __VA_ARGS__
#define PUSHMI_PP_OR(X,Y) \
PUSHMI_PP_NOT(PUSHMI_PP_CHECK(PUSHMI_PP_CAT( \
PUSHMI_PP_CAT(PUSHMI_PP_NOR_, X), Y)))
#define PUSHMI_PP_NOR_00 PUSHMI_PP_PROBE(~)
#if PUSHMI_CXX_VA_OPT
#define PUSHMI_PP_IS_EMPTY_NON_FUNCTION(...) \
PUSHMI_PP_CHECK(__VA_OPT__(, 0), 1)
#else // RANGES_VA_OPT
#define PUSHMI_PP_SPLIT(i, ...) \
PUSHMI_PP_CAT_(PUSHMI_PP_SPLIT_, i)(__VA_ARGS__) \
/**/
#define PUSHMI_PP_SPLIT_0(a, ...) a
#define PUSHMI_PP_SPLIT_1(a, ...) __VA_ARGS__
#define PUSHMI_PP_IS_VARIADIC(...) \
PUSHMI_PP_SPLIT( \
0, \
PUSHMI_PP_CAT( \
PUSHMI_PP_IS_VARIADIC_R_, \
PUSHMI_PP_IS_VARIADIC_C __VA_ARGS__)) \
/**/
#define PUSHMI_PP_IS_VARIADIC_C(...) 1
#define PUSHMI_PP_IS_VARIADIC_R_1 1,
#define PUSHMI_PP_IS_VARIADIC_R_PUSHMI_PP_IS_VARIADIC_C 0,
// emptiness detection macro...
#define PUSHMI_PP_IS_EMPTY_NON_FUNCTION(...) \
PUSHMI_PP_IIF(PUSHMI_PP_IS_VARIADIC(__VA_ARGS__)) \
(0, PUSHMI_PP_IS_VARIADIC(PUSHMI_PP_IS_EMPTY_NON_FUNCTION_C __VA_ARGS__()))\
/**/
#define PUSHMI_PP_IS_EMPTY_NON_FUNCTION_C() ()
#endif // PUSHMI_PP_VA_OPT
#define PUSHMI_PP_EMPTY() #define PUSHMI_PP_EMPTY()
#define PUSHMI_PP_COMMA() , #define PUSHMI_PP_COMMA() ,
...@@ -358,7 +291,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -358,7 +291,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
__VA_ARGS__) \ __VA_ARGS__) \
/**/ /**/
#define PUSHMI_PP_DECL_DEF_NAME(...) \ #define PUSHMI_PP_DECL_DEF_NAME(...) \
__VA_ARGS__, \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, __VA_ARGS__), \
/**/ /**/
#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...) \ #define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...) \
PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \ PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \
...@@ -371,7 +304,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -371,7 +304,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// (concept Name)(A, B, Rest...), // (concept Name)(A, B, Rest...),
// // requirements... // // requirements...
#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, ...) \ #define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, ...) \
PUSHMI_PP_EVAL4( \ PUSHMI_PP_EVAL2( \
PUSHMI_PP_DECL_DEF_IMPL, \ PUSHMI_PP_DECL_DEF_IMPL, \
TPARAM, \ TPARAM, \
PUSHMI_PP_DECL_DEF_NAME NAME, \ PUSHMI_PP_DECL_DEF_NAME NAME, \
...@@ -385,18 +318,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -385,18 +318,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, ...) \ #define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, ...) \
PUSHMI_PP_DECL_DEF_IMPL( \ PUSHMI_PP_DECL_DEF_IMPL( \
TPARAM, \ TPARAM, \
NAME, \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), \
(PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \ (PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \
__VA_ARGS__) \ __VA_ARGS__) \
/**/ /**/
// Expand the template definition into a struct and template alias like: // Expand the template definition into a struct and template alias like:
// struct NameConcept { // struct NameConcept {
// template<class A, class B> // template<class A, class B>
// static auto _concept_requires_(/* args (optional)*/) -> // static auto Requires_(/* args (optional)*/) ->
// decltype(/*requirements...*/); // decltype(/*requirements...*/);
// template<class A, class B> // template<class A, class B>
// static constexpr auto is_satisfied_by(int) -> // static constexpr auto is_satisfied_by(int) ->
// decltype(bool(&_concept_requires_<A,B>)) { return true; } // decltype(bool(&Requires_<A,B>)) { return true; }
// template<class A, class B> // template<class A, class B>
// static constexpr bool is_satisfied_by(long) { return false; } // static constexpr bool is_satisfied_by(long) { return false; }
// }; // };
...@@ -421,21 +354,17 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -421,21 +354,17 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
{ __VA_ARGS__; } \ { __VA_ARGS__; } \
/**/ /**/
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \ #define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
inline namespace pushmi_concept_eager { \ inline namespace _eager_ { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
concept bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = PUSHMI_PP_EVAL2( \ concept bool NAME = PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__); \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
__VA_ARGS__); \
} \ } \
namespace defer = pushmi_concept_eager; \ namespace defer = _eager_; \
namespace lazy { \ namespace lazy { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \ struct PUSHMI_PP_CAT(NAME, Concept) { \
using Concept = \ using Concept = PUSHMI_PP_CAT(NAME, Concept); \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept); \
explicit constexpr operator bool() const noexcept { \ explicit constexpr operator bool() const noexcept { \
return (bool) defer::PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME)< \ return (bool) defer::NAME<PUSHMI_PP_EXPAND ARGS>; \
PUSHMI_PP_EXPAND ARGS>; \
} \ } \
constexpr auto operator!() const noexcept { \ constexpr auto operator!() const noexcept { \
return ::pushmi::concepts::detail::Not<Concept>{}; \ return ::pushmi::concepts::detail::Not<Concept>{}; \
...@@ -446,9 +375,8 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -446,9 +375,8 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
} \ } \
}; \ }; \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \ PUSHMI_INLINE_VAR constexpr auto NAME = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \ PUSHMI_PP_CAT(NAME, Concept)<PUSHMI_PP_EXPAND ARGS>{}; \
<PUSHMI_PP_EXPAND ARGS>{}; \
} \ } \
/**/ /**/
#else #else
...@@ -471,44 +399,38 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -471,44 +399,38 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
<decltype(__VA_ARGS__, void())>() \ <decltype(__VA_ARGS__, void())>() \
/**/ /**/
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \ #define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \ struct PUSHMI_PP_CAT(NAME, Concept) { \
using Concept = \ using Concept = PUSHMI_PP_CAT(NAME, Concept); \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept); \
PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN \ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
static auto _concept_requires_ PUSHMI_PP_EVAL2( \ static auto Requires_ PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__); \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
__VA_ARGS__); \
PUSHMI_PP_IGNORE_CXX2A_COMPAT_END \ PUSHMI_PP_IGNORE_CXX2A_COMPAT_END \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
struct _is_satisfied_by_ { \ struct Eval { \
template <class C_ = Concept> \ template <class C_ = Concept> \
static constexpr decltype( \ static constexpr decltype( \
!&C_::template _concept_requires_<PUSHMI_PP_EXPAND ARGS>) \ !&C_::template Requires_<PUSHMI_PP_EXPAND ARGS>) \
impl(int) noexcept { return true; } \ impl(int) noexcept { return true; } \
static constexpr bool impl(long) noexcept { return false; } \ static constexpr bool impl(long) noexcept { return false; } \
explicit constexpr operator bool() const noexcept { \ explicit constexpr operator bool() const noexcept { \
return _is_satisfied_by_::impl(0); \ return Eval::impl(0); \
} \ } \
constexpr auto operator!() const noexcept { \ constexpr auto operator!() const noexcept { \
return ::pushmi::concepts::detail::Not<_is_satisfied_by_>{}; \ return ::pushmi::concepts::detail::Not<Eval>{}; \
} \ } \
template <class That> \ template <class That> \
constexpr auto operator&&(That) const noexcept { \ constexpr auto operator&&(That) const noexcept { \
return ::pushmi::concepts::detail::And< \ return ::pushmi::concepts::detail::And<Eval, That>{}; \
_is_satisfied_by_, That>{}; \
} \ } \
}; \ }; \
}; \ }; \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \ PUSHMI_INLINE_VAR constexpr bool NAME = \
(bool)PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \ (bool)PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{}; \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
namespace lazy { \ namespace lazy { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \ PUSHMI_INLINE_VAR constexpr auto NAME = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \ PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{}; \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
} \ } \
namespace defer = lazy; \ namespace defer = lazy; \
/**/ /**/
......
...@@ -71,8 +71,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -71,8 +71,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_EVAL(X, ...) X(__VA_ARGS__) #define PUSHMI_PP_EVAL(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EVAL2(X, ...) X(__VA_ARGS__) #define PUSHMI_PP_EVAL2(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EVAL3(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EVAL4(X, ...) X(__VA_ARGS__)
#define PUSHMI_PP_EXPAND(...) __VA_ARGS__ #define PUSHMI_PP_EXPAND(...) __VA_ARGS__
#define PUSHMI_PP_EAT(...) #define PUSHMI_PP_EAT(...)
...@@ -95,74 +93,9 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -95,74 +93,9 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
N \ N \
/**/ /**/
#define PUSHMI_PP_IS_EQUAL(X,Y) \
PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_IS_EQUAL_, X), Y))
#define PUSHMI_PP_IS_EQUAL_00 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_11 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_22 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_33 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_44 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_55 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_66 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_77 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_88 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_99 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1010 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1111 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1212 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1313 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1414 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1515 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_IS_EQUAL_1616 PUSHMI_PP_PROBE(~)
#define PUSHMI_PP_NOT(X) PUSHMI_PP_CAT(PUSHMI_PP_NOT_, X)
#define PUSHMI_PP_NOT_0 1
#define PUSHMI_PP_NOT_1 0
#define PUSHMI_PP_IIF(BIT) PUSHMI_PP_CAT_(PUSHMI_PP_IIF_, BIT) #define PUSHMI_PP_IIF(BIT) PUSHMI_PP_CAT_(PUSHMI_PP_IIF_, BIT)
#define PUSHMI_PP_IIF_0(TRUE, ...) __VA_ARGS__ #define PUSHMI_PP_IIF_0(TRUE, ...) __VA_ARGS__
#define PUSHMI_PP_IIF_1(TRUE, ...) TRUE #define PUSHMI_PP_IIF_1(TRUE, ...) TRUE
#define PUSHMI_PP_FIRST(X, ...) X
#define PUSHMI_PP_SECOND(X, ...) __VA_ARGS__
#define PUSHMI_PP_OR(X,Y) \
PUSHMI_PP_NOT(PUSHMI_PP_CHECK(PUSHMI_PP_CAT( \
PUSHMI_PP_CAT(PUSHMI_PP_NOR_, X), Y)))
#define PUSHMI_PP_NOR_00 PUSHMI_PP_PROBE(~)
#if PUSHMI_CXX_VA_OPT
#define PUSHMI_PP_IS_EMPTY_NON_FUNCTION(...) \
PUSHMI_PP_CHECK(__VA_OPT__(, 0), 1)
#else // RANGES_VA_OPT
#define PUSHMI_PP_SPLIT(i, ...) \
PUSHMI_PP_CAT_(PUSHMI_PP_SPLIT_, i)(__VA_ARGS__) \
/**/
#define PUSHMI_PP_SPLIT_0(a, ...) a
#define PUSHMI_PP_SPLIT_1(a, ...) __VA_ARGS__
#define PUSHMI_PP_IS_VARIADIC(...) \
PUSHMI_PP_SPLIT( \
0, \
PUSHMI_PP_CAT( \
PUSHMI_PP_IS_VARIADIC_R_, \
PUSHMI_PP_IS_VARIADIC_C __VA_ARGS__)) \
/**/
#define PUSHMI_PP_IS_VARIADIC_C(...) 1
#define PUSHMI_PP_IS_VARIADIC_R_1 1,
#define PUSHMI_PP_IS_VARIADIC_R_PUSHMI_PP_IS_VARIADIC_C 0,
// emptiness detection macro...
#define PUSHMI_PP_IS_EMPTY_NON_FUNCTION(...) \
PUSHMI_PP_IIF(PUSHMI_PP_IS_VARIADIC(__VA_ARGS__)) \
(0, PUSHMI_PP_IS_VARIADIC(PUSHMI_PP_IS_EMPTY_NON_FUNCTION_C __VA_ARGS__()))\
/**/
#define PUSHMI_PP_IS_EMPTY_NON_FUNCTION_C() ()
#endif // PUSHMI_PP_VA_OPT
#define PUSHMI_PP_EMPTY() #define PUSHMI_PP_EMPTY()
#define PUSHMI_PP_COMMA() , #define PUSHMI_PP_COMMA() ,
...@@ -194,7 +127,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -194,7 +127,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
__VA_ARGS__) \ __VA_ARGS__) \
/**/ /**/
#define PUSHMI_PP_DECL_DEF_NAME(...) \ #define PUSHMI_PP_DECL_DEF_NAME(...) \
__VA_ARGS__, \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, __VA_ARGS__), \
/**/ /**/
#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...) \ #define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...) \
PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \ PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \
...@@ -207,7 +140,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -207,7 +140,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// (concept Name)(A, B, Rest...), // (concept Name)(A, B, Rest...),
// // requirements... // // requirements...
#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, ...) \ #define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME, ...) \
PUSHMI_PP_EVAL4( \ PUSHMI_PP_EVAL2( \
PUSHMI_PP_DECL_DEF_IMPL, \ PUSHMI_PP_DECL_DEF_IMPL, \
TPARAM, \ TPARAM, \
PUSHMI_PP_DECL_DEF_NAME NAME, \ PUSHMI_PP_DECL_DEF_NAME NAME, \
...@@ -221,18 +154,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -221,18 +154,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, ...) \ #define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME, ...) \
PUSHMI_PP_DECL_DEF_IMPL( \ PUSHMI_PP_DECL_DEF_IMPL( \
TPARAM, \ TPARAM, \
NAME, \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), \
(PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \ (PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \
__VA_ARGS__) \ __VA_ARGS__) \
/**/ /**/
// Expand the template definition into a struct and template alias like: // Expand the template definition into a struct and template alias like:
// struct NameConcept { // struct NameConcept {
// template<class A, class B> // template<class A, class B>
// static auto _concept_requires_(/* args (optional)*/) -> // static auto Requires_(/* args (optional)*/) ->
// decltype(/*requirements...*/); // decltype(/*requirements...*/);
// template<class A, class B> // template<class A, class B>
// static constexpr auto is_satisfied_by(int) -> // static constexpr auto is_satisfied_by(int) ->
// decltype(bool(&_concept_requires_<A,B>)) { return true; } // decltype(bool(&Requires_<A,B>)) { return true; }
// template<class A, class B> // template<class A, class B>
// static constexpr bool is_satisfied_by(long) { return false; } // static constexpr bool is_satisfied_by(long) { return false; }
// }; // };
...@@ -257,21 +190,17 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -257,21 +190,17 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
{ __VA_ARGS__; } \ { __VA_ARGS__; } \
/**/ /**/
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \ #define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
inline namespace pushmi_concept_eager { \ inline namespace _eager_ { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
concept bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = PUSHMI_PP_EVAL2( \ concept bool NAME = PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__); \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
__VA_ARGS__); \
} \ } \
namespace defer = pushmi_concept_eager; \ namespace defer = _eager_; \
namespace lazy { \ namespace lazy { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \ struct PUSHMI_PP_CAT(NAME, Concept) { \
using Concept = \ using Concept = PUSHMI_PP_CAT(NAME, Concept); \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept); \
explicit constexpr operator bool() const noexcept { \ explicit constexpr operator bool() const noexcept { \
return (bool) defer::PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME)< \ return (bool) defer::NAME<PUSHMI_PP_EXPAND ARGS>; \
PUSHMI_PP_EXPAND ARGS>; \
} \ } \
constexpr auto operator!() const noexcept { \ constexpr auto operator!() const noexcept { \
return ::pushmi::concepts::detail::Not<Concept>{}; \ return ::pushmi::concepts::detail::Not<Concept>{}; \
...@@ -282,9 +211,8 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -282,9 +211,8 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
} \ } \
}; \ }; \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \ PUSHMI_INLINE_VAR constexpr auto NAME = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \ PUSHMI_PP_CAT(NAME, Concept)<PUSHMI_PP_EXPAND ARGS>{}; \
<PUSHMI_PP_EXPAND ARGS>{}; \
} \ } \
/**/ /**/
#else #else
...@@ -307,44 +235,38 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -307,44 +235,38 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
<decltype(__VA_ARGS__, void())>() \ <decltype(__VA_ARGS__, void())>() \
/**/ /**/
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \ #define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \ struct PUSHMI_PP_CAT(NAME, Concept) { \
using Concept = \ using Concept = PUSHMI_PP_CAT(NAME, Concept); \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept); \
PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN \ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
static auto _concept_requires_ PUSHMI_PP_EVAL2( \ static auto Requires_ PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__); \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
__VA_ARGS__); \
PUSHMI_PP_IGNORE_CXX2A_COMPAT_END \ PUSHMI_PP_IGNORE_CXX2A_COMPAT_END \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
struct _is_satisfied_by_ { \ struct Eval { \
template <class C_ = Concept> \ template <class C_ = Concept> \
static constexpr decltype( \ static constexpr decltype( \
!&C_::template _concept_requires_<PUSHMI_PP_EXPAND ARGS>) \ !&C_::template Requires_<PUSHMI_PP_EXPAND ARGS>) \
impl(int) noexcept { return true; } \ impl(int) noexcept { return true; } \
static constexpr bool impl(long) noexcept { return false; } \ static constexpr bool impl(long) noexcept { return false; } \
explicit constexpr operator bool() const noexcept { \ explicit constexpr operator bool() const noexcept { \
return _is_satisfied_by_::impl(0); \ return Eval::impl(0); \
} \ } \
constexpr auto operator!() const noexcept { \ constexpr auto operator!() const noexcept { \
return ::pushmi::concepts::detail::Not<_is_satisfied_by_>{}; \ return ::pushmi::concepts::detail::Not<Eval>{}; \
} \ } \
template <class That> \ template <class That> \
constexpr auto operator&&(That) const noexcept { \ constexpr auto operator&&(That) const noexcept { \
return ::pushmi::concepts::detail::And< \ return ::pushmi::concepts::detail::And<Eval, That>{}; \
_is_satisfied_by_, That>{}; \
} \ } \
}; \ }; \
}; \ }; \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \ PUSHMI_INLINE_VAR constexpr bool NAME = \
(bool)PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \ (bool)PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{}; \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
namespace lazy { \ namespace lazy { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \ PUSHMI_INLINE_VAR constexpr auto NAME = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \ PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{}; \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
} \ } \
namespace defer = lazy; \ namespace defer = lazy; \
/**/ /**/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment