mirror of
https://github.com/Naios/continuable.git
synced 2025-12-08 01:36:46 +08:00
Preparation for making expected available inside the base namespace
This commit is contained in:
parent
55a59fb7f7
commit
cb225835d6
@ -42,7 +42,6 @@
|
||||
#include <continuable/detail/expected.hpp>
|
||||
#include <continuable/detail/features.hpp>
|
||||
#include <continuable/detail/hints.hpp>
|
||||
#include <continuable/detail/traits.hpp>
|
||||
#include <continuable/detail/types.hpp>
|
||||
#include <continuable/detail/util.hpp>
|
||||
|
||||
@ -53,54 +52,6 @@
|
||||
namespace cti {
|
||||
namespace detail {
|
||||
namespace awaiting {
|
||||
namespace detail {
|
||||
struct void_guard_tag {};
|
||||
|
||||
template <typename T>
|
||||
struct result_trait;
|
||||
template <>
|
||||
struct result_trait<traits::identity<>> {
|
||||
using expected = util::expected<void_guard_tag>;
|
||||
|
||||
static constexpr void_guard_tag wrap() noexcept {
|
||||
return {};
|
||||
}
|
||||
static void unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
(void)e;
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct result_trait<traits::identity<T>> {
|
||||
using expected = util::expected<T>;
|
||||
|
||||
static auto wrap(T arg) {
|
||||
return std::move(arg);
|
||||
}
|
||||
static auto unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
return std::move(e.get_value());
|
||||
}
|
||||
};
|
||||
template <typename First, typename Second, typename... Rest>
|
||||
struct result_trait<traits::identity<First, Second, Rest...>> {
|
||||
using expected = util::expected<std::tuple<First, Second, Rest...>>;
|
||||
|
||||
static auto wrap(First first, Second second, Rest... rest) {
|
||||
return std::make_tuple(std::move(first), std::move(second),
|
||||
std::move(rest)...);
|
||||
}
|
||||
static auto unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
return std::move(e.get_value());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Continuable>
|
||||
using result_trait_t =
|
||||
result_trait<decltype(base::hint_of(traits::identity_of<Continuable>()))>;
|
||||
} // namespace detail
|
||||
|
||||
/// We import the coroutine handle in our namespace
|
||||
using std::experimental::coroutine_handle;
|
||||
|
||||
@ -108,7 +59,7 @@ using std::experimental::coroutine_handle;
|
||||
/// for waiting on a continuable in a stackless coroutine.
|
||||
template <typename Continuable>
|
||||
class awaitable {
|
||||
using trait_t = detail::result_trait_t<Continuable>;
|
||||
using trait_t = util::expected_result_trait_t<Continuable>;
|
||||
|
||||
/// The continuable which is invoked upon suspension
|
||||
Continuable continuable_;
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include <continuable/continuable-api.hpp>
|
||||
#include <continuable/detail/expected.hpp>
|
||||
#include <continuable/detail/features.hpp>
|
||||
#include <continuable/detail/hints.hpp>
|
||||
#include <continuable/detail/traits.hpp>
|
||||
@ -63,21 +64,6 @@ namespace detail {
|
||||
/// base::finalize_continuation(base::continuation<auto> continuation)
|
||||
/// -> void
|
||||
namespace base {
|
||||
/// Returns the signature hint of the given continuable
|
||||
template <typename T>
|
||||
constexpr auto hint_of(traits::identity<T>) {
|
||||
static_assert(traits::fail<T>::value,
|
||||
"Expected a continuation with an existing signature hint!");
|
||||
return traits::identity_of<void>();
|
||||
}
|
||||
/// Returns the signature hint of the given continuable
|
||||
template <typename Data, typename... Args>
|
||||
constexpr auto
|
||||
hint_of(traits::identity<
|
||||
continuable_base<Data, hints::signature_hint_tag<Args...>>>) {
|
||||
return hints::signature_hint_tag<Args...>{};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_continuation : std::false_type {};
|
||||
template <typename Data, typename Annotation>
|
||||
@ -179,6 +165,8 @@ invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
|
||||
using Type = decltype(attorney::materialize(
|
||||
std::declval<continuable_base<Data, Annotation>>()));
|
||||
|
||||
auto constexpr const hint = hints::hint_of(traits::identity_of<Type>());
|
||||
|
||||
return make_invoker(
|
||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||
@ -191,7 +179,7 @@ invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
|
||||
std::forward<decltype(next_callback)>(next_callback));
|
||||
CONTINUABLE_BLOCK_TRY_END
|
||||
},
|
||||
hint_of(traits::identity_of<Type>()));
|
||||
hint);
|
||||
}
|
||||
|
||||
/// - ? -> next_callback(?)
|
||||
@ -510,7 +498,7 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
|
||||
static_assert(is_continuation<std::decay_t<Continuation>>{},
|
||||
"Expected a continuation!");
|
||||
|
||||
using Hint = decltype(hint_of(traits::identity_of(continuation)));
|
||||
using Hint = decltype(hints::hint_of(traits::identity_of(continuation)));
|
||||
auto next_hint =
|
||||
next_hint_of(std::integral_constant<handle_results, HandleResults>{},
|
||||
traits::identity_of(callback), Hint{});
|
||||
|
||||
@ -341,7 +341,7 @@ auto finalize_composition(
|
||||
|
||||
// Merge all signature hints together
|
||||
auto signature = traits::unpack(composition, [](auto&... entries) {
|
||||
return traits::merge(base::hint_of(traits::identity_of(entries))...);
|
||||
return traits::merge(hints::hint_of(traits::identity_of(entries))...);
|
||||
});
|
||||
|
||||
return base::attorney::create(
|
||||
@ -369,7 +369,7 @@ auto finalize_composition(
|
||||
|
||||
// This is the length of the arguments of the current continuable
|
||||
auto arg_size =
|
||||
traits::pack_size_of(base::hint_of(traits::identity_of(entry)));
|
||||
traits::pack_size_of(hints::hint_of(traits::identity_of(entry)));
|
||||
|
||||
// The next position in the result tuple
|
||||
auto next = current.second + arg_size;
|
||||
@ -438,7 +438,7 @@ auto finalize_composition(
|
||||
// Determine the shared result between all continuations
|
||||
auto signature = traits::unpack(composition, [](auto const&... args) {
|
||||
return common_result_of(hints::signature_hint_tag<>{},
|
||||
base::hint_of(traits::identity_of(args))...);
|
||||
hints::hint_of(traits::identity_of(args))...);
|
||||
});
|
||||
|
||||
return base::attorney::create(
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
#include <utility>
|
||||
|
||||
#include <continuable/continuable-api.hpp>
|
||||
#include <continuable/detail/hints.hpp>
|
||||
#include <continuable/detail/traits.hpp>
|
||||
#include <continuable/detail/types.hpp>
|
||||
#include <continuable/detail/util.hpp>
|
||||
|
||||
@ -331,6 +333,54 @@ private:
|
||||
this->slot_ = slot;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
struct void_guard_tag {};
|
||||
|
||||
template <typename T>
|
||||
struct expected_result_trait;
|
||||
template <>
|
||||
struct expected_result_trait<traits::identity<>> {
|
||||
using expected = util::expected<void_guard_tag>;
|
||||
|
||||
static constexpr void_guard_tag wrap() noexcept {
|
||||
return {};
|
||||
}
|
||||
static void unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
(void)e;
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct expected_result_trait<traits::identity<T>> {
|
||||
using expected = util::expected<T>;
|
||||
|
||||
static auto wrap(T arg) {
|
||||
return std::move(arg);
|
||||
}
|
||||
static auto unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
return std::move(e.get_value());
|
||||
}
|
||||
};
|
||||
template <typename First, typename Second, typename... Rest>
|
||||
struct expected_result_trait<traits::identity<First, Second, Rest...>> {
|
||||
using expected = util::expected<std::tuple<First, Second, Rest...>>;
|
||||
|
||||
static auto wrap(First first, Second second, Rest... rest) {
|
||||
return std::make_tuple(std::move(first), std::move(second),
|
||||
std::move(rest)...);
|
||||
}
|
||||
static auto unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
return std::move(e.get_value());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename Continuable>
|
||||
using expected_result_trait_t = detail::expected_result_trait<decltype(
|
||||
hints::hint_of(traits::identity_of<Continuable>()))>;
|
||||
} // namespace util
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
|
||||
@ -50,6 +50,21 @@ template <typename>
|
||||
struct is_absent_hint : std::false_type {};
|
||||
template <>
|
||||
struct is_absent_hint<absent_signature_hint_tag> : std::true_type {};
|
||||
|
||||
/// Returns the signature hint of the given continuable
|
||||
template <typename T>
|
||||
constexpr auto hint_of(traits::identity<T>) {
|
||||
static_assert(traits::fail<T>::value,
|
||||
"Expected a continuation with an existing signature hint!");
|
||||
return traits::identity_of<void>();
|
||||
}
|
||||
/// Returns the signature hint of the given continuable
|
||||
template <typename Data, typename... Args>
|
||||
constexpr auto
|
||||
hint_of(traits::identity<
|
||||
continuable_base<Data, hints::signature_hint_tag<Args...>>>) {
|
||||
return hints::signature_hint_tag<Args...>{};
|
||||
}
|
||||
} // namespace hints
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
|
||||
@ -120,7 +120,7 @@ public:
|
||||
template <typename Data, typename Annotation>
|
||||
auto as_future(continuable_base<Data, Annotation>&& continuable) {
|
||||
// Create the promise which is able to supply the current arguments
|
||||
auto hint = base::hint_of(traits::identity_of(continuable));
|
||||
auto hint = hints::hint_of(traits::identity_of(continuable));
|
||||
|
||||
promise_callback<std::decay_t<decltype(hint)>> callback;
|
||||
(void)hint;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user