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

get folly/experimental/pushmi building with gcc-5 again

Summary: Judging from the number of things that needed fixing, pushmi has been busted on gcc-5 for some time.

Reviewed By: yfeldblum, kirkshoop

Differential Revision: D13979146

fbshipit-source-id: 95def0ef6289b41e116a55359476ffec91787706
parent 4435c335
...@@ -325,7 +325,8 @@ PUSHMI_CONCEPT_DEF( ...@@ -325,7 +325,8 @@ PUSHMI_CONCEPT_DEF(
(concept ReceiveError)(R, E), // (concept ReceiveError)(R, E), //
requires(R& r, E&& e)( // requires(R& r, E&& e)( //
set_error(r, (E &&) e)) && set_error(r, (E &&) e)) &&
Receiver<R> && SemiMovable<E>); Receiver<R> && SemiMovable<E>
);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class D, class... PropertyN) // template(class D, class... PropertyN) //
......
...@@ -135,7 +135,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -135,7 +135,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
PUSHMI_PP_IIF(X)(PUSHMI_PP_EMPTY, PUSHMI_PP_COMMA)() PUSHMI_PP_IIF(X)(PUSHMI_PP_EMPTY, PUSHMI_PP_COMMA)()
#define PUSHMI_CONCEPT_ASSERT(...) \ #define PUSHMI_CONCEPT_ASSERT(...) \
static_assert((bool) (__VA_ARGS__), \ static_assert(static_cast<bool>(__VA_ARGS__), \
"Concept assertion failed : " #__VA_ARGS__) "Concept assertion failed : " #__VA_ARGS__)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -225,14 +225,14 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -225,14 +225,14 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \ #define PUSHMI_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
inline namespace _eager_ { \ inline namespace _eager_ { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
concept bool NAME = PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__); \ concept bool NAME = PUSHMI_PP_DEF_IMPL(__VA_ARGS__,)(__VA_ARGS__); \
} \ } \
namespace lazy = _eager_; \ namespace lazy = _eager_; \
/**/ /**/
#else #else
// No requires expression: // No requires expression:
#define PUSHMI_PP_DEF_IMPL_0(...) \ #define PUSHMI_PP_DEF_IMPL_0(...) \
() -> std::enable_if_t<bool(__VA_ARGS__), int> \ () -> std::enable_if_t<static_cast<bool>(__VA_ARGS__), int> \
/**/ /**/
// Requires expression: // Requires expression:
#define PUSHMI_PP_DEF_IMPL_1(...) \ #define PUSHMI_PP_DEF_IMPL_1(...) \
...@@ -254,16 +254,16 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -254,16 +254,16 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
using Concept = PUSHMI_PP_CAT(NAME, Concept); \ using Concept = PUSHMI_PP_CAT(NAME, Concept); \
PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN \ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
static auto Requires_ PUSHMI_PP_DEF_IMPL(__VA_ARGS__)(__VA_ARGS__) { \ static auto Requires_ PUSHMI_PP_DEF_IMPL(__VA_ARGS__,)(__VA_ARGS__) { \
return 0; \ return 0; \
} \ } \
PUSHMI_PP_IGNORE_CXX2A_COMPAT_END \ PUSHMI_PP_IGNORE_CXX2A_COMPAT_END \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
struct Eval { \ struct Eval { \
template <class C_ = Concept> \ template <class C_ = Concept, \
static constexpr decltype(::folly::pushmi::concepts::detail::gcc_bugs( \ decltype(::folly::pushmi::concepts::detail::gcc_bugs( \
&C_::template Requires_<PUSHMI_PP_EXPAND ARGS>)) \ &C_::template Requires_<PUSHMI_PP_EXPAND ARGS>)) = nullptr> \
impl(int) noexcept { \ static constexpr bool impl(int) noexcept { \
return true; \ return true; \
} \ } \
static constexpr bool impl(long) noexcept { \ static constexpr bool impl(long) noexcept { \
...@@ -275,7 +275,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -275,7 +275,7 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
template < \ template < \
class PMThis = Concept, \ class PMThis = Concept, \
bool PMB, \ bool PMB, \
class = std::enable_if_t<PMB == (bool)PMThis{}>> \ class = std::enable_if_t<PMB == static_cast<bool>(PMThis{})>> \
constexpr operator std::integral_constant<bool, PMB>() const noexcept { \ constexpr operator std::integral_constant<bool, PMB>() const noexcept { \
return {}; \ return {}; \
} \ } \
...@@ -299,7 +299,8 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -299,7 +299,8 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
} \ } \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \ PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr bool NAME = \ PUSHMI_INLINE_VAR constexpr bool NAME = \
(bool)PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS> {} \ static_cast<bool>( \
PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{}) \
/**/ /**/
#endif #endif
...@@ -382,11 +383,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN ...@@ -382,11 +383,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#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__))[ \ bool PUSHMI_PP_CAT(_pushmi_false_, __LINE__) = false, \
PUSHMI_COUNTER] = nullptr, \ std::enable_if_t< \
std::enable_if_t<PUSHMI_PP_CAT(_pushmi_concept_unique_, __LINE__) || \ static_cast<bool>(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT( \
bool(PUSHMI_TEMPLATE_AUX_4(PUSHMI_PP_CAT( \ PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))) || \
PUSHMI_TEMPLATE_AUX_3_, __VA_ARGS__))), int> = 0> \ PUSHMI_PP_CAT(_pushmi_false_, __LINE__), int> = 0> \
/**/ /**/
#define PUSHMI_TEMPLATE_AUX_3_requires #define PUSHMI_TEMPLATE_AUX_3_requires
#define PUSHMI_TEMPLATE_AUX_4(...) \ #define PUSHMI_TEMPLATE_AUX_4(...) \
...@@ -444,7 +445,8 @@ using bool_ = std::integral_constant<bool, B>; ...@@ -444,7 +445,8 @@ using bool_ = std::integral_constant<bool, B>;
namespace concepts { namespace concepts {
namespace detail { namespace detail {
bool gcc_bugs(...); template<class T>
T gcc_bugs(T);
template <class> template <class>
inline constexpr bool requires_() { inline constexpr bool requires_() {
...@@ -459,10 +461,10 @@ struct Or; ...@@ -459,10 +461,10 @@ struct Or;
template <class T> template <class T>
struct Not { struct Not {
explicit constexpr operator bool() const noexcept { explicit constexpr operator bool() const noexcept {
return !(bool)T{}; return !static_cast<bool>(T{});
} }
PUSHMI_TEMPLATE(class This = Not, bool B) PUSHMI_TEMPLATE(class This = Not, bool B)
(requires B == (bool)This{}) constexpr (requires B == static_cast<bool>(This{})) constexpr
operator std::integral_constant<bool, B>() const noexcept { operator std::integral_constant<bool, B>() const noexcept {
return {}; return {};
} }
...@@ -484,9 +486,9 @@ struct And { ...@@ -484,9 +486,9 @@ struct And {
explicit constexpr operator bool() const noexcept { explicit constexpr operator bool() const noexcept {
return (bool)std::conditional_t<(bool)T{}, U, std::false_type>{}; return (bool)std::conditional_t<(bool)T{}, U, std::false_type>{};
} }
PUSHMI_TEMPLATE(class This = And, bool B) PUSHMI_TEMPLATE(class This = And, bool B) //
(requires B == (bool)This{}) constexpr (requires B == static_cast<bool>(This{})) //
operator std::integral_constant<bool, B>() const noexcept { constexpr operator std::integral_constant<bool, B>() const noexcept {
return {}; return {};
} }
constexpr auto operator!() const noexcept { constexpr auto operator!() const noexcept {
...@@ -507,9 +509,9 @@ struct Or { ...@@ -507,9 +509,9 @@ struct Or {
explicit constexpr operator bool() const noexcept { explicit constexpr operator bool() const noexcept {
return (bool)std::conditional_t<(bool)T{}, std::true_type, U>{}; return (bool)std::conditional_t<(bool)T{}, std::true_type, U>{};
} }
PUSHMI_TEMPLATE(class This = Or, bool B) PUSHMI_TEMPLATE(class This = Or, bool B) //
(requires B == (bool)This{}) constexpr (requires B == static_cast<bool>(This{})) //
operator std::integral_constant<bool, B>() const noexcept { constexpr operator std::integral_constant<bool, B>() const noexcept {
return {}; return {};
} }
constexpr auto operator!() const noexcept { constexpr auto operator!() const noexcept {
......
...@@ -42,13 +42,15 @@ auto println = [](auto v) { std::cout << v << std::endl; }; ...@@ -42,13 +42,15 @@ auto println = [](auto v) { std::cout << v << std::endl; };
// concat not yet implemented // concat not yet implemented
template <class T, class E = std::exception_ptr> template <class T, class E = std::exception_ptr>
auto concat = [](auto in) { auto concat() {
return mi::make_single_sender([in](auto out) mutable { return [](auto in) {
mi::submit(in, mi::make_receiver(out, [](auto out_, auto v) { return mi::make_single_sender([in](auto out) mutable {
mi::submit(v, mi::any_receiver<E, T>(out_)); mi::submit(in, mi::make_receiver(out, [](auto out_, auto v) {
})); mi::submit(v, mi::any_receiver<E, T>(out_));
}); }));
}; });
};
}
int main() { int main() {
get_setting() | op::transform([](int i) { return std::to_string(i); }) | get_setting() | op::transform([](int i) { return std::to_string(i); }) |
...@@ -65,7 +67,7 @@ int main() { ...@@ -65,7 +67,7 @@ int main() {
} }
return mi::any_single_sender<std::exception_ptr, std::string>{ return mi::any_single_sender<std::exception_ptr, std::string>{
op::just(std::to_string(i))}; op::just(std::to_string(i))};
}) | concat<std::string> | }) | concat<std::string>() |
op::submit(println); op::submit(println);
std::cout << "OK" << std::endl; std::cout << "OK" << std::endl;
......
...@@ -29,13 +29,15 @@ using namespace folly::pushmi::aliases; ...@@ -29,13 +29,15 @@ using namespace folly::pushmi::aliases;
// concat not yet implemented // concat not yet implemented
template <class T, class E = std::exception_ptr> template <class T, class E = std::exception_ptr>
auto concat = [](auto in) { auto concat() {
return mi::make_single_sender([in](auto out) mutable { return [](auto in) {
mi::submit(in, mi::make_receiver(out, [](auto out_, auto v) { return mi::make_single_sender([in](auto out) mutable {
mi::submit(v, mi::any_receiver<E, T>(out_)); mi::submit(in, mi::make_receiver(out, [](auto out_, auto v) {
})); mi::submit(v, mi::any_receiver<E, T>(out_));
}); }));
}; });
};
}
int main() { int main() {
auto stop_abort = mi::on_error([](auto) noexcept {}); auto stop_abort = mi::on_error([](auto) noexcept {});
...@@ -76,7 +78,7 @@ int main() { ...@@ -76,7 +78,7 @@ int main() {
} else { } else {
return r_t{op::just(v)}; return r_t{op::just(v)};
} }
}) | concat<int> | }) | concat<int>() |
op::submit(); op::submit();
// retry on error // retry on error
......
...@@ -68,7 +68,7 @@ public: ...@@ -68,7 +68,7 @@ public:
static_assert( static_assert(
SenderTo<Wrapped, any_receiver<E,This>>, SenderTo<Wrapped, any_receiver<E,This>>,
"Expecting to be passed a Sender that can send to a SingleReceiver" "Expecting to be passed a Sender that can send to a SingleReceiver"
" that accpets a value of type This and an error of type E"); " that accepts a value of type This and an error of type E");
struct s { struct s {
static void submit(void* pobj, void* s) { static void submit(void* pobj, void* s) {
return ::folly::pushmi::submit( return ::folly::pushmi::submit(
......
...@@ -403,7 +403,7 @@ PUSHMI_INLINE_VAR constexpr __adl::get_top_fn top{}; ...@@ -403,7 +403,7 @@ PUSHMI_INLINE_VAR constexpr __adl::get_top_fn top{};
template <class T> template <class T>
struct property_set_traits< struct property_set_traits<
T, T,
std::enable_if_t<(bool)Invocable<T&> && not Valid<T&, __properties_t>>> { void_t<invoke_result_t<T&>>> {
using properties = property_set<is_receiver<>>; using properties = property_set<is_receiver<>>;
}; };
......
...@@ -99,13 +99,18 @@ struct tap_fn { ...@@ -99,13 +99,18 @@ struct tap_fn {
(requires Sender<In>&& Receiver<SideEffects>) (requires Sender<In>&& Receiver<SideEffects>)
struct out_impl { struct out_impl {
SideEffects sideEffects_; SideEffects sideEffects_;
template<class Out>
using tap_t =
decltype(
detail::make_tap(
std::declval<const SideEffects&>(),
std::declval<Out>()));
template<class Out>
using receiver_t = invoke_result_t<receiver_from_fn<In>, tap_t<Out>>;
PUSHMI_TEMPLATE(class Out) PUSHMI_TEMPLATE(class Out)
(requires Receiver<Out>&& SenderTo<In, Out>&& SenderTo< (requires Receiver<Out>&& SenderTo<In, Out>&& SenderTo<
In, In,
decltype( receiver_t<Out>>)
::folly::pushmi::detail::receiver_from_fn<In>()(detail::make_tap(
std::declval<SideEffects>(),
std::declval<Out>())))>)
auto operator()(Out out) const { auto operator()(Out out) const {
auto gang{::folly::pushmi::detail::receiver_from_fn<In>()( auto gang{::folly::pushmi::detail::receiver_from_fn<In>()(
detail::make_tap(sideEffects_, std::move(out)))}; detail::make_tap(sideEffects_, std::move(out)))};
......
...@@ -22,7 +22,8 @@ namespace folly { ...@@ -22,7 +22,8 @@ namespace folly {
namespace pushmi { namespace pushmi {
PUSHMI_TEMPLATE(class In, class Op) PUSHMI_TEMPLATE(class In, class Op)
(requires lazy::Sender<std::decay_t<In>>&& lazy::Invocable<Op&, In>) // (requires PUSHMI_EXP(lazy::Sender<std::decay_t<In>> PUSHMI_AND
lazy::Invocable<Op&, In>)) //
decltype(auto) decltype(auto)
operator|(In&& in, Op op) { operator|(In&& in, Op op) {
return op((In &&) in); return op((In &&) in);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#pragma once #pragma once
#include <folly/Traits.h>
#include <folly/experimental/pushmi/traits.h> #include <folly/experimental/pushmi/traits.h>
#include <folly/experimental/pushmi/forwards.h> #include <folly/experimental/pushmi/forwards.h>
...@@ -35,7 +36,7 @@ struct property_traits {}; ...@@ -35,7 +36,7 @@ struct property_traits {};
template <class T> template <class T>
struct property_traits< struct property_traits<
T, T,
std::enable_if_t<Valid<std::decay_t<T>, __property_category_t>>> { void_t<__property_category_t<std::decay_t<T>>>> {
using property_category = __property_category_t<std::decay_t<T>>; using property_category = __property_category_t<std::decay_t<T>>;
}; };
...@@ -45,7 +46,7 @@ using property_category_t = __property_category_t<property_traits<T>>; ...@@ -45,7 +46,7 @@ using property_category_t = __property_category_t<property_traits<T>>;
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class T) template(class T)
concept Property, concept Property,
Valid<T, property_category_t> True<__property_category_t<property_traits<T>>>
); );
// in cases where Set contains T, allow T to find itself only once // in cases where Set contains T, allow T to find itself only once
...@@ -96,7 +97,7 @@ struct property_set_traits {}; ...@@ -96,7 +97,7 @@ struct property_set_traits {};
template <class T> template <class T>
struct property_set_traits< struct property_set_traits<
T, T,
std::enable_if_t<Valid<std::decay_t<T>, __properties_t>>> { void_t<__properties_t<std::decay_t<T>>>> {
using properties = __properties_t<std::decay_t<T>>; using properties = __properties_t<std::decay_t<T>>;
}; };
...@@ -108,7 +109,7 @@ using properties_t = std::enable_if_t< ...@@ -108,7 +109,7 @@ using properties_t = std::enable_if_t<
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class T) template(class T)
concept Properties, concept Properties,
Valid<T, properties_t> PropertySet<__properties_t<property_set_traits<T>>>
); );
// find property in the specified set that matches the category of the property // find property in the specified set that matches the category of the property
......
...@@ -123,9 +123,8 @@ class any_receiver { ...@@ -123,9 +123,8 @@ class any_receiver {
std::swap(that.vptr_, vptr_); std::swap(that.vptr_, vptr_);
} }
PUSHMI_TEMPLATE(class Wrapped) PUSHMI_TEMPLATE(class Wrapped)
(requires ReceiveValue<wrapped_t<Wrapped>, VN...>&& ReceiveError< (requires ReceiveValue<wrapped_t<Wrapped>, VN...>&& //
Wrapped, ReceiveError<wrapped_t<Wrapped>, E>)
E>)
explicit any_receiver(Wrapped obj) noexcept(insitu<Wrapped>()) explicit any_receiver(Wrapped obj) noexcept(insitu<Wrapped>())
: any_receiver{std::move(obj), bool_<insitu<Wrapped>()>{}} { : any_receiver{std::move(obj), bool_<insitu<Wrapped>()>{}} {
check<Wrapped>(); check<Wrapped>();
......
...@@ -92,7 +92,6 @@ class any_single_sender { ...@@ -92,7 +92,6 @@ class any_single_sender {
template <class T, class U = std::decay_t<T>> template <class T, class U = std::decay_t<T>>
using wrapped_t = using wrapped_t =
std::enable_if_t<!std::is_same<U, any_single_sender>::value, U>; std::enable_if_t<!std::is_same<U, any_single_sender>::value, U>;
public: public:
using properties = property_set<is_sender<>, is_single<>>; using properties = property_set<is_sender<>, is_single<>>;
...@@ -102,13 +101,9 @@ class any_single_sender { ...@@ -102,13 +101,9 @@ class any_single_sender {
std::swap(that.vptr_, vptr_); std::swap(that.vptr_, vptr_);
} }
PUSHMI_TEMPLATE(class Wrapped) PUSHMI_TEMPLATE(class Wrapped) //
(requires SenderTo< (requires SenderTo<wrapped_t<Wrapped>, any_receiver<E, VN...>>) //
wrapped_t<Wrapped>, explicit any_single_sender(Wrapped obj) noexcept(insitu<Wrapped>())
any_receiver<
E,
VN...>>) //
explicit any_single_sender(Wrapped obj) noexcept(insitu<Wrapped>())
: any_single_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {} : any_single_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {}
~any_single_sender() { ~any_single_sender() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>
#include <folly/Traits.h>
#include <folly/experimental/pushmi/detail/functional.h> #include <folly/experimental/pushmi/detail/functional.h>
#define PUSHMI_NOEXCEPT_AUTO(...) \ #define PUSHMI_NOEXCEPT_AUTO(...) \
...@@ -74,9 +75,6 @@ PUSHMI_INLINE_VAR constexpr int sum_v = detail::sum_impl<Is...>(); ...@@ -74,9 +75,6 @@ PUSHMI_INLINE_VAR constexpr int sum_v = detail::sum_impl<Is...>();
template <class...> template <class...>
struct typelist; struct typelist;
template <class...>
using void_t = void;
template <class T> template <class T>
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>; using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
...@@ -86,12 +84,6 @@ PUSHMI_CONCEPT_DEF( ...@@ -86,12 +84,6 @@ PUSHMI_CONCEPT_DEF(
true true
); );
PUSHMI_CONCEPT_DEF(
template(class T, template<class...> class C)
(concept Valid)(T, C),
True< C<T> >
);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template (class T, template<class...> class Trait, class... Args) template (class T, template<class...> class Trait, class... Args)
(concept Satisfies)(T, Trait, Args...), (concept Satisfies)(T, Trait, Args...),
......
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