Fix a recursive template instantiation issue on clang and gcc

This commit is contained in:
Denis Blank 2018-12-10 05:08:39 +01:00
parent 1320c8eb63
commit 57bb43138b
3 changed files with 23 additions and 22 deletions

View File

@ -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

View File

@ -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

View File

@ -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()));
}