mirror of
https://github.com/Naios/continuable.git
synced 2026-02-16 23:29:48 +08:00
Fix a recursive template instantiation issue on clang and gcc
This commit is contained in:
parent
1320c8eb63
commit
57bb43138b
@ -119,13 +119,14 @@ public:
|
|||||||
|
|
||||||
/// Constructor accepting any object convertible to the data object,
|
/// Constructor accepting any object convertible to the data object,
|
||||||
/// while erasing the annotation
|
/// while erasing the annotation
|
||||||
template <typename OData,
|
template <typename OtherData,
|
||||||
std::enable_if_t<detail::base::can_accept_continuation<
|
std::enable_if_t<detail::base::can_accept_continuation<
|
||||||
Data, Annotation, detail::traits::unrefcv_t<OData>>::value>* =
|
Data, Annotation,
|
||||||
nullptr>
|
detail::traits::unrefcv_t<OtherData>>::value>* = nullptr>
|
||||||
continuable_base(OData&& data) // NOLINT(misc-forwarding-reference-overload)
|
continuable_base(OtherData&& data)
|
||||||
: data_(detail::base::proxy_continuable<Annotation, OData>(
|
: data_(detail::base::proxy_continuable<
|
||||||
std::forward<OData>(data))) {
|
Annotation, detail::traits::unrefcv_t<OtherData>>(
|
||||||
|
std::forward<OtherData>(data))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructor taking the data of other continuable_base objects
|
/// Constructor taking the data of other continuable_base objects
|
||||||
|
|||||||
@ -134,7 +134,6 @@ struct proxy_continuable<traits::identity<Args...>, Continuation>
|
|||||||
proxy_continuable& operator=(proxy_continuable&&) = default;
|
proxy_continuable& operator=(proxy_continuable&&) = default;
|
||||||
proxy_continuable& operator=(proxy_continuable const&) = delete;
|
proxy_continuable& operator=(proxy_continuable const&) = delete;
|
||||||
|
|
||||||
using Continuation::Continuation;
|
|
||||||
using Continuation::operator();
|
using Continuation::operator();
|
||||||
|
|
||||||
bool operator()(is_ready_arg_t) const noexcept {
|
bool operator()(is_ready_arg_t) const noexcept {
|
||||||
@ -154,7 +153,7 @@ struct attorney {
|
|||||||
util::ownership ownership) {
|
util::ownership ownership) {
|
||||||
using continuation_t = continuable_base<traits::unrefcv_t<T>, //
|
using continuation_t = continuable_base<traits::unrefcv_t<T>, //
|
||||||
traits::unrefcv_t<Annotation>>;
|
traits::unrefcv_t<Annotation>>;
|
||||||
return continuation_t({std::forward<T>(continuation)}, ownership);
|
return continuation_t{std::forward<T>(continuation), ownership};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a continuable_base from the given continuation,
|
/// Creates a continuable_base from the given continuation,
|
||||||
@ -165,8 +164,8 @@ struct attorney {
|
|||||||
static auto create_from(T&& continuation, Hint, util::ownership ownership) {
|
static auto create_from(T&& continuation, Hint, util::ownership ownership) {
|
||||||
using hint_t = traits::unrefcv_t<Hint>;
|
using hint_t = traits::unrefcv_t<Hint>;
|
||||||
using proxy_t = proxy_continuable<hint_t, traits::unrefcv_t<T>>;
|
using proxy_t = proxy_continuable<hint_t, traits::unrefcv_t<T>>;
|
||||||
return continuable_base<proxy_t, hint_t>(
|
return continuable_base<proxy_t, hint_t>{
|
||||||
proxy_t{std::forward<T>(continuation)}, ownership);
|
proxy_t{std::forward<T>(continuation)}, ownership};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the ownership of the given continuable_base
|
/// Returns the ownership of the given continuable_base
|
||||||
@ -873,20 +872,15 @@ void finalize_continuation(Continuation&& continuation) {
|
|||||||
|
|
||||||
/// Deduces to a true type if the given callable data can be wrapped
|
/// Deduces to a true type if the given callable data can be wrapped
|
||||||
/// with the given hint and converted to the given Data.
|
/// with the given hint and converted to the given Data.
|
||||||
template <typename Data, typename Annotation, typename Continuation,
|
template <typename Data, typename Annotation, typename Continuation>
|
||||||
typename = void>
|
|
||||||
struct can_accept_continuation : std::false_type {};
|
struct can_accept_continuation : std::false_type {};
|
||||||
template <typename Data, typename... Args, typename Continuation>
|
template <typename Data, typename... Args, typename Continuation>
|
||||||
struct can_accept_continuation<
|
struct can_accept_continuation<Data, traits::identity<Args...>, Continuation>
|
||||||
Data, traits::identity<Args...>, Continuation,
|
: traits::conjunction<
|
||||||
traits::void_t<
|
traits::is_invocable<Continuation, callbacks::final_callback>,
|
||||||
std::enable_if_t<traits::is_invocable<
|
std::is_convertible<
|
||||||
Continuation, callbacks::final_callback>::value>,
|
proxy_continuable<traits::identity<Args...>, Continuation>,
|
||||||
std::enable_if_t<std::is_convertible<
|
Data>> {};
|
||||||
proxy_continuable<traits::identity<Args...>, Continuation>,
|
|
||||||
Data>::value>>> : std::true_type
|
|
||||||
|
|
||||||
{};
|
|
||||||
|
|
||||||
/// Workaround for GCC bug:
|
/// Workaround for GCC bug:
|
||||||
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
|
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
|
||||||
|
|||||||
@ -43,3 +43,9 @@ TEST(regression_tests, are_multiple_args_mergeable) {
|
|||||||
tp2);
|
tp2);
|
||||||
EXPECT_EQ(count, 20);
|
EXPECT_EQ(count, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recursive instantiation issue which affects Clang and GCC
|
||||||
|
TEST(regression_tests, are_erasures_direct_chainable) {
|
||||||
|
continuable<>(make_ready_continuable())
|
||||||
|
.then(continuable<>(make_ready_continuable()));
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user