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

work around various gcc-6 and -7 bugs

fbshipit-source-id: a26e4e767b4aea27d5092edba3f755a02a8e1cbe
parent e1af1682
...@@ -920,7 +920,7 @@ PUSHMI_CONCEPT_DEF( ...@@ -920,7 +920,7 @@ PUSHMI_CONCEPT_DEF(
Semiregular<T> && EqualityComparable<T> Semiregular<T> && EqualityComparable<T>
); );
#if __cpp_lib_invoke >= 201411 #if 0 //__cpp_lib_invoke >= 201411
using std::invoke; using std::invoke;
#else #else
PUSHMI_TEMPLATE (class F, class...As) PUSHMI_TEMPLATE (class F, class...As)
...@@ -5080,47 +5080,53 @@ struct out_from_fn { ...@@ -5080,47 +5080,53 @@ struct out_from_fn {
}; };
PUSHMI_TEMPLATE(class In, class FN) PUSHMI_TEMPLATE(class In, class FN)
(requires Sender<In> && SemiMovable<FN>) (requires Sender<In> && SemiMovable<FN>
PUSHMI_BROKEN_SUBSUMPTION(&& not TimeSender<In>))
auto submit_transform_out(FN fn){ auto submit_transform_out(FN fn){
PUSHMI_IF_CONSTEXPR_RETURN( ((bool) TimeSender<In>) ( return on_submit(
return on_submit( constrain(lazy::Receiver<_2>,
constrain(lazy::Receiver<_3>, [fn = std::move(fn)](In& in, auto out) {
[fn = std::move(fn)](In& in, auto tp, auto out) { ::pushmi::submit(in, fn(std::move(out)));
::pushmi::submit(in, tp, fn(std::move(out))); }
} )
) );
); }
) else (
return on_submit( PUSHMI_TEMPLATE(class In, class FN)
constrain(lazy::Receiver<_2>, (requires TimeSender<In> && SemiMovable<FN>)
[fn = std::move(fn)](In& in, auto out) { auto submit_transform_out(FN fn){
::pushmi::submit(in, fn(std::move(out))); return on_submit(
} constrain(lazy::Receiver<_3>,
) [fn = std::move(fn)](In& in, auto tp, auto out) {
); ::pushmi::submit(in, tp, fn(std::move(out)));
)) }
)
);
} }
PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF) PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF)
(requires Sender<In> && SemiMovable<SDSF> && SemiMovable<TSDSF>) (requires Sender<In> && SemiMovable<SDSF> && SemiMovable<TSDSF>
PUSHMI_BROKEN_SUBSUMPTION(&& not TimeSender<In>))
auto submit_transform_out(SDSF sdsf, TSDSF tsdsf) { auto submit_transform_out(SDSF sdsf, TSDSF tsdsf) {
PUSHMI_IF_CONSTEXPR_RETURN( ((bool) TimeSender<In>) ( return on_submit(
return on_submit( constrain(lazy::Receiver<_2> && lazy::Invocable<SDSF&, In&, _2>,
constrain(lazy::Receiver<_3> && lazy::Invocable<TSDSF&, In&, _2, _3>, [sdsf = std::move(sdsf)](In& in, auto out) {
[tsdsf = std::move(tsdsf)](In& in, auto tp, auto out) { sdsf(in, std::move(out));
tsdsf(in, tp, std::move(out)); }
} )
) );
); }
) else (
return on_submit( PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF)
constrain(lazy::Receiver<_2> && lazy::Invocable<SDSF&, In&, _2>, (requires TimeSender<In> && SemiMovable<SDSF> && SemiMovable<TSDSF>)
[sdsf = std::move(sdsf)](In& in, auto out) { auto submit_transform_out(SDSF sdsf, TSDSF tsdsf) {
sdsf(in, std::move(out)); return on_submit(
} constrain(lazy::Receiver<_3> && lazy::Invocable<TSDSF&, In&, _2, _3>,
) [tsdsf = std::move(tsdsf)](In& in, auto tp, auto out) {
); tsdsf(in, tp, std::move(out));
)) }
)
);
} }
PUSHMI_TEMPLATE(class In, class Out) PUSHMI_TEMPLATE(class In, class Out)
...@@ -6020,6 +6026,10 @@ PUSHMI_INLINE_VAR constexpr struct make_tap_fn { ...@@ -6020,6 +6026,10 @@ PUSHMI_INLINE_VAR constexpr struct make_tap_fn {
} const make_tap {}; } const make_tap {};
struct tap_fn { struct tap_fn {
private:
template <class In, class SideEffects>
static auto impl(In, SideEffects);
public:
template <class... AN> template <class... AN>
auto operator()(AN... an) const; auto operator()(AN... an) const;
}; };
...@@ -6040,43 +6050,46 @@ auto tap_fn::operator()(AN... an) const { ...@@ -6040,43 +6050,46 @@ auto tap_fn::operator()(AN... an) const {
return constrain(lazy::Sender<_1>, return constrain(lazy::Sender<_1>,
[args = std::tuple<AN...>{std::move(an)...}](auto in) mutable { [args = std::tuple<AN...>{std::move(an)...}](auto in) mutable {
using In = decltype(in); using In = decltype(in);
auto sideEffects{::pushmi::detail::out_from_fn<In>()(std::move(args))}; return tap_fn::impl(
using SideEffects = decltype(sideEffects);
PUSHMI_STATIC_ASSERT(
::pushmi::detail::deferred_requires_from<In, SideEffects,
SenderTo<In, SideEffects, is_none<>>,
SenderTo<In, SideEffects, is_single<>>,
TimeSenderTo<In, SideEffects, is_single<>> >(),
"'In' is not deliverable to 'SideEffects'");
return ::pushmi::detail::deferred_from<In, SideEffects>(
std::move(in), std::move(in),
::pushmi::detail::submit_transform_out<In>( ::pushmi::detail::out_from_fn<In>()(std::move(args)));
constrain(lazy::Receiver<_1>, });
[sideEffects_ = std::move(sideEffects)](auto out) { }
using Out = decltype(out);
PUSHMI_STATIC_ASSERT( template <class In, class SideEffects>
::pushmi::detail::deferred_requires_from<In, SideEffects, auto tap_fn::impl(In in, SideEffects sideEffects) {
SenderTo<In, Out, is_none<>>, PUSHMI_STATIC_ASSERT(
SenderTo<In, Out, is_single<>>, ::pushmi::detail::deferred_requires_from<In, SideEffects,
TimeSenderTo<In, Out, is_single<>> >(), SenderTo<In, SideEffects, is_none<>>,
"'In' is not deliverable to 'Out'"); SenderTo<In, SideEffects, is_single<>>,
auto gang{::pushmi::detail::out_from_fn<In>()( TimeSenderTo<In, SideEffects, is_single<>> >(),
detail::make_tap(sideEffects_, std::move(out)))}; "'In' is not deliverable to 'SideEffects'");
using Gang = decltype(gang);
PUSHMI_STATIC_ASSERT( return ::pushmi::detail::deferred_from<In, SideEffects>(
::pushmi::detail::deferred_requires_from<In, SideEffects, std::move(in),
SenderTo<In, Gang>, ::pushmi::detail::submit_transform_out<In>(
SenderTo<In, Gang, is_single<>>, constrain(lazy::Receiver<_1>,
TimeSenderTo<In, Gang, is_single<>> >(), [sideEffects_ = std::move(sideEffects)](auto out) {
"'In' is not deliverable to 'Out' & 'SideEffects'"); using Out = decltype(out);
return gang; PUSHMI_STATIC_ASSERT(
} ::pushmi::detail::deferred_requires_from<In, SideEffects,
) SenderTo<In, Out, is_none<>>,
) SenderTo<In, Out, is_single<>>,
); TimeSenderTo<In, Out, is_single<>> >(),
} "'In' is not deliverable to 'Out'");
auto gang{::pushmi::detail::out_from_fn<In>()(
detail::make_tap(sideEffects_, std::move(out)))};
using Gang = decltype(gang);
PUSHMI_STATIC_ASSERT(
::pushmi::detail::deferred_requires_from<In, SideEffects,
SenderTo<In, Gang>,
SenderTo<In, Gang, is_single<>>,
TimeSenderTo<In, Gang, is_single<>> >(),
"'In' is not deliverable to 'Out' & 'SideEffects'");
return gang;
}
)
)
); );
} }
......
...@@ -81,47 +81,53 @@ struct out_from_fn { ...@@ -81,47 +81,53 @@ struct out_from_fn {
}; };
PUSHMI_TEMPLATE(class In, class FN) PUSHMI_TEMPLATE(class In, class FN)
(requires Sender<In> && SemiMovable<FN>) (requires Sender<In> && SemiMovable<FN>
PUSHMI_BROKEN_SUBSUMPTION(&& not TimeSender<In>))
auto submit_transform_out(FN fn){ auto submit_transform_out(FN fn){
PUSHMI_IF_CONSTEXPR_RETURN( ((bool) TimeSender<In>) ( return on_submit(
return on_submit( constrain(lazy::Receiver<_2>,
constrain(lazy::Receiver<_3>, [fn = std::move(fn)](In& in, auto out) {
[fn = std::move(fn)](In& in, auto tp, auto out) { ::pushmi::submit(in, fn(std::move(out)));
::pushmi::submit(in, tp, fn(std::move(out))); }
} )
) );
); }
) else (
return on_submit( PUSHMI_TEMPLATE(class In, class FN)
constrain(lazy::Receiver<_2>, (requires TimeSender<In> && SemiMovable<FN>)
[fn = std::move(fn)](In& in, auto out) { auto submit_transform_out(FN fn){
::pushmi::submit(in, fn(std::move(out))); return on_submit(
} constrain(lazy::Receiver<_3>,
) [fn = std::move(fn)](In& in, auto tp, auto out) {
); ::pushmi::submit(in, tp, fn(std::move(out)));
)) }
)
);
} }
PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF) PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF)
(requires Sender<In> && SemiMovable<SDSF> && SemiMovable<TSDSF>) (requires Sender<In> && SemiMovable<SDSF> && SemiMovable<TSDSF>
PUSHMI_BROKEN_SUBSUMPTION(&& not TimeSender<In>))
auto submit_transform_out(SDSF sdsf, TSDSF tsdsf) { auto submit_transform_out(SDSF sdsf, TSDSF tsdsf) {
PUSHMI_IF_CONSTEXPR_RETURN( ((bool) TimeSender<In>) ( return on_submit(
return on_submit( constrain(lazy::Receiver<_2> && lazy::Invocable<SDSF&, In&, _2>,
constrain(lazy::Receiver<_3> && lazy::Invocable<TSDSF&, In&, _2, _3>, [sdsf = std::move(sdsf)](In& in, auto out) {
[tsdsf = std::move(tsdsf)](In& in, auto tp, auto out) { sdsf(in, std::move(out));
tsdsf(in, tp, std::move(out)); }
} )
) );
); }
) else (
return on_submit( PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF)
constrain(lazy::Receiver<_2> && lazy::Invocable<SDSF&, In&, _2>, (requires TimeSender<In> && SemiMovable<SDSF> && SemiMovable<TSDSF>)
[sdsf = std::move(sdsf)](In& in, auto out) { auto submit_transform_out(SDSF sdsf, TSDSF tsdsf) {
sdsf(in, std::move(out)); return on_submit(
} constrain(lazy::Receiver<_3> && lazy::Invocable<TSDSF&, In&, _2, _3>,
) [tsdsf = std::move(tsdsf)](In& in, auto tp, auto out) {
); tsdsf(in, tp, std::move(out));
)) }
)
);
} }
PUSHMI_TEMPLATE(class In, class Out) PUSHMI_TEMPLATE(class In, class Out)
......
...@@ -57,6 +57,10 @@ PUSHMI_INLINE_VAR constexpr struct make_tap_fn { ...@@ -57,6 +57,10 @@ PUSHMI_INLINE_VAR constexpr struct make_tap_fn {
} const make_tap {}; } const make_tap {};
struct tap_fn { struct tap_fn {
private:
template <class In, class SideEffects>
static auto impl(In, SideEffects);
public:
template <class... AN> template <class... AN>
auto operator()(AN... an) const; auto operator()(AN... an) const;
}; };
...@@ -77,43 +81,46 @@ auto tap_fn::operator()(AN... an) const { ...@@ -77,43 +81,46 @@ auto tap_fn::operator()(AN... an) const {
return constrain(lazy::Sender<_1>, return constrain(lazy::Sender<_1>,
[args = std::tuple<AN...>{std::move(an)...}](auto in) mutable { [args = std::tuple<AN...>{std::move(an)...}](auto in) mutable {
using In = decltype(in); using In = decltype(in);
auto sideEffects{::pushmi::detail::out_from_fn<In>()(std::move(args))}; return tap_fn::impl(
using SideEffects = decltype(sideEffects); std::move(in),
::pushmi::detail::out_from_fn<In>()(std::move(args)));
});
}
PUSHMI_STATIC_ASSERT( template <class In, class SideEffects>
::pushmi::detail::deferred_requires_from<In, SideEffects, auto tap_fn::impl(In in, SideEffects sideEffects) {
SenderTo<In, SideEffects, is_none<>>, PUSHMI_STATIC_ASSERT(
SenderTo<In, SideEffects, is_single<>>, ::pushmi::detail::deferred_requires_from<In, SideEffects,
TimeSenderTo<In, SideEffects, is_single<>> >(), SenderTo<In, SideEffects, is_none<>>,
"'In' is not deliverable to 'SideEffects'"); SenderTo<In, SideEffects, is_single<>>,
TimeSenderTo<In, SideEffects, is_single<>> >(),
"'In' is not deliverable to 'SideEffects'");
return ::pushmi::detail::deferred_from<In, SideEffects>( return ::pushmi::detail::deferred_from<In, SideEffects>(
std::move(in), std::move(in),
::pushmi::detail::submit_transform_out<In>( ::pushmi::detail::submit_transform_out<In>(
constrain(lazy::Receiver<_1>, constrain(lazy::Receiver<_1>,
[sideEffects_ = std::move(sideEffects)](auto out) { [sideEffects_ = std::move(sideEffects)](auto out) {
using Out = decltype(out); using Out = decltype(out);
PUSHMI_STATIC_ASSERT( PUSHMI_STATIC_ASSERT(
::pushmi::detail::deferred_requires_from<In, SideEffects, ::pushmi::detail::deferred_requires_from<In, SideEffects,
SenderTo<In, Out, is_none<>>, SenderTo<In, Out, is_none<>>,
SenderTo<In, Out, is_single<>>, SenderTo<In, Out, is_single<>>,
TimeSenderTo<In, Out, is_single<>> >(), TimeSenderTo<In, Out, is_single<>> >(),
"'In' is not deliverable to 'Out'"); "'In' is not deliverable to 'Out'");
auto gang{::pushmi::detail::out_from_fn<In>()( auto gang{::pushmi::detail::out_from_fn<In>()(
detail::make_tap(sideEffects_, std::move(out)))}; detail::make_tap(sideEffects_, std::move(out)))};
using Gang = decltype(gang); using Gang = decltype(gang);
PUSHMI_STATIC_ASSERT( PUSHMI_STATIC_ASSERT(
::pushmi::detail::deferred_requires_from<In, SideEffects, ::pushmi::detail::deferred_requires_from<In, SideEffects,
SenderTo<In, Gang>, SenderTo<In, Gang>,
SenderTo<In, Gang, is_single<>>, SenderTo<In, Gang, is_single<>>,
TimeSenderTo<In, Gang, is_single<>> >(), TimeSenderTo<In, Gang, is_single<>> >(),
"'In' is not deliverable to 'Out' & 'SideEffects'"); "'In' is not deliverable to 'Out' & 'SideEffects'");
return gang; return gang;
} }
) )
) )
);
}
); );
} }
......
...@@ -192,7 +192,7 @@ PUSHMI_CONCEPT_DEF( ...@@ -192,7 +192,7 @@ PUSHMI_CONCEPT_DEF(
Semiregular<T> && EqualityComparable<T> Semiregular<T> && EqualityComparable<T>
); );
#if __cpp_lib_invoke >= 201411 #if 0 //__cpp_lib_invoke >= 201411
using std::invoke; using std::invoke;
#else #else
PUSHMI_TEMPLATE (class F, class...As) PUSHMI_TEMPLATE (class F, class...As)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment