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

make pushmi build with clang trunk

fbshipit-source-id: 7a4d2e9c7fff8248faddaa5b3c246eb66782c97e
parent c10dad4f
...@@ -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})
......
...@@ -11,4 +11,3 @@ target_link_libraries(for_each_3 ...@@ -11,4 +11,3 @@ target_link_libraries(for_each_3
pushmi pushmi
examples examples
Threads::Threads) Threads::Threads)
\ No newline at end of file
...@@ -10,14 +10,20 @@ using namespace pushmi::aliases; ...@@ -10,14 +10,20 @@ using namespace pushmi::aliases;
template<class Executor, class Allocator = std::allocator<char>> template<class Executor, class Allocator = std::allocator<char>>
auto naive_executor_bulk_target(Executor e, Allocator a = Allocator{}) { auto naive_executor_bulk_target(Executor e, Allocator a = Allocator{}) {
return [e, a]<class IF, class RS, class Input, class F, class ShapeBegin, class ShapeEnd, class Out>( return [e, a](
IF init, auto init,
RS selector, auto selector,
Input input, auto input,
F&& func, auto&& func,
ShapeBegin sb, auto sb,
ShapeEnd se, auto se,
Out out) { auto out) {
using RS = decltype(selector);
using F = std::conditional_t<
std::is_lvalue_reference<decltype(func)>::value,
decltype(func),
typename std::remove_reference<decltype(func)>::type>;
using Out = decltype(out);
try { try {
typename std::allocator_traits<Allocator>::template rebind_alloc<char> allocState(a); typename std::allocator_traits<Allocator>::template rebind_alloc<char> allocState(a);
auto shared_state = std::allocate_shared< auto shared_state = std::allocate_shared<
......
...@@ -8,14 +8,14 @@ ...@@ -8,14 +8,14 @@
using namespace pushmi::aliases; using namespace pushmi::aliases;
auto inline_bulk_target() { auto inline_bulk_target() {
return []<class IF, class RS, class Input, class F, class ShapeBegin, class ShapeEnd, class Out>( return [](
IF init, auto init,
RS selector, auto selector,
Input input, auto input,
F&& func, auto&& func,
ShapeBegin sb, auto sb,
ShapeEnd se, auto se,
Out out) { auto out) {
try { try {
auto acc = init(input); auto acc = init(input);
for (decltype(sb) idx{sb}; idx != se; ++idx){ for (decltype(sb) idx{sb}; idx != se; ++idx){
......
...@@ -12,14 +12,20 @@ using namespace pushmi::aliases; ...@@ -12,14 +12,20 @@ using namespace pushmi::aliases;
template<class Executor, class Allocator = std::allocator<char>> template<class Executor, class Allocator = std::allocator<char>>
auto naive_executor_bulk_target(Executor e, Allocator a = Allocator{}) { auto naive_executor_bulk_target(Executor e, Allocator a = Allocator{}) {
return [e, a]<class IF, class RS, class Input, class F, class ShapeBegin, class ShapeEnd, class Out>( return [e, a](
IF init, auto init,
RS selector, auto selector,
Input input, auto input,
F&& func, auto&& func,
ShapeBegin sb, auto sb,
ShapeEnd se, auto se,
Out out) { auto out) {
using RS = decltype(selector);
using F = std::conditional_t<
std::is_lvalue_reference<decltype(func)>::value,
decltype(func),
typename std::remove_reference<decltype(func)>::type>;
using Out = decltype(out);
try { try {
typename std::allocator_traits<Allocator>::template rebind_alloc<char> allocState(a); typename std::allocator_traits<Allocator>::template rebind_alloc<char> allocState(a);
auto shared_state = std::allocate_shared< auto shared_state = std::allocate_shared<
......
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
using namespace pushmi::aliases; using namespace pushmi::aliases;
auto inline_bulk_target() { auto inline_bulk_target() {
return []<class IF, class RS, class Input, class F, class ShapeBegin, class ShapeEnd, class Out>( return [](
IF init, auto init,
RS selector, auto selector,
Input input, auto input,
F&& func, auto&& func,
ShapeBegin sb, auto sb,
ShapeEnd se, auto se,
Out out) { auto out) {
try { try {
auto acc = init(input); auto acc = init(input);
for (decltype(sb) idx{sb}; idx != se; ++idx){ for (decltype(sb) idx{sb}; idx != se; ++idx){
......
This diff is collapsed.
...@@ -43,7 +43,7 @@ struct ignoreVF { ...@@ -43,7 +43,7 @@ struct ignoreVF {
struct abortEF { struct abortEF {
template <class E> template <class E>
void operator()(E) noexcept { void operator()(E &&) noexcept {
std::abort(); std::abort();
} }
}; };
......
...@@ -27,8 +27,9 @@ class deferred<detail::erase_deferred_t, E> { ...@@ -27,8 +27,9 @@ class deferred<detail::erase_deferred_t, E> {
static void s_submit(data&, any_none<E>) {} static void s_submit(data&, any_none<E>) {}
void (*op_)(data&, data*) = s_op; void (*op_)(data&, data*) = s_op;
void (*submit_)(data&, any_none<E>) = s_submit; void (*submit_)(data&, any_none<E>) = s_submit;
};
PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_); PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_);
} const* vptr_ = &vtable::noop_; vtable const* vptr_ = &noop_;
template <class Wrapped> template <class Wrapped>
deferred(Wrapped obj, std::false_type) : deferred() { deferred(Wrapped obj, std::false_type) : deferred() {
struct s { struct s {
...@@ -94,7 +95,7 @@ class deferred<detail::erase_deferred_t, E> { ...@@ -94,7 +95,7 @@ class deferred<detail::erase_deferred_t, E> {
// Class static definitions: // Class static definitions:
template <class E> template <class E>
PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename deferred<detail::erase_deferred_t, E>::vtable const PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename deferred<detail::erase_deferred_t, E>::vtable const
deferred<detail::erase_deferred_t, E>::vtable::noop_); deferred<detail::erase_deferred_t, E>::noop_);
template <class SF> template <class SF>
class deferred<SF> { class deferred<SF> {
......
...@@ -258,7 +258,9 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -258,7 +258,9 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
using Concept = PUSHMI_PP_CAT(NAME, Concept); \ using Concept = PUSHMI_PP_CAT(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 Requires_ PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__); \ static auto Requires_ PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__) { \
return 0; \
} \
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 Eval { \ struct Eval { \
...@@ -490,8 +492,14 @@ template <class T> ...@@ -490,8 +492,14 @@ template <class T>
constexpr bool implicitly_convertible_to(T) { constexpr bool implicitly_convertible_to(T) {
return true; return true;
} }
#ifdef __clang__
template <bool B> template <bool B>
PUSHMI_INLINE_VAR constexpr std::enable_if_t<B, bool> requires_ = true; std::enable_if_t<B> requires_()
{}
#else
template <bool B>
PUSHMI_INLINE_VAR constexpr std::enable_if_t<B, int> requires_ = 0;
#endif
} // namespace pushmi } // namespace pushmi
PUSHMI_PP_IGNORE_CXX2A_COMPAT_END PUSHMI_PP_IGNORE_CXX2A_COMPAT_END
...@@ -42,7 +42,10 @@ public: ...@@ -42,7 +42,10 @@ public:
// will ask whether value(single<T,E>, T'&) is well-formed. And *that* will // will ask whether value(single<T,E>, T'&) is well-formed. And *that* will
// ask whether T'& is convertible to T. That brings us right back to this // ask whether T'& is convertible to T. That brings us right back to this
// constructor. Constraint recursion! // constructor. Constraint recursion!
static_assert(TimeSenderTo<Wrapped, single<Other, E>>, "any_time_executor_ref passed an invalid time_executor"); static_assert(
TimeSenderTo<Wrapped, single<Other, E>>,
"Expecting to be passed a TimeSender that can send to a SingleReceiver"
" that accpets a value of type Other and an error of type E");
struct s { struct s {
static TP now(void* pobj) { static TP now(void* pobj) {
return ::pushmi::now(*static_cast<Wrapped*>(pobj)); return ::pushmi::now(*static_cast<Wrapped*>(pobj));
......
...@@ -32,8 +32,9 @@ class flow_single<V, PE, E> { ...@@ -32,8 +32,9 @@ class flow_single<V, PE, E> {
void (*value_)(data&, V) = s_value; void (*value_)(data&, V) = s_value;
void (*stopping_)(data&) noexcept = s_stopping; void (*stopping_)(data&) noexcept = s_stopping;
void (*starting_)(data&, any_none<PE>&) = s_starting; void (*starting_)(data&, any_none<PE>&) = s_starting;
};
PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_); PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_);
} const* vptr_ = &vtable::noop_; vtable const* vptr_ = &noop_;
template <class Wrapped> template <class Wrapped>
flow_single(Wrapped obj, std::false_type) : flow_single() { flow_single(Wrapped obj, std::false_type) : flow_single() {
struct s { struct s {
...@@ -51,10 +52,10 @@ class flow_single<V, PE, E> { ...@@ -51,10 +52,10 @@ class flow_single<V, PE, E> {
static void value(data& src, V v) { static void value(data& src, V v) {
::pushmi::set_value(*static_cast<Wrapped*>(src.pobj_), std::move(v)); ::pushmi::set_value(*static_cast<Wrapped*>(src.pobj_), std::move(v));
} }
static void stopping(data& src) { static void stopping(data& src) noexcept {
::pushmi::set_stopping(*static_cast<Wrapped*>(src.pobj_)); ::pushmi::set_stopping(*static_cast<Wrapped*>(src.pobj_));
} }
static void stopping(data& src, any_none<PE>& up) { static void starting(data& src, any_none<PE>& up) {
::pushmi::set_starting(*static_cast<Wrapped*>(src.pobj_), up); ::pushmi::set_starting(*static_cast<Wrapped*>(src.pobj_), up);
} }
}; };
...@@ -137,7 +138,7 @@ public: ...@@ -137,7 +138,7 @@ public:
// Class static definitions: // Class static definitions:
template <class V, class PE, class E> template <class V, class PE, class E>
PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename flow_single<V, PE, E>::vtable const PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename flow_single<V, PE, E>::vtable const
flow_single<V, PE, E>::vtable::noop_); flow_single<V, PE, E>::noop_);
template <class VF, class EF, class DF, class StpF, class StrtF> template <class VF, class EF, class DF, class StpF, class StrtF>
#if __cpp_concepts #if __cpp_concepts
......
...@@ -24,8 +24,9 @@ class flow_single_deferred<V, PE, E> { ...@@ -24,8 +24,9 @@ class flow_single_deferred<V, PE, E> {
static void s_submit(data&, flow_single<V, PE, E>) {} static void s_submit(data&, flow_single<V, PE, E>) {}
void (*op_)(data&, data*) = s_op; void (*op_)(data&, data*) = s_op;
void (*submit_)(data&, flow_single<V, PE, E>) = s_submit; void (*submit_)(data&, flow_single<V, PE, E>) = s_submit;
};
PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_); PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_);
} const* vptr_ = &vtable::noop_; vtable const* vptr_ = &noop_;
template <class Wrapped> template <class Wrapped>
flow_single_deferred(Wrapped obj, std::false_type) : flow_single_deferred() { flow_single_deferred(Wrapped obj, std::false_type) : flow_single_deferred() {
struct s { struct s {
...@@ -94,7 +95,7 @@ class flow_single_deferred<V, PE, E> { ...@@ -94,7 +95,7 @@ class flow_single_deferred<V, PE, E> {
// Class static definitions: // Class static definitions:
template <class V, class PE, class E> template <class V, class PE, class E>
PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename flow_single_deferred<V, PE, E>::vtable const PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename flow_single_deferred<V, PE, E>::vtable const
flow_single_deferred<V, PE, E>::vtable::noop_); flow_single_deferred<V, PE, E>::noop_);
template <class SF> template <class SF>
class flow_single_deferred<SF> { class flow_single_deferred<SF> {
......
...@@ -27,8 +27,9 @@ class none<E> { ...@@ -27,8 +27,9 @@ class none<E> {
void (*op_)(data&, data*) = s_op; void (*op_)(data&, data*) = s_op;
void (*done_)(data&) = s_done; void (*done_)(data&) = s_done;
void (*error_)(data&, E) noexcept = s_error; void (*error_)(data&, E) noexcept = s_error;
PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_ ); };
} const* vptr_ = &vtable::noop_; PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_);
vtable const* vptr_ = &noop_;
template <class Wrapped> template <class Wrapped>
none(Wrapped obj, std::false_type) : none() { none(Wrapped obj, std::false_type) : none() {
struct s { struct s {
...@@ -106,14 +107,19 @@ public: ...@@ -106,14 +107,19 @@ public:
// Class static definitions: // Class static definitions:
template <class E> template <class E>
PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT( typename none<E>::vtable const none<E>::vtable::noop_); PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename none<E>::vtable const none<E>::noop_);
template <class EF, class DF> template <class EF, class DF>
#if __cpp_concepts #if __cpp_concepts
requires Invocable<DF&> requires Invocable<DF&>
#endif #endif
class none<EF, DF> { class none<EF, DF> {
static_assert(!detail::is_v<EF, on_value_fn> && !detail::is_v<EF, single>, "none was passed an invalid Error Function"); static_assert(
!detail::is_v<EF, on_value_fn>,
"the first parameter is the error implementation, but on_value{} was passed");
static_assert(
!detail::is_v<EF, single>,
"the first parameter is the error implementation, but a single<> was passed");
bool done_ = false; bool done_ = false;
EF ef_; EF ef_;
DF df_; DF df_;
...@@ -157,8 +163,12 @@ class none<Data, DEF, DDF> { ...@@ -157,8 +163,12 @@ class none<Data, DEF, DDF> {
Data data_; Data data_;
DEF ef_; DEF ef_;
DDF df_; DDF df_;
static_assert(!detail::is_v<DEF, on_value_fn>, "none was passed an invalid Error Function"); static_assert(
static_assert(!detail::is_v<Data, single>, "none was passed an invalid Data"); !detail::is_v<DEF, on_value_fn>,
"the second parameter is the error implementation, but on_value{} was passed");
static_assert(
!detail::is_v<Data, single>,
"none should not be used to wrap a single<>");
public: public:
using properties = property_set<is_receiver<>, is_none<>>; using properties = property_set<is_receiver<>, is_none<>>;
......
...@@ -32,8 +32,9 @@ class single<V, E> { ...@@ -32,8 +32,9 @@ class single<V, E> {
void (*error_)(data&, E) noexcept = s_error; void (*error_)(data&, E) noexcept = s_error;
void (*rvalue_)(data&, V&&) = s_rvalue; void (*rvalue_)(data&, V&&) = s_rvalue;
void (*lvalue_)(data&, V&) = s_lvalue; void (*lvalue_)(data&, V&) = s_lvalue;
};
PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_); PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_);
} const* vptr_ = &vtable::noop_; vtable const* vptr_ = &noop_;
template <class T, class U = std::decay_t<T>> template <class T, class U = std::decay_t<T>>
using wrapped_t = using wrapped_t =
std::enable_if_t<!std::is_same<U, single>::value, U>; std::enable_if_t<!std::is_same<U, single>::value, U>;
...@@ -153,7 +154,7 @@ public: ...@@ -153,7 +154,7 @@ public:
// Class static definitions: // Class static definitions:
template <class V, class E> template <class V, class E>
PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT( typename single<V, E>::vtable const single<V, E>::vtable::noop_); PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename single<V, E>::vtable const single<V, E>::noop_);
template <class VF, class EF, class DF> template <class VF, class EF, class DF>
#if __cpp_concepts #if __cpp_concepts
...@@ -171,9 +172,8 @@ class single<VF, EF, DF> { ...@@ -171,9 +172,8 @@ class single<VF, EF, DF> {
static_assert( static_assert(
!detail::is_v<EF, on_value_fn>, !detail::is_v<EF, on_value_fn>,
"the second parameter is the error implementation, but on_value{} was passed"); "the second parameter is the error implementation, but on_value{} was passed");
static_assert(NothrowInvocable<EF, std::exception_ptr>, static_assert(NothrowInvocable<EF&, std::exception_ptr>,
"error function must be noexcept and support std::exception_ptr"); "error function must be noexcept and support std::exception_ptr");
public: public:
using properties = property_set<is_receiver<>, is_single<>>; using properties = property_set<is_receiver<>, is_single<>>;
......
...@@ -24,8 +24,9 @@ class any_single_deferred { ...@@ -24,8 +24,9 @@ class any_single_deferred {
static void s_submit(data&, single<V, E>) {} static void s_submit(data&, single<V, E>) {}
void (*op_)(data&, data*) = s_op; void (*op_)(data&, data*) = s_op;
void (*submit_)(data&, single<V, E>) = s_submit; void (*submit_)(data&, single<V, E>) = s_submit;
};
PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_); PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_);
} const* vptr_ = &vtable::noop_; vtable const* vptr_ = &noop_;
template <class Wrapped> template <class Wrapped>
any_single_deferred(Wrapped obj, std::false_type) : any_single_deferred() { any_single_deferred(Wrapped obj, std::false_type) : any_single_deferred() {
struct s { struct s {
...@@ -94,7 +95,7 @@ class any_single_deferred { ...@@ -94,7 +95,7 @@ class any_single_deferred {
// Class static definitions: // Class static definitions:
template <class V, class E> template <class V, class E>
PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename any_single_deferred<V, E>::vtable const PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename any_single_deferred<V, E>::vtable const
any_single_deferred<V, E>::vtable::noop_); any_single_deferred<V, E>::noop_);
template <class SF> template <class SF>
class single_deferred<SF> { class single_deferred<SF> {
......
...@@ -29,8 +29,9 @@ class any_time_single_deferred { ...@@ -29,8 +29,9 @@ class any_time_single_deferred {
void (*op_)(data&, data*) = s_op; void (*op_)(data&, data*) = s_op;
TP (*now_)(data&) = s_now; TP (*now_)(data&) = s_now;
void (*submit_)(data&, TP, single<V, E>) = s_submit; void (*submit_)(data&, TP, single<V, E>) = s_submit;
};
PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_); PUSHMI_DECLARE_CONSTEXPR_IN_CLASS_INIT(static vtable const noop_);
} const* vptr_ = &vtable::noop_; vtable const* vptr_ = &noop_;
template <class Wrapped> template <class Wrapped>
any_time_single_deferred(Wrapped obj, std::false_type) any_time_single_deferred(Wrapped obj, std::false_type)
: any_time_single_deferred() { : any_time_single_deferred() {
...@@ -115,7 +116,7 @@ class any_time_single_deferred { ...@@ -115,7 +116,7 @@ class any_time_single_deferred {
// Class static definitions: // Class static definitions:
template <class V, class E, class TP> template <class V, class E, class TP>
PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename any_time_single_deferred<V, E, TP>::vtable const PUSHMI_DEFINE_CONSTEXPR_IN_CLASS_INIT(typename any_time_single_deferred<V, E, TP>::vtable const
any_time_single_deferred<V, E, TP>::vtable::noop_); any_time_single_deferred<V, E, TP>::noop_);
template <class SF, class NF> template <class SF, class NF>
#if __cpp_concepts #if __cpp_concepts
......
...@@ -71,7 +71,7 @@ PUSHMI_CONCEPT_DEF( ...@@ -71,7 +71,7 @@ PUSHMI_CONCEPT_DEF(
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template (class T, template<class...> class Trait, class... Args) template (class T, template<class...> class Trait, class... Args)
(concept Satisfies)(T, Trait, Args...), (concept Satisfies)(T, Trait, Args...),
bool(Trait<T>::type::value) static_cast<bool>(Trait<T>::type::value)
); );
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
...@@ -198,9 +198,9 @@ decltype(auto) invoke(F&& f, As&&...as) ...@@ -198,9 +198,9 @@ decltype(auto) invoke(F&& f, As&&...as)
PUSHMI_TEMPLATE (class F, class...As) PUSHMI_TEMPLATE (class F, class...As)
(requires requires ( (requires requires (
std::mem_fn(std::declval<F>())(std::declval<As>()...) std::mem_fn(std::declval<F>())(std::declval<As>()...)
)) ) && std::is_member_pointer<F>::value)
decltype(auto) invoke(F f, As&&...as) decltype(auto) invoke(F f, As&&...as)
noexcept(noexcept(std::mem_fn(f)((As&&) as...))) { noexcept(noexcept(std::declval<decltype(std::mem_fn(f))>()((As&&) as...))) {
return std::mem_fn(f)((As&&) as...); return std::mem_fn(f)((As&&) as...);
} }
template <class F, class...As> template <class F, class...As>
...@@ -211,16 +211,16 @@ using invoke_result_t = ...@@ -211,16 +211,16 @@ using invoke_result_t =
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template (class F, class... Args) template (class F, class... Args)
(concept Invocable)(F, Args...), (concept Invocable)(F, Args...),
requires(F&& f, Args&&... args) ( requires(F&& f) (
pushmi::invoke((F &&) f, (Args &&) args...) pushmi::invoke((F &&) f, std::declval<Args>()...)
) )
); );
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template (class F, class... Args) template (class F, class... Args)
(concept NothrowInvocable)(F, Args...), (concept NothrowInvocable)(F, Args...),
requires(F&& f, Args&&... args) ( requires(F&& f) (
requires_<noexcept(pushmi::invoke((F &&) f, (Args &&) args...))> requires_<noexcept(pushmi::invoke((F &&) f, std::declval<Args>()...))>
) && ) &&
Invocable<F, Args...> Invocable<F, Args...>
); );
......
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