Preparation for making expected available inside the base namespace

This commit is contained in:
Denis Blank 2018-01-14 04:26:32 +01:00
parent 55a59fb7f7
commit cb225835d6
6 changed files with 75 additions and 71 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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