Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
folly
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
folly
Commits
2690ee57
Commit
2690ee57
authored
Oct 16, 2018
by
Eric Niebler
Committed by
Facebook Github Bot
Oct 17, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use real concepts when they are available
fbshipit-source-id: bfecdc1c0e934cf073e610c2cb98518bfde84ecd
parent
a68731cb
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
738 additions
and
504 deletions
+738
-504
folly/experimental/pushmi/include/pushmi.h
folly/experimental/pushmi/include/pushmi.h
+369
-252
folly/experimental/pushmi/include/pushmi/concepts.h
folly/experimental/pushmi/include/pushmi/concepts.h
+6
-7
folly/experimental/pushmi/include/pushmi/deferred.h
folly/experimental/pushmi/include/pushmi/deferred.h
+19
-19
folly/experimental/pushmi/include/pushmi/detail/concept_def.h
...y/experimental/pushmi/include/pushmi/detail/concept_def.h
+166
-61
folly/experimental/pushmi/include/pushmi/flow_single.h
folly/experimental/pushmi/include/pushmi/flow_single.h
+19
-19
folly/experimental/pushmi/include/pushmi/flow_single_deferred.h
...experimental/pushmi/include/pushmi/flow_single_deferred.h
+21
-19
folly/experimental/pushmi/include/pushmi/none.h
folly/experimental/pushmi/include/pushmi/none.h
+39
-38
folly/experimental/pushmi/include/pushmi/o/defer.h
folly/experimental/pushmi/include/pushmi/o/defer.h
+1
-0
folly/experimental/pushmi/include/pushmi/properties.h
folly/experimental/pushmi/include/pushmi/properties.h
+4
-2
folly/experimental/pushmi/include/pushmi/single.h
folly/experimental/pushmi/include/pushmi/single.h
+43
-42
folly/experimental/pushmi/include/pushmi/single_deferred.h
folly/experimental/pushmi/include/pushmi/single_deferred.h
+26
-23
folly/experimental/pushmi/include/pushmi/time_single_deferred.h
...experimental/pushmi/include/pushmi/time_single_deferred.h
+25
-22
No files found.
folly/experimental/pushmi/include/pushmi.h
View file @
2690ee57
...
@@ -3872,33 +3872,32 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -3872,33 +3872,32 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// t = (U &&) u,
// t = (U &&) u,
// ::pushmi::concepts::requires_<Same<decltype(t = (U &&) u), T>>
// ::pushmi::concepts::requires_<Same<decltype(t = (U &&) u), T>>
// ) &&
// ) &&
// std::is_lvalue_reference
<T>{}
// std::is_lvalue_reference
_v<T>
// );
// );
#define PUSHMI_CONCEPT_DEF(DECL, ...) \
#define PUSHMI_CONCEPT_DEF(DECL, ...) \
PUSHMI_PP_EVAL( \
PUSHMI_PP_EVAL( \
PUSHMI_PP_DECL_DEF, \
PUSHMI_PP_DECL_DEF, \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_DECL_, DECL), \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_DECL_, DECL), \
__VA_ARGS__) \
/**/
#define PUSHMI_PP_DECL_DEF_NAME(...) \
__VA_ARGS__, \
__VA_ARGS__, \
PUSHMI_PP_EAT) \
/**/
/**/
#define PUSHMI_PP_DECL_DEF_NAME(...) __VA_ARGS__,
#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...) \
#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, REQUIRES, ...) \
PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \
PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \
TPARAM, \
TPARAM, \
NAME, \
NAME, \
REQUIRES, \
__VA_ARGS__) \
__VA_ARGS__) \
/**/
/**/
// The defn is of the form:
// The defn is of the form:
// template(class A, class B = void, class... Rest)
// template(class A, class B = void, class... Rest)
// (concept Name)(A, B, Rest...),
// (concept Name)(A, B, Rest...),
// // requirements...
// // requirements...
#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME,
REQUIRES, ...)
\
#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME,
...)
\
PUSHMI_PP_EVAL4( \
PUSHMI_PP_EVAL4( \
PUSHMI_PP_DECL_DEF_IMPL, \
PUSHMI_PP_DECL_DEF_IMPL, \
TPARAM, \
TPARAM, \
PUSHMI_PP_DECL_DEF_NAME NAME, \
PUSHMI_PP_DECL_DEF_NAME NAME, \
REQUIRES, \
__VA_ARGS__) \
__VA_ARGS__) \
/**/
/**/
// The defn is of the form:
// The defn is of the form:
...
@@ -3906,12 +3905,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -3906,12 +3905,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// concept Name,
// concept Name,
// // requirements...
// // requirements...
// Compute the template arguments (A, B) from the template introducer.
// Compute the template arguments (A, B) from the template introducer.
#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME,
REQUIRES, ...)
\
#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME,
...)
\
PUSHMI_PP_DECL_DEF_IMPL( \
PUSHMI_PP_DECL_DEF_IMPL( \
TPARAM, \
TPARAM, \
NAME, \
NAME, \
(PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \
(PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \
REQUIRES, \
__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:
...
@@ -3927,17 +3925,83 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -3927,17 +3925,83 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// };
// };
// template<class A, class B>
// template<class A, class B>
// inline constexpr bool Name = NameConcept::is_satisfied_by<A, B>(0);
// inline constexpr bool Name = NameConcept::is_satisfied_by<A, B>(0);
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, REQUIRES, ...) \
#if __cpp_concepts
// No requires expression
#define PUSHMI_PP_DEF_IMPL_0(...) \
__VA_ARGS__ \
/**/
// Requires expression
#define PUSHMI_PP_DEF_IMPL_1(...) \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__) \
/**/
#define PUSHMI_PP_DEF_IMPL_1_requires \
requires PUSHMI_PP_DEF_IMPL_1_REQUIRES \
/**/
#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...) \
(__VA_ARGS__) PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY \
/**/
#define PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY(...) \
{ __VA_ARGS__; } \
/**/
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
inline namespace pushmi_concept_eager { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
concept bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = PUSHMI_PP_EVAL2( \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
__VA_ARGS__); \
} \
namespace defer = pushmi_concept_eager; \
namespace lazy { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \
using Concept = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept); \
explicit constexpr operator bool() const noexcept { \
return (bool) defer::PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME)< \
PUSHMI_PP_EXPAND ARGS>; \
} \
constexpr auto operator!() const noexcept { \
return ::pushmi::concepts::detail::Not<Concept>{}; \
} \
template <class That> \
constexpr auto operator&&(That) const noexcept { \
return ::pushmi::concepts::detail::And<Concept, That>{}; \
} \
}; \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \
<PUSHMI_PP_EXPAND ARGS>{}; \
} \
/**/
#else
// No requires expression:
#define PUSHMI_PP_DEF_IMPL_0(...) \
() -> std::enable_if_t<bool(__VA_ARGS__), int> \
/**/
// Requires expression:
#define PUSHMI_PP_DEF_IMPL_1(...) \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__) ), int> \
/**/
#define PUSHMI_PP_DEF_IMPL_1_requires \
PUSHMI_PP_DEF_IMPL_1_REQUIRES \
/**/
#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...) \
(__VA_ARGS__) -> std::enable_if_t<bool( \
::pushmi::concepts::detail::requires_ PUSHMI_PP_DEF_REQUIRES_BODY \
/**/
#define PUSHMI_PP_DEF_REQUIRES_BODY(...) \
<decltype(__VA_ARGS__, void())>() \
/**/
#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(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \
using Concept = \
using Concept = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, 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 _concept_requires_ PUSHMI_PP_EVAL2( \
PUSHMI_PP_DEF_WRAP, \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, REQUIRES), \
__VA_ARGS__); \
REQUIRES, \
(__VA_ARGS__))(~) int>; \
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 _is_satisfied_by_ { \
...
@@ -3969,8 +4033,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -3969,8 +4033,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
} \
} \
namespace defer = lazy; \
/**/
/**/
#endif
#define PUSHMI_PP_REQUIRES_PROBE_requires \
PUSHMI_PP_PROBE(~) \
/**/
#define PUSHMI_PP_DEF_IMPL(REQUIRES, ...) \
PUSHMI_PP_CAT( \
PUSHMI_PP_DEF_IMPL_, \
PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES))) \
/**/
#define PUSHMI_PP_DEF_DECL_template(...) \
#define PUSHMI_PP_DEF_DECL_template(...) \
template(__VA_ARGS__), \
template(__VA_ARGS__), \
/**/
/**/
...
@@ -3984,7 +4058,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -3984,7 +4058,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_DEF_bool
#define PUSHMI_PP_DEF_bool
#define PUSHMI_PP_DEF_size_t
#define PUSHMI_PP_DEF_size_t
#define PUSHMI_PP_DEF_unsigned
#define PUSHMI_PP_DEF_unsigned
#define PUSHMI_PP_DEF_requires ~,
#define PUSHMI_PP_AUX_template(...) \
#define PUSHMI_PP_AUX_template(...) \
PUSHMI_PP_CAT2( \
PUSHMI_PP_CAT2( \
PUSHMI_PP_TPARAM_, \
PUSHMI_PP_TPARAM_, \
...
@@ -4001,63 +4074,95 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -4001,63 +4074,95 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_TPARAM_5(_1, ...) \
#define PUSHMI_PP_TPARAM_5(_1, ...) \
PUSHMI_PP_CAT2(PUSHMI_PP_DEF_, _1), PUSHMI_PP_TPARAM_4(__VA_ARGS__)
PUSHMI_PP_CAT2(PUSHMI_PP_DEF_, _1), PUSHMI_PP_TPARAM_4(__VA_ARGS__)
#define PUSHMI_PP_DEF_WRAP(X, Y, ...) \
////////////////////////////////////////////////////////////////////////////////
PUSHMI_PP_EVAL3( \
// PUSHMI_TEMPLATE
PUSHMI_PP_CAT(PUSHMI_PP_DEF_WRAP_, PUSHMI_PP_COUNT(__VA_ARGS__)), \
// Usage:
X, \
// PUSHMI_TEMPLATE (class A, class B)
Y, \
// (requires Concept1<A> && Concept2<B>)
__VA_ARGS__) \
// void foo(A a, B b)
// {}
// or
// PUSHMI_TEMPLATE (class A, class B)
// (requires requires (expr1, expr2, expr3) && Concept1<A> && Concept2<B>)
// void foo(A a, B b)
// {}
#if __cpp_concepts
#define PUSHMI_TEMPLATE(...) \
template<__VA_ARGS__> PUSHMI_TEMPLATE_AUX_ \
/**/
/**/
#define PUSHMI_TEMPLATE_AUX_(...) \
// No requires expression:
PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__)) \
#define PUSHMI_PP_DEF_WRAP_1(_, HEAD, TAIL) \
() -> std::enable_if_t<HEAD, PUSHMI_PP_EXPAND TAIL \
/**/
/**/
// Requires expression:
#define PUSHMI_TEMPLATE_AUX_3_requires
#define PUSHMI_PP_DEF_WRAP_2(_a, HEAD, _b, TAIL) \
#define PUSHMI_TEMPLATE_AUX_4(...) \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_REQUIRES_, PUSHMI_PP_IS_PAREN(HEAD)) HEAD, \
PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__) \
PUSHMI_PP_EXPAND TAIL \
/**/
/**/
// Requires expression without a requirement parameter list:
#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...) \
#define PUSHMI_PP_DEF_REQUIRES_0
\
PUSHMI_PP_CAT(
\
() -> decltype(::pushmi::concepts::detail::requires_
\
PUSHMI_TEMPLATE_AUX_5_,
\
PUSHMI_PP_
DEF_REQUIRES_EXPRS
\
PUSHMI_PP_
CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))
\
/**/
/**/
// Requires expression with a requirement parameter list:
// No requires expression:
#define PUSHMI_PP_DEF_REQUIRES_1(...) \
#define PUSHMI_TEMPLATE_AUX_5_0(...) \
(__VA_ARGS__) -> std::enable_if_t<::pushmi::concepts::detail::requires_ \
requires __VA_ARGS__ \
PUSHMI_PP_DEF_REQUIRES_EXPRS \
/**/
/**/
// Requires expression
#define
PUSHMI_PP_DEF_REQUIRES_EXPRS(...)
\
#define
PUSHMI_TEMPLATE_AUX_5_1(...)
\
<decltype(__VA_ARGS__, void())>()
\
PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)
\
/**/
/**/
#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
#define PUSHMI_TYPE_CONSTRAINT(X) class
requires requires { __VA_ARGS__; }
#else
#define PUSHMI_TEMPLATE(...) \
#define PUSHMI_TEMPLATE(...) \
template<__VA_ARGS__ PUSHMI_TEMPLATE_AUX_
template<__VA_ARGS__ PUSHMI_TEMPLATE_AUX_
#define PUSHMI_TEMPLATE_AUX_(...) , \
#define PUSHMI_TEMPLATE_AUX_(...) , \
int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[PUSHMI_COUNTER] = nullptr, \
int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[ \
PUSHMI_COUNTER] = nullptr, \
std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) || \
std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) || \
bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0>
bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT( \
PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0> \
/**/
#define PUSHMI_TEMPLATE_AUX_3_requires
#define PUSHMI_TEMPLATE_AUX_3_requires
#define PUSHMI_TEMPLATE_AUX_4(...) \
#define PUSHMI_TEMPLATE_AUX_4(...) \
PUSHMI_PP_EVAL(\
PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__) \
PUSHMI_PP_CAT,\
/**/
#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...) \
PUSHMI_PP_CAT( \
PUSHMI_TEMPLATE_AUX_5_, \
PUSHMI_TEMPLATE_AUX_5_, \
PUSHMI_PP_IS_EQUAL(\
PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES))) \
PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, PUSHMI_PP_CAT2(PUSHMI_TEMPLATE_AUX_5_, __VA_ARGS__)),\
/**/
PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, __VA_ARGS__)))(__VA_ARGS__)
// No requires expression:
#define PUSHMI_TEMPLATE_AUX_5_requires ~,
#define PUSHMI_TEMPLATE_AUX_5_0(...) \
#define PUSHMI_TEMPLATE_AUX_5_0(...) \
PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)
__VA_ARGS__ \
/**/
#define PUSHMI_TEMPLATE_AUX_5_1(...) \
#define PUSHMI_TEMPLATE_AUX_5_1(...) \
__VA_ARGS__
PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__) \
#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
/**/
::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>()
#define PUSHMI_TEMPLATE_AUX_6_requires(...) \
::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>() \
/**/
#endif
#if __cpp_concepts
#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__ // BUGBUG
#define PUSHMI_TYPE_CONSTRAINT(...) __VA_ARGS__
#else
#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__
#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__
#define PUSHMI_TYPE_CONSTRAINT(...) class
#endif
#if __cpp_concepts
#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE) \
requires REQUIRES \
using NAME TYPE; \
/**/
#else
#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE) \
using NAME std::enable_if_t<bool(REQUIRES), TYPE>; \
/**/
#endif
namespace
pushmi
{
namespace
pushmi
{
namespace
concepts
{
namespace
concepts
{
...
@@ -5065,14 +5170,16 @@ struct property_query_impl :
...
@@ -5065,14 +5170,16 @@ struct property_query_impl :
meta
::
and_c
<
decltype
(
property_query_fn
<
ExpectedN
>
((
properties_t
<
PS
>*
)
nullptr
))
::
value
...
>
{};
meta
::
and_c
<
decltype
(
property_query_fn
<
ExpectedN
>
((
properties_t
<
PS
>*
)
nullptr
))
::
value
...
>
{};
}
//namespace detail
}
//namespace detail
template
<
PUSHMI_TYPE_CONSTRAINT
(
Properties
)
PS
,
PUSHMI_TYPE_CONSTRAINT
(
Property
)...
ExpectedN
>
//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
template
<
class
PS
,
class
...
ExpectedN
>
struct
property_query
struct
property_query
:
meta
::
if_c
<
:
meta
::
if_c
<
Properties
<
PS
>
&&
And
<
Property
<
ExpectedN
>
...
>
,
Properties
<
PS
>
&&
And
<
Property
<
ExpectedN
>
...
>
,
detail
::
property_query_impl
<
PS
,
ExpectedN
...
>
,
detail
::
property_query_impl
<
PS
,
ExpectedN
...
>
,
std
::
false_type
>
{};
std
::
false_type
>
{};
template
<
PUSHMI_TYPE_CONSTRAINT
(
Properties
)
PS
,
PUSHMI_TYPE_CONSTRAINT
(
Property
)...
ExpectedN
>
//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
template
<
class
PS
,
class
...
ExpectedN
>
PUSHMI_INLINE_VAR
constexpr
bool
property_query_v
=
property_query
<
PS
,
ExpectedN
...
>::
value
;
PUSHMI_INLINE_VAR
constexpr
bool
property_query_v
=
property_query
<
PS
,
ExpectedN
...
>::
value
;
}
// namespace pushmi
}
// namespace pushmi
...
@@ -5428,9 +5535,9 @@ PUSHMI_CONCEPT_DEF(
...
@@ -5428,9 +5535,9 @@ PUSHMI_CONCEPT_DEF(
);
);
template
<
class
D
>
template
<
class
D
>
using
time_point_t
=
PUSHMI_PP_CONSTRAINED_USING
(
std
::
enable_if_t
<
TimeSender
<
D
>
,
decltype
(
::
pushmi
::
now
(
std
::
declval
<
D
&>
()))
>
;
TimeSender
<
D
>
,
time_point_t
=
,
decltype
(
::
pushmi
::
now
(
std
::
declval
<
D
&>
())));
// this is a more general form where the constraint could be time or priority
// this is a more general form where the constraint could be time or priority
// enum or any other ordering constraint value-type.
// enum or any other ordering constraint value-type.
...
@@ -5464,10 +5571,9 @@ PUSHMI_CONCEPT_DEF(
...
@@ -5464,10 +5571,9 @@ PUSHMI_CONCEPT_DEF(
);
);
template
<
class
D
>
template
<
class
D
>
using
constraint_t
=
PUSHMI_PP_CONSTRAINED_USING
(
std
::
enable_if_t
<
ConstrainedSender
<
D
>
,
ConstrainedSender
<
D
>
,
decltype
(
::
pushmi
::
top
(
std
::
declval
<
D
&>
()))
>
;
constraint_t
=
,
decltype
(
::
pushmi
::
top
(
std
::
declval
<
D
&>
())))
;
}
// namespace pushmi
}
// namespace pushmi
//#pragma once
//#pragma once
...
@@ -5784,21 +5890,8 @@ class none<E> {
...
@@ -5784,21 +5890,8 @@ class none<E> {
void
(
*
error_
)(
data
&
,
E
)
noexcept
=
s_error
;
void
(
*
error_
)(
data
&
,
E
)
noexcept
=
s_error
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
none
(
Wrapped
obj
,
std
::
false_type
)
:
none
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
none
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_none
<>>
;
none
()
=
default
;
none
(
none
&&
that
)
noexcept
:
none
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
NoneReceiver
<
wrapped_t
<
Wrapped
>
,
E
>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
none
(
Wrapped
obj
)
:
none
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -5816,9 +5909,8 @@ public:
...
@@ -5816,9 +5909,8 @@ public:
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtable_v
;
vptr_
=
&
vtable_v
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
NoneReceiver
<
wrapped_t
<
Wrapped
>
,
E
>
&&
insitu
<
Wrapped
>
())
none
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
none
()
{
explicit
none
(
Wrapped
obj
)
noexcept
:
none
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -5838,6 +5930,21 @@ public:
...
@@ -5838,6 +5930,21 @@ public:
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
none
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_none
<>>
;
none
()
=
default
;
none
(
none
&&
that
)
noexcept
:
none
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
NoneReceiver
<
wrapped_t
<
Wrapped
>
,
E
>
)
explicit
none
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
none
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
none
()
{
~
none
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -5951,40 +6058,40 @@ inline auto make_none() -> none<> {
...
@@ -5951,40 +6058,40 @@ inline auto make_none() -> none<> {
return
{};
return
{};
}
}
PUSHMI_TEMPLATE
(
class
EF
)
PUSHMI_TEMPLATE
(
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
EF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
EF
>
&&
not
defer
::
Invocable
<
EF
&>
))
auto
make_none
(
EF
ef
)
->
none
<
EF
,
ignoreDF
>
{
auto
make_none
(
EF
ef
)
->
none
<
EF
,
ignoreDF
>
{
return
none
<
EF
,
ignoreDF
>
{
std
::
move
(
ef
)};
return
none
<
EF
,
ignoreDF
>
{
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
auto
make_none
(
DF
df
)
->
none
<
abortEF
,
DF
>
{
auto
make_none
(
DF
df
)
->
none
<
abortEF
,
DF
>
{
return
none
<
abortEF
,
DF
>
{
std
::
move
(
df
)};
return
none
<
abortEF
,
DF
>
{
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
auto
make_none
(
EF
ef
,
DF
df
)
->
none
<
EF
,
DF
>
{
auto
make_none
(
EF
ef
,
DF
df
)
->
none
<
EF
,
DF
>
{
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
)
auto
make_none
(
Data
d
)
->
none
<
Data
,
passDEF
,
passDDF
>
{
auto
make_none
(
Data
d
)
->
none
<
Data
,
passDEF
,
passDDF
>
{
return
none
<
Data
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
return
none
<
Data
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
auto
make_none
(
Data
d
,
DEF
ef
)
->
none
<
Data
,
DEF
,
passDDF
>
{
auto
make_none
(
Data
d
,
DEF
ef
)
->
none
<
Data
,
DEF
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_none
(
Data
d
,
DDF
df
)
->
none
<
Data
,
passDEF
,
DDF
>
{
auto
make_none
(
Data
d
,
DDF
df
)
->
none
<
Data
,
passDEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_none
(
Data
d
,
DEF
ef
,
DDF
df
)
->
none
<
Data
,
DEF
,
DDF
>
{
auto
make_none
(
Data
d
,
DEF
ef
,
DDF
df
)
->
none
<
Data
,
DEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
...
@@ -5995,34 +6102,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
...
@@ -5995,34 +6102,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
none
()
->
none
<>
;
none
()
->
none
<>
;
PUSHMI_TEMPLATE
(
class
EF
)
PUSHMI_TEMPLATE
(
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
EF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
EF
>
&&
not
defer
::
Invocable
<
EF
&>
))
none
(
EF
)
->
none
<
EF
,
ignoreDF
>
;
none
(
EF
)
->
none
<
EF
,
ignoreDF
>
;
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
none
(
DF
)
->
none
<
abortEF
,
DF
>
;
none
(
DF
)
->
none
<
abortEF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
none
(
EF
,
DF
)
->
none
<
EF
,
DF
>
;
none
(
EF
,
DF
)
->
none
<
EF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
)
none
(
Data
)
->
none
<
Data
,
passDEF
,
passDDF
>
;
none
(
Data
)
->
none
<
Data
,
passDEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
none
(
Data
,
DEF
)
->
none
<
Data
,
DEF
,
passDDF
>
;
none
(
Data
,
DEF
)
->
none
<
Data
,
DEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
none
(
Data
,
DDF
)
->
none
<
Data
,
passDEF
,
DDF
>
;
none
(
Data
,
DDF
)
->
none
<
Data
,
passDEF
,
DDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
none
(
Data
,
DEF
,
DDF
)
->
none
<
Data
,
DEF
,
DDF
>
;
none
(
Data
,
DEF
,
DDF
)
->
none
<
Data
,
DEF
,
DDF
>
;
#endif
#endif
...
@@ -6092,21 +6199,8 @@ class deferred<detail::erase_deferred_t, E> {
...
@@ -6092,21 +6199,8 @@ class deferred<detail::erase_deferred_t, E> {
void
(
*
submit_
)(
data
&
,
any_none
<
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
any_none
<
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
deferred
(
Wrapped
obj
,
std
::
false_type
)
:
deferred
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_none
<>>
;
deferred
()
=
default
;
deferred
(
deferred
&&
that
)
noexcept
:
deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
any_none
<
E
>
,
is_none
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
deferred
(
Wrapped
obj
)
:
deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6121,10 +6215,8 @@ class deferred<detail::erase_deferred_t, E> {
...
@@ -6121,10 +6215,8 @@ class deferred<detail::erase_deferred_t, E> {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
any_none
<
E
>
,
is_none
<>>
deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
deferred
()
{
&&
insitu
<
Wrapped
>
())
explicit
deferred
(
Wrapped
obj
)
noexcept
:
deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6141,6 +6233,21 @@ class deferred<detail::erase_deferred_t, E> {
...
@@ -6141,6 +6233,21 @@ class deferred<detail::erase_deferred_t, E> {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_none
<>>
;
deferred
()
=
default
;
deferred
(
deferred
&&
that
)
noexcept
:
deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
any_none
<
E
>
,
is_none
<>>
)
explicit
deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
deferred
()
{
~
deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -6271,7 +6378,7 @@ class single<V, E> {
...
@@ -6271,7 +6378,7 @@ class single<V, E> {
char
buffer_
[
sizeof
(
std
::
promise
<
int
>
)];
// can hold a std::promise in-situ
char
buffer_
[
sizeof
(
std
::
promise
<
int
>
)];
// can hold a std::promise in-situ
}
data_
{};
}
data_
{};
template
<
class
Wrapped
>
template
<
class
Wrapped
>
static
constexpr
bool
insitu
()
{
static
constexpr
bool
insitu
()
noexcept
{
return
sizeof
(
Wrapped
)
<=
sizeof
(
data
::
buffer_
)
&&
return
sizeof
(
Wrapped
)
<=
sizeof
(
data
::
buffer_
)
&&
std
::
is_nothrow_move_constructible
<
Wrapped
>::
value
;
std
::
is_nothrow_move_constructible
<
Wrapped
>::
value
;
}
}
...
@@ -6300,19 +6407,8 @@ class single<V, E> {
...
@@ -6300,19 +6407,8 @@ class single<V, E> {
static_assert
(
NothrowInvocable
<
decltype
(
::
pushmi
::
set_error
),
Wrapped
,
E
>
,
static_assert
(
NothrowInvocable
<
decltype
(
::
pushmi
::
set_error
),
Wrapped
,
E
>
,
"Wrapped single must support E and be noexcept"
);
"Wrapped single must support E and be noexcept"
);
}
}
public:
template
<
class
Wrapped
>
using
properties
=
property_set
<
is_receiver
<>
,
is_single
<>>
;
single
(
Wrapped
obj
,
std
::
false_type
)
:
single
()
{
single
()
=
default
;
single
(
single
&&
that
)
noexcept
:
single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SingleReceiver
<
wrapped_t
<
Wrapped
>
,
V
,
E
>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
single
(
Wrapped
obj
)
:
single
()
{
check
<
Wrapped
>
();
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6336,10 +6432,8 @@ public:
...
@@ -6336,10 +6432,8 @@ public:
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
SingleReceiver
<
wrapped_t
<
Wrapped
>
,
V
,
E
>
&&
insitu
<
Wrapped
>
())
single
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
single
()
{
explicit
single
(
Wrapped
obj
)
noexcept
:
single
()
{
check
<
Wrapped
>
();
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6366,6 +6460,20 @@ public:
...
@@ -6366,6 +6460,20 @@ public:
new
((
void
*
)
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
((
void
*
)
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_single
<>>
;
single
()
=
default
;
single
(
single
&&
that
)
noexcept
:
single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SingleReceiver
<
wrapped_t
<
Wrapped
>
,
V
,
E
>
)
explicit
single
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
single
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{
check
<
Wrapped
>
();
}
~
single
()
{
~
single
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -6535,7 +6643,7 @@ inline auto make_single() -> single<> {
...
@@ -6535,7 +6643,7 @@ inline auto make_single() -> single<> {
return
{};
return
{};
}
}
PUSHMI_TEMPLATE
(
class
VF
)
PUSHMI_TEMPLATE
(
class
VF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
VF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
VF
&>
))
auto
make_single
(
VF
vf
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
{
auto
make_single
(
VF
vf
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
{
return
single
<
VF
,
abortEF
,
ignoreDF
>
{
std
::
move
(
vf
)};
return
single
<
VF
,
abortEF
,
ignoreDF
>
{
std
::
move
(
vf
)};
}
}
...
@@ -6544,58 +6652,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...>
...
@@ -6544,58 +6652,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...>
return
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
{
std
::
move
(
ef
)};
return
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
{
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
auto
make_single
(
DF
df
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
{
auto
make_single
(
DF
df
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
{
return
single
<
ignoreVF
,
abortEF
,
DF
>
{
std
::
move
(
df
)};
return
single
<
ignoreVF
,
abortEF
,
DF
>
{
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
EF
&>
))
auto
make_single
(
VF
vf
,
EF
ef
)
->
single
<
VF
,
EF
,
ignoreDF
>
{
auto
make_single
(
VF
vf
,
EF
ef
)
->
single
<
VF
,
EF
,
ignoreDF
>
{
return
{
std
::
move
(
vf
),
std
::
move
(
ef
)};
return
{
std
::
move
(
vf
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
auto
make_single
(
EF
ef
,
DF
df
)
->
single
<
ignoreVF
,
EF
,
DF
>
{
auto
make_single
(
EF
ef
,
DF
df
)
->
single
<
ignoreVF
,
EF
,
DF
>
{
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
VF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
VF
>
))
auto
make_single
(
VF
vf
,
EF
ef
,
DF
df
)
->
single
<
VF
,
EF
,
DF
>
{
auto
make_single
(
VF
vf
,
EF
ef
,
DF
df
)
->
single
<
VF
,
EF
,
DF
>
{
return
{
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
auto
make_single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
auto
make_single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
return
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
return
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DVF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DVF
&
,
Data
&>
))
auto
make_single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
{
auto
make_single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
vf
)};
return
{
std
::
move
(
d
),
std
::
move
(
vf
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
auto
make_single
(
Data
d
,
on_error_fn
<
DEFN
...
>
ef
)
->
auto
make_single
(
Data
d
,
on_error_fn
<
DEFN
...
>
ef
)
->
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
{
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_single
(
Data
d
,
DDF
df
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
{
auto
make_single
(
Data
d
,
DDF
df
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
{
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
)};
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_single
(
Data
d
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
{
auto
make_single
(
Data
d
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
{
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
...
@@ -6606,55 +6714,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>
...
@@ -6606,55 +6714,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>
single
()
->
single
<>
;
single
()
->
single
<>
;
PUSHMI_TEMPLATE
(
class
VF
)
PUSHMI_TEMPLATE
(
class
VF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
VF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
VF
&>
))
single
(
VF
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
;
single
(
VF
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
;
template
<
class
...
EFN
>
template
<
class
...
EFN
>
single
(
on_error_fn
<
EFN
...
>
)
->
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
;
single
(
on_error_fn
<
EFN
...
>
)
->
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
;
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
single
(
DF
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
;
single
(
DF
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
EF
&>
))
single
(
VF
,
EF
)
->
single
<
VF
,
EF
,
ignoreDF
>
;
single
(
VF
,
EF
)
->
single
<
VF
,
EF
,
ignoreDF
>
;
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
single
(
EF
,
DF
)
->
single
<
ignoreVF
,
EF
,
DF
>
;
single
(
EF
,
DF
)
->
single
<
ignoreVF
,
EF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
VF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
VF
>
))
single
(
VF
,
EF
,
DF
)
->
single
<
VF
,
EF
,
DF
>
;
single
(
VF
,
EF
,
DF
)
->
single
<
VF
,
EF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
;
single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DVF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DVF
&
,
Data
&>
))
single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
;
single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
single
(
Data
d
,
on_error_fn
<
DEFN
...
>
)
->
single
(
Data
d
,
on_error_fn
<
DEFN
...
>
)
->
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
;
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
single
(
Data
d
,
DDF
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
;
single
(
Data
d
,
DDF
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
;
single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
single
(
Data
d
,
DEF
,
DDF
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
;
single
(
Data
d
,
DEF
,
DDF
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
;
single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
;
#endif
#endif
...
@@ -6713,22 +6821,8 @@ class any_single_deferred {
...
@@ -6713,22 +6821,8 @@ class any_single_deferred {
void
(
*
submit_
)(
data
&
,
single
<
V
,
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
single
<
V
,
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
any_single_deferred
(
Wrapped
obj
,
std
::
false_type
)
:
any_single_deferred
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_single
<>>
;
any_single_deferred
()
=
default
;
any_single_deferred
(
any_single_deferred
&&
that
)
noexcept
:
any_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
any_single_deferred
(
Wrapped
obj
)
:
any_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6743,10 +6837,9 @@ class any_single_deferred {
...
@@ -6743,10 +6837,9 @@ class any_single_deferred {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>
,
is_single
<>>
any_single_deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
&&
insitu
<
Wrapped
>
())
:
any_single_deferred
()
{
explicit
any_single_deferred
(
Wrapped
obj
)
noexcept
:
any_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6763,6 +6856,23 @@ class any_single_deferred {
...
@@ -6763,6 +6856,23 @@ class any_single_deferred {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_single
<>>
;
any_single_deferred
()
=
default
;
any_single_deferred
(
any_single_deferred
&&
that
)
noexcept
:
any_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>
,
is_single
<>>
)
explicit
any_single_deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
any_single_deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
any_single_deferred
()
{
~
any_single_deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -6793,7 +6903,7 @@ class single_deferred<SF> {
...
@@ -6793,7 +6903,7 @@ class single_deferred<SF> {
:
sf_
(
std
::
move
(
sf
))
{}
:
sf_
(
std
::
move
(
sf
))
{}
PUSHMI_TEMPLATE
(
class
Out
)
PUSHMI_TEMPLATE
(
class
Out
)
(
requires
lazy
::
Receiver
<
Out
,
is_single
<>>
&&
lazy
::
Invocable
<
SF
&
,
Out
>
)
(
requires
defer
::
Receiver
<
Out
,
is_single
<>>
&&
defer
::
Invocable
<
SF
&
,
Out
>
)
void
submit
(
Out
out
)
{
void
submit
(
Out
out
)
{
sf_
(
std
::
move
(
out
));
sf_
(
std
::
move
(
out
));
}
}
...
@@ -6814,7 +6924,8 @@ class single_deferred_2 {
...
@@ -6814,7 +6924,8 @@ class single_deferred_2 {
constexpr
single_deferred_2
(
Data
data
,
DSF
sf
)
constexpr
single_deferred_2
(
Data
data
,
DSF
sf
)
:
data_
(
std
::
move
(
data
)),
sf_
(
std
::
move
(
sf
))
{}
:
data_
(
std
::
move
(
data
)),
sf_
(
std
::
move
(
sf
))
{}
PUSHMI_TEMPLATE
(
class
Out
)
PUSHMI_TEMPLATE
(
class
Out
)
(
requires
lazy
::
Receiver
<
Out
,
is_single
<>>
&&
lazy
::
Invocable
<
DSF
&
,
Data
&
,
Out
>
)
(
requires
defer
::
Receiver
<
Out
,
is_single
<>>
&&
defer
::
Invocable
<
DSF
&
,
Data
&
,
Out
>
)
void
submit
(
Out
out
)
{
void
submit
(
Out
out
)
{
sf_
(
data_
,
std
::
move
(
out
));
sf_
(
data_
,
std
::
move
(
out
));
}
}
...
@@ -6823,7 +6934,7 @@ class single_deferred_2 {
...
@@ -6823,7 +6934,7 @@ class single_deferred_2 {
template
<
class
A
,
class
B
>
template
<
class
A
,
class
B
>
using
single_deferred_base
=
using
single_deferred_base
=
meta
::
if_c
<
meta
::
if_c
<
Sender
<
A
,
is_single
<>>
,
(
bool
)
Sender
<
A
,
is_single
<>>
,
single_deferred_2
<
A
,
B
>
,
single_deferred_2
<
A
,
B
>
,
any_single_deferred
<
A
,
B
>>
;
any_single_deferred
<
A
,
B
>>
;
}
// namespace detail
}
// namespace detail
...
@@ -6916,23 +7027,9 @@ class any_time_single_deferred {
...
@@ -6916,23 +7027,9 @@ class any_time_single_deferred {
void
(
*
submit_
)(
data
&
,
TP
,
single
<
V
,
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
TP
,
single
<
V
,
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
=
{};
static
constexpr
vtable
const
noop_
=
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
any_time_single_deferred
(
Wrapped
obj
,
std
::
false_type
)
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_time_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_time
<>
,
is_single
<>>
;
any_time_single_deferred
()
=
default
;
any_time_single_deferred
(
any_time_single_deferred
&&
that
)
noexcept
:
any_time_single_deferred
()
{
:
any_time_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
TimeSenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
any_time_single_deferred
(
Wrapped
obj
)
:
any_time_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6953,10 +7050,9 @@ class any_time_single_deferred {
...
@@ -6953,10 +7050,9 @@ class any_time_single_deferred {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
TimeSenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>>
&&
any_time_single_deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
insitu
<
Wrapped
>
())
:
any_time_single_deferred
()
{
explicit
any_time_single_deferred
(
Wrapped
obj
)
noexcept
:
any_time_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -6978,6 +7074,24 @@ class any_time_single_deferred {
...
@@ -6978,6 +7074,24 @@ class any_time_single_deferred {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_time_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_time
<>
,
is_single
<>>
;
any_time_single_deferred
()
=
default
;
any_time_single_deferred
(
any_time_single_deferred
&&
that
)
noexcept
:
any_time_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
TimeSenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>>
)
explicit
any_time_single_deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
any_time_single_deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{
}
~
any_time_single_deferred
()
{
~
any_time_single_deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -7058,7 +7172,7 @@ class time_single_deferred_2 {
...
@@ -7058,7 +7172,7 @@ class time_single_deferred_2 {
template
<
class
A
,
class
B
,
class
C
>
template
<
class
A
,
class
B
,
class
C
>
using
time_single_deferred_base
=
using
time_single_deferred_base
=
meta
::
if_c
<
meta
::
if_c
<
TimeSender
<
A
,
is_single
<>>
,
(
bool
)
TimeSender
<
A
,
is_single
<>>
,
time_single_deferred_2
<
A
,
B
,
C
>
,
time_single_deferred_2
<
A
,
B
,
C
>
,
any_time_single_deferred
<
A
,
B
,
C
>>
;
any_time_single_deferred
<
A
,
B
,
C
>>
;
}
// namespace detail
}
// namespace detail
...
@@ -7318,21 +7432,8 @@ class flow_single<V, PE, E> {
...
@@ -7318,21 +7432,8 @@ class flow_single<V, PE, E> {
void
(
*
starting_
)(
data
&
,
any_none
<
PE
>&
)
=
s_starting
;
void
(
*
starting_
)(
data
&
,
any_none
<
PE
>&
)
=
s_starting
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
flow_single
(
Wrapped
obj
,
std
::
false_type
)
:
flow_single
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single
()
=
default
;
flow_single
(
flow_single
&&
that
)
noexcept
:
flow_single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSingleReceiver
<
wrapped_t
<
Wrapped
>
,
any_none
<
PE
>
,
V
,
PE
,
E
>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
flow_single
(
Wrapped
obj
)
:
flow_single
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -7359,10 +7460,8 @@ public:
...
@@ -7359,10 +7460,8 @@ public:
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
FlowSingleReceiver
<
wrapped_t
<
Wrapped
>
,
any_none
<
PE
>
,
V
,
PE
,
E
>
flow_single
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
flow_single
()
{
&&
insitu
<
Wrapped
>
())
explicit
flow_single
(
Wrapped
obj
)
noexcept
:
flow_single
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -7392,6 +7491,21 @@ public:
...
@@ -7392,6 +7491,21 @@ public:
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single
()
=
default
;
flow_single
(
flow_single
&&
that
)
noexcept
:
flow_single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSingleReceiver
<
wrapped_t
<
Wrapped
>
,
any_none
<
PE
>
,
V
,
PE
,
E
>
)
explicit
flow_single
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
flow_single
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
flow_single
()
{
~
flow_single
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -7884,22 +7998,8 @@ class flow_single_deferred<V, PE, E> {
...
@@ -7884,22 +7998,8 @@ class flow_single_deferred<V, PE, E> {
void
(
*
submit_
)(
data
&
,
flow_single
<
V
,
PE
,
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
flow_single
<
V
,
PE
,
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
flow_single_deferred
(
Wrapped
obj
,
std
::
false_type
)
:
flow_single_deferred
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single_deferred
()
=
default
;
flow_single_deferred
(
flow_single_deferred
&&
that
)
noexcept
:
flow_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSender
<
wrapped_t
<
Wrapped
>
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
flow_single_deferred
(
Wrapped
obj
)
:
flow_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -7914,9 +8014,9 @@ class flow_single_deferred<V, PE, E> {
...
@@ -7914,9 +8014,9 @@ class flow_single_deferred<V, PE, E> {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
FlowSender
<
wrapped_t
<
Wrapped
>
,
is_single
<>>
&&
insitu
<
Wrapped
>
())
flow_single_deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
explicit
flow_single_deferred
(
Wrapped
obj
)
noexcept
:
flow_single_deferred
()
{
:
flow_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -7934,6 +8034,22 @@ class flow_single_deferred<V, PE, E> {
...
@@ -7934,6 +8034,22 @@ class flow_single_deferred<V, PE, E> {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single_deferred
()
=
default
;
flow_single_deferred
(
flow_single_deferred
&&
that
)
noexcept
:
flow_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSender
<
wrapped_t
<
Wrapped
>
,
is_single
<>>
)
explicit
flow_single_deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
flow_single_deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
flow_single_deferred
()
{
~
flow_single_deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -8981,6 +9097,7 @@ auto just(V v) {
...
@@ -8981,6 +9097,7 @@ auto just(V v) {
// LICENSE file in the root directory of this source tree.
// LICENSE file in the root directory of this source tree.
//#include "../single.h"
//#include "../single.h"
//#include "../single_deferred.h"
//#include "submit.h"
//#include "submit.h"
//#include "extension_operators.h"
//#include "extension_operators.h"
...
...
folly/experimental/pushmi/include/pushmi/concepts.h
View file @
2690ee57
...
@@ -350,9 +350,9 @@ PUSHMI_CONCEPT_DEF(
...
@@ -350,9 +350,9 @@ PUSHMI_CONCEPT_DEF(
);
);
template
<
class
D
>
template
<
class
D
>
using
time_point_t
=
PUSHMI_PP_CONSTRAINED_USING
(
std
::
enable_if_t
<
TimeSender
<
D
>
,
decltype
(
::
pushmi
::
now
(
std
::
declval
<
D
&>
()))
>
;
TimeSender
<
D
>
,
time_point_t
=
,
decltype
(
::
pushmi
::
now
(
std
::
declval
<
D
&>
())));
// this is a more general form where the constraint could be time or priority
// this is a more general form where the constraint could be time or priority
// enum or any other ordering constraint value-type.
// enum or any other ordering constraint value-type.
...
@@ -386,9 +386,8 @@ PUSHMI_CONCEPT_DEF(
...
@@ -386,9 +386,8 @@ PUSHMI_CONCEPT_DEF(
);
);
template
<
class
D
>
template
<
class
D
>
using
constraint_t
=
PUSHMI_PP_CONSTRAINED_USING
(
std
::
enable_if_t
<
ConstrainedSender
<
D
>
,
ConstrainedSender
<
D
>
,
decltype
(
::
pushmi
::
top
(
std
::
declval
<
D
&>
()))
>
;
constraint_t
=
,
decltype
(
::
pushmi
::
top
(
std
::
declval
<
D
&>
())))
;
}
// namespace pushmi
}
// namespace pushmi
folly/experimental/pushmi/include/pushmi/deferred.h
View file @
2690ee57
...
@@ -29,21 +29,8 @@ class deferred<detail::erase_deferred_t, E> {
...
@@ -29,21 +29,8 @@ class deferred<detail::erase_deferred_t, E> {
void
(
*
submit_
)(
data
&
,
any_none
<
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
any_none
<
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
deferred
(
Wrapped
obj
,
std
::
false_type
)
:
deferred
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_none
<>>
;
deferred
()
=
default
;
deferred
(
deferred
&&
that
)
noexcept
:
deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
any_none
<
E
>
,
is_none
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
deferred
(
Wrapped
obj
)
:
deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -58,10 +45,8 @@ class deferred<detail::erase_deferred_t, E> {
...
@@ -58,10 +45,8 @@ class deferred<detail::erase_deferred_t, E> {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
any_none
<
E
>
,
is_none
<>>
deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
deferred
()
{
&&
insitu
<
Wrapped
>
())
explicit
deferred
(
Wrapped
obj
)
noexcept
:
deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -78,6 +63,21 @@ class deferred<detail::erase_deferred_t, E> {
...
@@ -78,6 +63,21 @@ class deferred<detail::erase_deferred_t, E> {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_none
<>>
;
deferred
()
=
default
;
deferred
(
deferred
&&
that
)
noexcept
:
deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
any_none
<
E
>
,
is_none
<>>
)
explicit
deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
deferred
()
{
~
deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
...
folly/experimental/pushmi/include/pushmi/detail/concept_def.h
View file @
2690ee57
...
@@ -185,33 +185,32 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -185,33 +185,32 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// t = (U &&) u,
// t = (U &&) u,
// ::pushmi::concepts::requires_<Same<decltype(t = (U &&) u), T>>
// ::pushmi::concepts::requires_<Same<decltype(t = (U &&) u), T>>
// ) &&
// ) &&
// std::is_lvalue_reference
<T>{}
// std::is_lvalue_reference
_v<T>
// );
// );
#define PUSHMI_CONCEPT_DEF(DECL, ...) \
#define PUSHMI_CONCEPT_DEF(DECL, ...) \
PUSHMI_PP_EVAL( \
PUSHMI_PP_EVAL( \
PUSHMI_PP_DECL_DEF, \
PUSHMI_PP_DECL_DEF, \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_DECL_, DECL), \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_DECL_, DECL), \
__VA_ARGS__) \
/**/
#define PUSHMI_PP_DECL_DEF_NAME(...) \
__VA_ARGS__, \
__VA_ARGS__, \
PUSHMI_PP_EAT) \
/**/
/**/
#define PUSHMI_PP_DECL_DEF_NAME(...) __VA_ARGS__,
#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, ...) \
#define PUSHMI_PP_DECL_DEF(TPARAM, NAME, REQUIRES, ...) \
PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \
PUSHMI_PP_CAT(PUSHMI_PP_DECL_DEF_, PUSHMI_PP_IS_PAREN(NAME))( \
TPARAM, \
TPARAM, \
NAME, \
NAME, \
REQUIRES, \
__VA_ARGS__) \
__VA_ARGS__) \
/**/
/**/
// The defn is of the form:
// The defn is of the form:
// template(class A, class B = void, class... Rest)
// template(class A, class B = void, class... Rest)
// (concept Name)(A, B, Rest...),
// (concept Name)(A, B, Rest...),
// // requirements...
// // requirements...
#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME,
REQUIRES, ...)
\
#define PUSHMI_PP_DECL_DEF_1(TPARAM, NAME,
...)
\
PUSHMI_PP_EVAL4( \
PUSHMI_PP_EVAL4( \
PUSHMI_PP_DECL_DEF_IMPL, \
PUSHMI_PP_DECL_DEF_IMPL, \
TPARAM, \
TPARAM, \
PUSHMI_PP_DECL_DEF_NAME NAME, \
PUSHMI_PP_DECL_DEF_NAME NAME, \
REQUIRES, \
__VA_ARGS__) \
__VA_ARGS__) \
/**/
/**/
// The defn is of the form:
// The defn is of the form:
...
@@ -219,12 +218,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -219,12 +218,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// concept Name,
// concept Name,
// // requirements...
// // requirements...
// Compute the template arguments (A, B) from the template introducer.
// Compute the template arguments (A, B) from the template introducer.
#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME,
REQUIRES, ...)
\
#define PUSHMI_PP_DECL_DEF_0(TPARAM, NAME,
...)
\
PUSHMI_PP_DECL_DEF_IMPL( \
PUSHMI_PP_DECL_DEF_IMPL( \
TPARAM, \
TPARAM, \
NAME, \
NAME, \
(PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \
(PUSHMI_PP_CAT(PUSHMI_PP_AUX_, TPARAM)), \
REQUIRES, \
__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:
...
@@ -240,17 +238,83 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -240,17 +238,83 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
// };
// };
// template<class A, class B>
// template<class A, class B>
// inline constexpr bool Name = NameConcept::is_satisfied_by<A, B>(0);
// inline constexpr bool Name = NameConcept::is_satisfied_by<A, B>(0);
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, REQUIRES, ...) \
#if __cpp_concepts
// No requires expression
#define PUSHMI_PP_DEF_IMPL_0(...) \
__VA_ARGS__ \
/**/
// Requires expression
#define PUSHMI_PP_DEF_IMPL_1(...) \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__) \
/**/
#define PUSHMI_PP_DEF_IMPL_1_requires \
requires PUSHMI_PP_DEF_IMPL_1_REQUIRES \
/**/
#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...) \
(__VA_ARGS__) PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY \
/**/
#define PUSHMI_PP_DEF_IMPL_1_REQUIRES_BODY(...) \
{ __VA_ARGS__; } \
/**/
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
inline namespace pushmi_concept_eager { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
concept bool PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = PUSHMI_PP_EVAL2( \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
__VA_ARGS__); \
} \
namespace defer = pushmi_concept_eager; \
namespace lazy { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
struct PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \
using Concept = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept); \
explicit constexpr operator bool() const noexcept { \
return (bool) defer::PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME)< \
PUSHMI_PP_EXPAND ARGS>; \
} \
constexpr auto operator!() const noexcept { \
return ::pushmi::concepts::detail::Not<Concept>{}; \
} \
template <class That> \
constexpr auto operator&&(That) const noexcept { \
return ::pushmi::concepts::detail::And<Concept, That>{}; \
} \
}; \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr auto PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME) = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \
<PUSHMI_PP_EXPAND ARGS>{}; \
} \
/**/
#else
// No requires expression:
#define PUSHMI_PP_DEF_IMPL_0(...) \
() -> std::enable_if_t<bool(__VA_ARGS__), int> \
/**/
// Requires expression:
#define PUSHMI_PP_DEF_IMPL_1(...) \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_IMPL_1_, __VA_ARGS__) ), int> \
/**/
#define PUSHMI_PP_DEF_IMPL_1_requires \
PUSHMI_PP_DEF_IMPL_1_REQUIRES \
/**/
#define PUSHMI_PP_DEF_IMPL_1_REQUIRES(...) \
(__VA_ARGS__) -> std::enable_if_t<bool( \
::pushmi::concepts::detail::requires_ PUSHMI_PP_DEF_REQUIRES_BODY \
/**/
#define PUSHMI_PP_DEF_REQUIRES_BODY(...) \
<decltype(__VA_ARGS__, void())>() \
/**/
#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(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) { \
using Concept = \
using Concept = \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, 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 _concept_requires_ PUSHMI_PP_EVAL2( \
PUSHMI_PP_DEF_WRAP, \
PUSHMI_PP_DEF_IMPL(__VA_ARGS__), \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, REQUIRES), \
__VA_ARGS__); \
REQUIRES, \
(__VA_ARGS__))(~) int>; \
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 _is_satisfied_by_ { \
...
@@ -282,8 +346,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -282,8 +346,18 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \
PUSHMI_PP_CAT(PUSHMI_PP_CAT(PUSHMI_PP_DEF_, NAME), Concept) \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
::_is_satisfied_by_<PUSHMI_PP_EXPAND ARGS>{}; \
} \
} \
namespace defer = lazy; \
/**/
/**/
#endif
#define PUSHMI_PP_REQUIRES_PROBE_requires \
PUSHMI_PP_PROBE(~) \
/**/
#define PUSHMI_PP_DEF_IMPL(REQUIRES, ...) \
PUSHMI_PP_CAT( \
PUSHMI_PP_DEF_IMPL_, \
PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES))) \
/**/
#define PUSHMI_PP_DEF_DECL_template(...) \
#define PUSHMI_PP_DEF_DECL_template(...) \
template(__VA_ARGS__), \
template(__VA_ARGS__), \
/**/
/**/
...
@@ -297,7 +371,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -297,7 +371,6 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_DEF_bool
#define PUSHMI_PP_DEF_bool
#define PUSHMI_PP_DEF_size_t
#define PUSHMI_PP_DEF_size_t
#define PUSHMI_PP_DEF_unsigned
#define PUSHMI_PP_DEF_unsigned
#define PUSHMI_PP_DEF_requires ~,
#define PUSHMI_PP_AUX_template(...) \
#define PUSHMI_PP_AUX_template(...) \
PUSHMI_PP_CAT2( \
PUSHMI_PP_CAT2( \
PUSHMI_PP_TPARAM_, \
PUSHMI_PP_TPARAM_, \
...
@@ -314,63 +387,95 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
...
@@ -314,63 +387,95 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_TPARAM_5(_1, ...) \
#define PUSHMI_PP_TPARAM_5(_1, ...) \
PUSHMI_PP_CAT2(PUSHMI_PP_DEF_, _1), PUSHMI_PP_TPARAM_4(__VA_ARGS__)
PUSHMI_PP_CAT2(PUSHMI_PP_DEF_, _1), PUSHMI_PP_TPARAM_4(__VA_ARGS__)
#define PUSHMI_PP_DEF_WRAP(X, Y, ...) \
////////////////////////////////////////////////////////////////////////////////
PUSHMI_PP_EVAL3( \
// PUSHMI_TEMPLATE
PUSHMI_PP_CAT(PUSHMI_PP_DEF_WRAP_, PUSHMI_PP_COUNT(__VA_ARGS__)), \
// Usage:
X, \
// PUSHMI_TEMPLATE (class A, class B)
Y, \
// (requires Concept1<A> && Concept2<B>)
__VA_ARGS__) \
// void foo(A a, B b)
// {}
// or
// PUSHMI_TEMPLATE (class A, class B)
// (requires requires (expr1, expr2, expr3) && Concept1<A> && Concept2<B>)
// void foo(A a, B b)
// {}
#if __cpp_concepts
#define PUSHMI_TEMPLATE(...) \
template<__VA_ARGS__> PUSHMI_TEMPLATE_AUX_ \
/**/
/**/
#define PUSHMI_TEMPLATE_AUX_(...) \
// No requires expression:
PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__)) \
#define PUSHMI_PP_DEF_WRAP_1(_, HEAD, TAIL) \
() -> std::enable_if_t<HEAD, PUSHMI_PP_EXPAND TAIL \
/**/
/**/
// Requires expression:
#define PUSHMI_TEMPLATE_AUX_3_requires
#define PUSHMI_PP_DEF_WRAP_2(_a, HEAD, _b, TAIL) \
#define PUSHMI_TEMPLATE_AUX_4(...) \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_REQUIRES_, PUSHMI_PP_IS_PAREN(HEAD)) HEAD, \
PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__) \
PUSHMI_PP_EXPAND TAIL \
/**/
/**/
// Requires expression without a requirement parameter list:
#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...) \
#define PUSHMI_PP_DEF_REQUIRES_0
\
PUSHMI_PP_CAT(
\
() -> decltype(::pushmi::concepts::detail::requires_
\
PUSHMI_TEMPLATE_AUX_5_,
\
PUSHMI_PP_
DEF_REQUIRES_EXPRS
\
PUSHMI_PP_
CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES)))
\
/**/
/**/
// Requires expression with a requirement parameter list:
// No requires expression:
#define PUSHMI_PP_DEF_REQUIRES_1(...) \
#define PUSHMI_TEMPLATE_AUX_5_0(...) \
(__VA_ARGS__) -> std::enable_if_t<::pushmi::concepts::detail::requires_ \
requires __VA_ARGS__ \
PUSHMI_PP_DEF_REQUIRES_EXPRS \
/**/
/**/
// Requires expression
#define
PUSHMI_PP_DEF_REQUIRES_EXPRS(...)
\
#define
PUSHMI_TEMPLATE_AUX_5_1(...)
\
<decltype(__VA_ARGS__, void())>()
\
PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)
\
/**/
/**/
#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
#define PUSHMI_TYPE_CONSTRAINT(X) class
requires requires { __VA_ARGS__; }
#else
#define PUSHMI_TEMPLATE(...) \
#define PUSHMI_TEMPLATE(...) \
template<__VA_ARGS__ PUSHMI_TEMPLATE_AUX_
template<__VA_ARGS__ PUSHMI_TEMPLATE_AUX_
#define PUSHMI_TEMPLATE_AUX_(...) , \
#define PUSHMI_TEMPLATE_AUX_(...) , \
int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[PUSHMI_COUNTER] = nullptr, \
int (*PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__))[ \
PUSHMI_COUNTER] = nullptr, \
std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) || \
std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) || \
bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0>
bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT( \
PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0> \
/**/
#define PUSHMI_TEMPLATE_AUX_3_requires
#define PUSHMI_TEMPLATE_AUX_3_requires
#define PUSHMI_TEMPLATE_AUX_4(...) \
#define PUSHMI_TEMPLATE_AUX_4(...) \
PUSHMI_PP_EVAL(\
PUSHMI_TEMPLATE_AUX_5(__VA_ARGS__)(__VA_ARGS__) \
PUSHMI_PP_CAT,\
/**/
#define PUSHMI_TEMPLATE_AUX_5(REQUIRES, ...) \
PUSHMI_PP_CAT( \
PUSHMI_TEMPLATE_AUX_5_, \
PUSHMI_TEMPLATE_AUX_5_, \
PUSHMI_PP_IS_EQUAL(\
PUSHMI_PP_CHECK(PUSHMI_PP_CAT(PUSHMI_PP_REQUIRES_PROBE_, REQUIRES))) \
PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, PUSHMI_PP_CAT2(PUSHMI_TEMPLATE_AUX_5_, __VA_ARGS__)),\
/**/
PUSHMI_PP_EVAL2(PUSHMI_PP_COUNT, __VA_ARGS__)))(__VA_ARGS__)
// No requires expression:
#define PUSHMI_TEMPLATE_AUX_5_requires ~,
#define PUSHMI_TEMPLATE_AUX_5_0(...) \
#define PUSHMI_TEMPLATE_AUX_5_0(...) \
PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__)
__VA_ARGS__ \
/**/
#define PUSHMI_TEMPLATE_AUX_5_1(...) \
#define PUSHMI_TEMPLATE_AUX_5_1(...) \
__VA_ARGS__
PUSHMI_PP_CAT(PUSHMI_TEMPLATE_AUX_6_, __VA_ARGS__) \
#define PUSHMI_TEMPLATE_AUX_6_requires(...)\
/**/
::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>()
#define PUSHMI_TEMPLATE_AUX_6_requires(...) \
::pushmi::concepts::detail::requires_<decltype(__VA_ARGS__)>() \
/**/
#endif
#if __cpp_concepts
#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__ // BUGBUG
#define PUSHMI_TYPE_CONSTRAINT(...) __VA_ARGS__
#else
#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__
#define PUSHMI_BROKEN_SUBSUMPTION(...) __VA_ARGS__
#define PUSHMI_TYPE_CONSTRAINT(...) class
#endif
#if __cpp_concepts
#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE) \
requires REQUIRES \
using NAME TYPE; \
/**/
#else
#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, TYPE) \
using NAME std::enable_if_t<bool(REQUIRES), TYPE>; \
/**/
#endif
namespace
pushmi
{
namespace
pushmi
{
namespace
concepts
{
namespace
concepts
{
...
...
folly/experimental/pushmi/include/pushmi/flow_single.h
View file @
2690ee57
...
@@ -34,21 +34,8 @@ class flow_single<V, PE, E> {
...
@@ -34,21 +34,8 @@ class flow_single<V, PE, E> {
void
(
*
starting_
)(
data
&
,
any_none
<
PE
>&
)
=
s_starting
;
void
(
*
starting_
)(
data
&
,
any_none
<
PE
>&
)
=
s_starting
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
flow_single
(
Wrapped
obj
,
std
::
false_type
)
:
flow_single
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single
()
=
default
;
flow_single
(
flow_single
&&
that
)
noexcept
:
flow_single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSingleReceiver
<
wrapped_t
<
Wrapped
>
,
any_none
<
PE
>
,
V
,
PE
,
E
>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
flow_single
(
Wrapped
obj
)
:
flow_single
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -75,10 +62,8 @@ public:
...
@@ -75,10 +62,8 @@ public:
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
FlowSingleReceiver
<
wrapped_t
<
Wrapped
>
,
any_none
<
PE
>
,
V
,
PE
,
E
>
flow_single
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
flow_single
()
{
&&
insitu
<
Wrapped
>
())
explicit
flow_single
(
Wrapped
obj
)
noexcept
:
flow_single
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -108,6 +93,21 @@ public:
...
@@ -108,6 +93,21 @@ public:
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single
()
=
default
;
flow_single
(
flow_single
&&
that
)
noexcept
:
flow_single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSingleReceiver
<
wrapped_t
<
Wrapped
>
,
any_none
<
PE
>
,
V
,
PE
,
E
>
)
explicit
flow_single
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
flow_single
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
flow_single
()
{
~
flow_single
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
...
folly/experimental/pushmi/include/pushmi/flow_single_deferred.h
View file @
2690ee57
...
@@ -26,22 +26,8 @@ class flow_single_deferred<V, PE, E> {
...
@@ -26,22 +26,8 @@ class flow_single_deferred<V, PE, E> {
void
(
*
submit_
)(
data
&
,
flow_single
<
V
,
PE
,
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
flow_single
<
V
,
PE
,
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
flow_single_deferred
(
Wrapped
obj
,
std
::
false_type
)
:
flow_single_deferred
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single_deferred
()
=
default
;
flow_single_deferred
(
flow_single_deferred
&&
that
)
noexcept
:
flow_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSender
<
wrapped_t
<
Wrapped
>
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
flow_single_deferred
(
Wrapped
obj
)
:
flow_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -56,9 +42,9 @@ class flow_single_deferred<V, PE, E> {
...
@@ -56,9 +42,9 @@ class flow_single_deferred<V, PE, E> {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
FlowSender
<
wrapped_t
<
Wrapped
>
,
is_single
<>>
&&
insitu
<
Wrapped
>
())
flow_single_deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
explicit
flow_single_deferred
(
Wrapped
obj
)
noexcept
:
flow_single_deferred
()
{
:
flow_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -76,6 +62,22 @@ class flow_single_deferred<V, PE, E> {
...
@@ -76,6 +62,22 @@ class flow_single_deferred<V, PE, E> {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
flow_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_flow
<>
,
is_single
<>>
;
flow_single_deferred
()
=
default
;
flow_single_deferred
(
flow_single_deferred
&&
that
)
noexcept
:
flow_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
FlowSender
<
wrapped_t
<
Wrapped
>
,
is_single
<>>
)
explicit
flow_single_deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
flow_single_deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
flow_single_deferred
()
{
~
flow_single_deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
...
folly/experimental/pushmi/include/pushmi/none.h
View file @
2690ee57
...
@@ -29,21 +29,8 @@ class none<E> {
...
@@ -29,21 +29,8 @@ class none<E> {
void
(
*
error_
)(
data
&
,
E
)
noexcept
=
s_error
;
void
(
*
error_
)(
data
&
,
E
)
noexcept
=
s_error
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
none
(
Wrapped
obj
,
std
::
false_type
)
:
none
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
none
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_none
<>>
;
none
()
=
default
;
none
(
none
&&
that
)
noexcept
:
none
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
NoneReceiver
<
wrapped_t
<
Wrapped
>
,
E
>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
none
(
Wrapped
obj
)
:
none
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -61,9 +48,8 @@ public:
...
@@ -61,9 +48,8 @@ public:
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtable_v
;
vptr_
=
&
vtable_v
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
NoneReceiver
<
wrapped_t
<
Wrapped
>
,
E
>
&&
insitu
<
Wrapped
>
())
none
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
none
()
{
explicit
none
(
Wrapped
obj
)
noexcept
:
none
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -83,6 +69,21 @@ public:
...
@@ -83,6 +69,21 @@ public:
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
none
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_none
<>>
;
none
()
=
default
;
none
(
none
&&
that
)
noexcept
:
none
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
NoneReceiver
<
wrapped_t
<
Wrapped
>
,
E
>
)
explicit
none
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
none
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
none
()
{
~
none
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -196,40 +197,40 @@ inline auto make_none() -> none<> {
...
@@ -196,40 +197,40 @@ inline auto make_none() -> none<> {
return
{};
return
{};
}
}
PUSHMI_TEMPLATE
(
class
EF
)
PUSHMI_TEMPLATE
(
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
EF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
EF
>
&&
not
defer
::
Invocable
<
EF
&>
))
auto
make_none
(
EF
ef
)
->
none
<
EF
,
ignoreDF
>
{
auto
make_none
(
EF
ef
)
->
none
<
EF
,
ignoreDF
>
{
return
none
<
EF
,
ignoreDF
>
{
std
::
move
(
ef
)};
return
none
<
EF
,
ignoreDF
>
{
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
auto
make_none
(
DF
df
)
->
none
<
abortEF
,
DF
>
{
auto
make_none
(
DF
df
)
->
none
<
abortEF
,
DF
>
{
return
none
<
abortEF
,
DF
>
{
std
::
move
(
df
)};
return
none
<
abortEF
,
DF
>
{
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
auto
make_none
(
EF
ef
,
DF
df
)
->
none
<
EF
,
DF
>
{
auto
make_none
(
EF
ef
,
DF
df
)
->
none
<
EF
,
DF
>
{
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
)
auto
make_none
(
Data
d
)
->
none
<
Data
,
passDEF
,
passDDF
>
{
auto
make_none
(
Data
d
)
->
none
<
Data
,
passDEF
,
passDDF
>
{
return
none
<
Data
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
return
none
<
Data
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
auto
make_none
(
Data
d
,
DEF
ef
)
->
none
<
Data
,
DEF
,
passDDF
>
{
auto
make_none
(
Data
d
,
DEF
ef
)
->
none
<
Data
,
DEF
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_none
(
Data
d
,
DDF
df
)
->
none
<
Data
,
passDEF
,
DDF
>
{
auto
make_none
(
Data
d
,
DDF
df
)
->
none
<
Data
,
passDEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_none
(
Data
d
,
DEF
ef
,
DDF
df
)
->
none
<
Data
,
DEF
,
DDF
>
{
auto
make_none
(
Data
d
,
DEF
ef
,
DDF
df
)
->
none
<
Data
,
DEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
...
@@ -240,34 +241,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
...
@@ -240,34 +241,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
none
()
->
none
<>
;
none
()
->
none
<>
;
PUSHMI_TEMPLATE
(
class
EF
)
PUSHMI_TEMPLATE
(
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
EF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
EF
>
&&
not
defer
::
Invocable
<
EF
&>
))
none
(
EF
)
->
none
<
EF
,
ignoreDF
>
;
none
(
EF
)
->
none
<
EF
,
ignoreDF
>
;
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
none
(
DF
)
->
none
<
abortEF
,
DF
>
;
none
(
DF
)
->
none
<
abortEF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
none
(
EF
,
DF
)
->
none
<
EF
,
DF
>
;
none
(
EF
,
DF
)
->
none
<
EF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
)
none
(
Data
)
->
none
<
Data
,
passDEF
,
passDDF
>
;
none
(
Data
)
->
none
<
Data
,
passDEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
none
(
Data
,
DEF
)
->
none
<
Data
,
DEF
,
passDDF
>
;
none
(
Data
,
DEF
)
->
none
<
Data
,
DEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
none
(
Data
,
DDF
)
->
none
<
Data
,
passDEF
,
DDF
>
;
none
(
Data
,
DDF
)
->
none
<
Data
,
passDEF
,
DDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_none
<>>
&&
not
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
(
requires
defer
::
Receiver
<
Data
,
is_none
<>>
&&
not
defer
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
defer
::
Invocable
<
DDF
&
,
Data
&>
)
none
(
Data
,
DEF
,
DDF
)
->
none
<
Data
,
DEF
,
DDF
>
;
none
(
Data
,
DEF
,
DDF
)
->
none
<
Data
,
DEF
,
DDF
>
;
#endif
#endif
...
...
folly/experimental/pushmi/include/pushmi/o/defer.h
View file @
2690ee57
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
// LICENSE file in the root directory of this source tree.
// LICENSE file in the root directory of this source tree.
#include "../single.h"
#include "../single.h"
#include "../single_deferred.h"
#include "submit.h"
#include "submit.h"
#include "extension_operators.h"
#include "extension_operators.h"
...
...
folly/experimental/pushmi/include/pushmi/properties.h
View file @
2690ee57
...
@@ -161,14 +161,16 @@ struct property_query_impl :
...
@@ -161,14 +161,16 @@ struct property_query_impl :
meta
::
and_c
<
decltype
(
property_query_fn
<
ExpectedN
>
((
properties_t
<
PS
>*
)
nullptr
))
::
value
...
>
{};
meta
::
and_c
<
decltype
(
property_query_fn
<
ExpectedN
>
((
properties_t
<
PS
>*
)
nullptr
))
::
value
...
>
{};
}
//namespace detail
}
//namespace detail
template
<
PUSHMI_TYPE_CONSTRAINT
(
Properties
)
PS
,
PUSHMI_TYPE_CONSTRAINT
(
Property
)...
ExpectedN
>
//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
template
<
class
PS
,
class
...
ExpectedN
>
struct
property_query
struct
property_query
:
meta
::
if_c
<
:
meta
::
if_c
<
Properties
<
PS
>
&&
And
<
Property
<
ExpectedN
>
...
>
,
Properties
<
PS
>
&&
And
<
Property
<
ExpectedN
>
...
>
,
detail
::
property_query_impl
<
PS
,
ExpectedN
...
>
,
detail
::
property_query_impl
<
PS
,
ExpectedN
...
>
,
std
::
false_type
>
{};
std
::
false_type
>
{};
template
<
PUSHMI_TYPE_CONSTRAINT
(
Properties
)
PS
,
PUSHMI_TYPE_CONSTRAINT
(
Property
)...
ExpectedN
>
//template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
template
<
class
PS
,
class
...
ExpectedN
>
PUSHMI_INLINE_VAR
constexpr
bool
property_query_v
=
property_query
<
PS
,
ExpectedN
...
>::
value
;
PUSHMI_INLINE_VAR
constexpr
bool
property_query_v
=
property_query
<
PS
,
ExpectedN
...
>::
value
;
}
// namespace pushmi
}
// namespace pushmi
folly/experimental/pushmi/include/pushmi/single.h
View file @
2690ee57
...
@@ -17,7 +17,7 @@ class single<V, E> {
...
@@ -17,7 +17,7 @@ class single<V, E> {
char
buffer_
[
sizeof
(
std
::
promise
<
int
>
)];
// can hold a std::promise in-situ
char
buffer_
[
sizeof
(
std
::
promise
<
int
>
)];
// can hold a std::promise in-situ
}
data_
{};
}
data_
{};
template
<
class
Wrapped
>
template
<
class
Wrapped
>
static
constexpr
bool
insitu
()
{
static
constexpr
bool
insitu
()
noexcept
{
return
sizeof
(
Wrapped
)
<=
sizeof
(
data
::
buffer_
)
&&
return
sizeof
(
Wrapped
)
<=
sizeof
(
data
::
buffer_
)
&&
std
::
is_nothrow_move_constructible
<
Wrapped
>::
value
;
std
::
is_nothrow_move_constructible
<
Wrapped
>::
value
;
}
}
...
@@ -46,19 +46,8 @@ class single<V, E> {
...
@@ -46,19 +46,8 @@ class single<V, E> {
static_assert
(
NothrowInvocable
<
decltype
(
::
pushmi
::
set_error
),
Wrapped
,
E
>
,
static_assert
(
NothrowInvocable
<
decltype
(
::
pushmi
::
set_error
),
Wrapped
,
E
>
,
"Wrapped single must support E and be noexcept"
);
"Wrapped single must support E and be noexcept"
);
}
}
public:
template
<
class
Wrapped
>
using
properties
=
property_set
<
is_receiver
<>
,
is_single
<>>
;
single
(
Wrapped
obj
,
std
::
false_type
)
:
single
()
{
single
()
=
default
;
single
(
single
&&
that
)
noexcept
:
single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SingleReceiver
<
wrapped_t
<
Wrapped
>
,
V
,
E
>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
single
(
Wrapped
obj
)
:
single
()
{
check
<
Wrapped
>
();
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -82,10 +71,8 @@ public:
...
@@ -82,10 +71,8 @@ public:
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
SingleReceiver
<
wrapped_t
<
Wrapped
>
,
V
,
E
>
&&
insitu
<
Wrapped
>
())
single
(
Wrapped
obj
,
std
::
true_type
)
noexcept
:
single
()
{
explicit
single
(
Wrapped
obj
)
noexcept
:
single
()
{
check
<
Wrapped
>
();
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -112,6 +99,20 @@ public:
...
@@ -112,6 +99,20 @@ public:
new
((
void
*
)
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
((
void
*
)
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
public:
using
properties
=
property_set
<
is_receiver
<>
,
is_single
<>>
;
single
()
=
default
;
single
(
single
&&
that
)
noexcept
:
single
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SingleReceiver
<
wrapped_t
<
Wrapped
>
,
V
,
E
>
)
explicit
single
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
single
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{
check
<
Wrapped
>
();
}
~
single
()
{
~
single
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -281,7 +282,7 @@ inline auto make_single() -> single<> {
...
@@ -281,7 +282,7 @@ inline auto make_single() -> single<> {
return
{};
return
{};
}
}
PUSHMI_TEMPLATE
(
class
VF
)
PUSHMI_TEMPLATE
(
class
VF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
VF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
VF
&>
))
auto
make_single
(
VF
vf
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
{
auto
make_single
(
VF
vf
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
{
return
single
<
VF
,
abortEF
,
ignoreDF
>
{
std
::
move
(
vf
)};
return
single
<
VF
,
abortEF
,
ignoreDF
>
{
std
::
move
(
vf
)};
}
}
...
@@ -290,58 +291,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...>
...
@@ -290,58 +291,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...>
return
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
{
std
::
move
(
ef
)};
return
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
{
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
auto
make_single
(
DF
df
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
{
auto
make_single
(
DF
df
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
{
return
single
<
ignoreVF
,
abortEF
,
DF
>
{
std
::
move
(
df
)};
return
single
<
ignoreVF
,
abortEF
,
DF
>
{
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
EF
&>
))
auto
make_single
(
VF
vf
,
EF
ef
)
->
single
<
VF
,
EF
,
ignoreDF
>
{
auto
make_single
(
VF
vf
,
EF
ef
)
->
single
<
VF
,
EF
,
ignoreDF
>
{
return
{
std
::
move
(
vf
),
std
::
move
(
ef
)};
return
{
std
::
move
(
vf
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
auto
make_single
(
EF
ef
,
DF
df
)
->
single
<
ignoreVF
,
EF
,
DF
>
{
auto
make_single
(
EF
ef
,
DF
df
)
->
single
<
ignoreVF
,
EF
,
DF
>
{
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
VF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
VF
>
))
auto
make_single
(
VF
vf
,
EF
ef
,
DF
df
)
->
single
<
VF
,
EF
,
DF
>
{
auto
make_single
(
VF
vf
,
EF
ef
,
DF
df
)
->
single
<
VF
,
EF
,
DF
>
{
return
{
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
auto
make_single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
auto
make_single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
return
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
return
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
{
std
::
move
(
d
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DVF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DVF
&
,
Data
&>
))
auto
make_single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
{
auto
make_single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
vf
)};
return
{
std
::
move
(
d
),
std
::
move
(
vf
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
auto
make_single
(
Data
d
,
on_error_fn
<
DEFN
...
>
ef
)
->
auto
make_single
(
Data
d
,
on_error_fn
<
DEFN
...
>
ef
)
->
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
{
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_single
(
Data
d
,
DDF
df
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
{
auto
make_single
(
Data
d
,
DDF
df
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
{
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
)};
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_single
(
Data
d
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
{
auto
make_single
(
Data
d
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
{
auto
make_single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
{
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
return
{
std
::
move
(
d
),
std
::
move
(
vf
),
std
::
move
(
ef
),
std
::
move
(
df
)};
}
}
...
@@ -352,55 +353,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>
...
@@ -352,55 +353,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>
single
()
->
single
<>
;
single
()
->
single
<>
;
PUSHMI_TEMPLATE
(
class
VF
)
PUSHMI_TEMPLATE
(
class
VF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
VF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
VF
&>
))
single
(
VF
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
;
single
(
VF
)
->
single
<
VF
,
abortEF
,
ignoreDF
>
;
template
<
class
...
EFN
>
template
<
class
...
EFN
>
single
(
on_error_fn
<
EFN
...
>
)
->
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
;
single
(
on_error_fn
<
EFN
...
>
)
->
single
<
ignoreVF
,
on_error_fn
<
EFN
...
>
,
ignoreDF
>
;
PUSHMI_TEMPLATE
(
class
DF
)
PUSHMI_TEMPLATE
(
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
DF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
DF
>
))
single
(
DF
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
;
single
(
DF
)
->
single
<
ignoreVF
,
abortEF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
)
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
lazy
::
Receiver
<
VF
>
&&
not
lazy
::
Invocable
<
EF
&>
))
(
requires
PUSHMI_BROKEN_SUBSUMPTION
(
not
defer
::
Receiver
<
VF
>
&&
not
defer
::
Invocable
<
EF
&>
))
single
(
VF
,
EF
)
->
single
<
VF
,
EF
,
ignoreDF
>
;
single
(
VF
,
EF
)
->
single
<
VF
,
EF
,
ignoreDF
>
;
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
EF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
EF
>
))
single
(
EF
,
DF
)
->
single
<
ignoreVF
,
EF
,
DF
>
;
single
(
EF
,
DF
)
->
single
<
ignoreVF
,
EF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
PUSHMI_TEMPLATE
(
class
VF
,
class
EF
,
class
DF
)
(
requires
lazy
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Receiver
<
VF
>
))
(
requires
defer
::
Invocable
<
DF
&>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Receiver
<
VF
>
))
single
(
VF
,
EF
,
DF
)
->
single
<
VF
,
EF
,
DF
>
;
single
(
VF
,
EF
,
DF
)
->
single
<
VF
,
EF
,
DF
>
;
PUSHMI_TEMPLATE
(
class
Data
)
PUSHMI_TEMPLATE
(
class
Data
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
;
single
(
Data
d
)
->
single
<
Data
,
passDVF
,
passDEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DVF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DVF
&
,
Data
&>
))
single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
;
single
(
Data
d
,
DVF
vf
)
->
single
<
Data
,
DVF
,
passDEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
PUSHMI_TEMPLATE
(
class
Data
,
class
...
DEFN
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
)
single
(
Data
d
,
on_error_fn
<
DEFN
...
>
)
->
single
(
Data
d
,
on_error_fn
<
DEFN
...
>
)
->
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
;
single
<
Data
,
passDVF
,
on_error_fn
<
DEFN
...
>
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
single
(
Data
d
,
DDF
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
;
single
(
Data
d
,
DDF
)
->
single
<
Data
,
passDVF
,
passDEF
,
DDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
lazy
::
Invocable
<
DEF
&
,
Data
&>
))
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
not
defer
::
Invocable
<
DEF
&
,
Data
&>
))
single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
;
single
(
Data
d
,
DVF
vf
,
DEF
ef
)
->
single
<
Data
,
DVF
,
DEF
,
passDDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
single
(
Data
d
,
DEF
,
DDF
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
;
single
(
Data
d
,
DEF
,
DDF
)
->
single
<
Data
,
passDVF
,
DEF
,
DDF
>
;
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
PUSHMI_TEMPLATE
(
class
Data
,
class
DVF
,
class
DEF
,
class
DDF
)
(
requires
lazy
::
Receiver
<
Data
,
is_single
<>>
&&
lazy
::
Invocable
<
DDF
&
,
Data
&>
)
(
requires
defer
::
Receiver
<
Data
,
is_single
<>>
&&
defer
::
Invocable
<
DDF
&
,
Data
&>
)
single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
;
single
(
Data
d
,
DVF
vf
,
DEF
ef
,
DDF
df
)
->
single
<
Data
,
DVF
,
DEF
,
DDF
>
;
#endif
#endif
...
...
folly/experimental/pushmi/include/pushmi/single_deferred.h
View file @
2690ee57
...
@@ -26,22 +26,8 @@ class any_single_deferred {
...
@@ -26,22 +26,8 @@ class any_single_deferred {
void
(
*
submit_
)(
data
&
,
single
<
V
,
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
single
<
V
,
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
{};
static
constexpr
vtable
const
noop_
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
any_single_deferred
(
Wrapped
obj
,
std
::
false_type
)
:
any_single_deferred
()
{
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_single
<>>
;
any_single_deferred
()
=
default
;
any_single_deferred
(
any_single_deferred
&&
that
)
noexcept
:
any_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>
,
is_single
<>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
any_single_deferred
(
Wrapped
obj
)
:
any_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -56,10 +42,9 @@ class any_single_deferred {
...
@@ -56,10 +42,9 @@ class any_single_deferred {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>
,
is_single
<>>
any_single_deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
&&
insitu
<
Wrapped
>
())
:
any_single_deferred
()
{
explicit
any_single_deferred
(
Wrapped
obj
)
noexcept
:
any_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -76,6 +61,23 @@ class any_single_deferred {
...
@@ -76,6 +61,23 @@ class any_single_deferred {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_sender
<>
,
is_single
<>>
;
any_single_deferred
()
=
default
;
any_single_deferred
(
any_single_deferred
&&
that
)
noexcept
:
any_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
SenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>
,
is_single
<>>
)
explicit
any_single_deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
any_single_deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{}
~
any_single_deferred
()
{
~
any_single_deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -106,7 +108,7 @@ class single_deferred<SF> {
...
@@ -106,7 +108,7 @@ class single_deferred<SF> {
:
sf_
(
std
::
move
(
sf
))
{}
:
sf_
(
std
::
move
(
sf
))
{}
PUSHMI_TEMPLATE
(
class
Out
)
PUSHMI_TEMPLATE
(
class
Out
)
(
requires
lazy
::
Receiver
<
Out
,
is_single
<>>
&&
lazy
::
Invocable
<
SF
&
,
Out
>
)
(
requires
defer
::
Receiver
<
Out
,
is_single
<>>
&&
defer
::
Invocable
<
SF
&
,
Out
>
)
void
submit
(
Out
out
)
{
void
submit
(
Out
out
)
{
sf_
(
std
::
move
(
out
));
sf_
(
std
::
move
(
out
));
}
}
...
@@ -127,7 +129,8 @@ class single_deferred_2 {
...
@@ -127,7 +129,8 @@ class single_deferred_2 {
constexpr
single_deferred_2
(
Data
data
,
DSF
sf
)
constexpr
single_deferred_2
(
Data
data
,
DSF
sf
)
:
data_
(
std
::
move
(
data
)),
sf_
(
std
::
move
(
sf
))
{}
:
data_
(
std
::
move
(
data
)),
sf_
(
std
::
move
(
sf
))
{}
PUSHMI_TEMPLATE
(
class
Out
)
PUSHMI_TEMPLATE
(
class
Out
)
(
requires
lazy
::
Receiver
<
Out
,
is_single
<>>
&&
lazy
::
Invocable
<
DSF
&
,
Data
&
,
Out
>
)
(
requires
defer
::
Receiver
<
Out
,
is_single
<>>
&&
defer
::
Invocable
<
DSF
&
,
Data
&
,
Out
>
)
void
submit
(
Out
out
)
{
void
submit
(
Out
out
)
{
sf_
(
data_
,
std
::
move
(
out
));
sf_
(
data_
,
std
::
move
(
out
));
}
}
...
@@ -136,7 +139,7 @@ class single_deferred_2 {
...
@@ -136,7 +139,7 @@ class single_deferred_2 {
template
<
class
A
,
class
B
>
template
<
class
A
,
class
B
>
using
single_deferred_base
=
using
single_deferred_base
=
meta
::
if_c
<
meta
::
if_c
<
Sender
<
A
,
is_single
<>>
,
(
bool
)
Sender
<
A
,
is_single
<>>
,
single_deferred_2
<
A
,
B
>
,
single_deferred_2
<
A
,
B
>
,
any_single_deferred
<
A
,
B
>>
;
any_single_deferred
<
A
,
B
>>
;
}
// namespace detail
}
// namespace detail
...
...
folly/experimental/pushmi/include/pushmi/time_single_deferred.h
View file @
2690ee57
...
@@ -31,23 +31,9 @@ class any_time_single_deferred {
...
@@ -31,23 +31,9 @@ class any_time_single_deferred {
void
(
*
submit_
)(
data
&
,
TP
,
single
<
V
,
E
>
)
=
s_submit
;
void
(
*
submit_
)(
data
&
,
TP
,
single
<
V
,
E
>
)
=
s_submit
;
static
constexpr
vtable
const
noop_
=
{};
static
constexpr
vtable
const
noop_
=
{};
}
const
*
vptr_
=
&
vtable
::
noop_
;
}
const
*
vptr_
=
&
vtable
::
noop_
;
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
template
<
class
Wrapped
>
using
wrapped_t
=
any_time_single_deferred
(
Wrapped
obj
,
std
::
false_type
)
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_time_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_time
<>
,
is_single
<>>
;
any_time_single_deferred
()
=
default
;
any_time_single_deferred
(
any_time_single_deferred
&&
that
)
noexcept
:
any_time_single_deferred
()
{
:
any_time_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
TimeSenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>>
PUSHMI_BROKEN_SUBSUMPTION
(
&&
!
insitu
<
Wrapped
>
()))
explicit
any_time_single_deferred
(
Wrapped
obj
)
:
any_time_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -68,10 +54,9 @@ class any_time_single_deferred {
...
@@ -68,10 +54,9 @@ class any_time_single_deferred {
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
data_
.
pobj_
=
new
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
template
<
class
Wrapped
>
(
requires
TimeSenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>>
&&
any_time_single_deferred
(
Wrapped
obj
,
std
::
true_type
)
noexcept
insitu
<
Wrapped
>
())
:
any_time_single_deferred
()
{
explicit
any_time_single_deferred
(
Wrapped
obj
)
noexcept
:
any_time_single_deferred
()
{
struct
s
{
struct
s
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
static
void
op
(
data
&
src
,
data
*
dst
)
{
if
(
dst
)
if
(
dst
)
...
@@ -93,6 +78,24 @@ class any_time_single_deferred {
...
@@ -93,6 +78,24 @@ class any_time_single_deferred {
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
new
(
data_
.
buffer_
)
Wrapped
(
std
::
move
(
obj
));
vptr_
=
&
vtbl
;
vptr_
=
&
vtbl
;
}
}
template
<
class
T
,
class
U
=
std
::
decay_t
<
T
>
>
using
wrapped_t
=
std
::
enable_if_t
<!
std
::
is_same
<
U
,
any_time_single_deferred
>::
value
,
U
>
;
public:
using
properties
=
property_set
<
is_time
<>
,
is_single
<>>
;
any_time_single_deferred
()
=
default
;
any_time_single_deferred
(
any_time_single_deferred
&&
that
)
noexcept
:
any_time_single_deferred
()
{
that
.
vptr_
->
op_
(
that
.
data_
,
&
data_
);
std
::
swap
(
that
.
vptr_
,
vptr_
);
}
PUSHMI_TEMPLATE
(
class
Wrapped
)
(
requires
TimeSenderTo
<
wrapped_t
<
Wrapped
>
,
single
<
V
,
E
>>
)
explicit
any_time_single_deferred
(
Wrapped
obj
)
noexcept
(
insitu
<
Wrapped
>
())
:
any_time_single_deferred
{
std
::
move
(
obj
),
meta
::
bool_
<
insitu
<
Wrapped
>
()
>
{}}
{
}
~
any_time_single_deferred
()
{
~
any_time_single_deferred
()
{
vptr_
->
op_
(
data_
,
nullptr
);
vptr_
->
op_
(
data_
,
nullptr
);
}
}
...
@@ -173,7 +176,7 @@ class time_single_deferred_2 {
...
@@ -173,7 +176,7 @@ class time_single_deferred_2 {
template
<
class
A
,
class
B
,
class
C
>
template
<
class
A
,
class
B
,
class
C
>
using
time_single_deferred_base
=
using
time_single_deferred_base
=
meta
::
if_c
<
meta
::
if_c
<
TimeSender
<
A
,
is_single
<>>
,
(
bool
)
TimeSender
<
A
,
is_single
<>>
,
time_single_deferred_2
<
A
,
B
,
C
>
,
time_single_deferred_2
<
A
,
B
,
C
>
,
any_time_single_deferred
<
A
,
B
,
C
>>
;
any_time_single_deferred
<
A
,
B
,
C
>>
;
}
// namespace detail
}
// namespace detail
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment