This commit is contained in:
Denis Blank 2018-12-25 11:12:11 +01:00
parent 1cbfcbea6d
commit 96c9f7af99
22 changed files with 282 additions and 163 deletions

View File

@ -835,7 +835,7 @@ constexpr auto make_continuable(Continuation&& continuation) {
template <typename... Args>
auto make_ready_continuable(Args&&... args) {
using detail::base::ready_continuation;
using detail::traits::identity;
using detail::identity;
using detail::traits::unrefcv_t;
return detail::base::attorney::create_from_raw(
ready_continuation<unrefcv_t<Args>...>{std::forward<Args>(args)...},

View File

@ -51,7 +51,7 @@ namespace std {
namespace experimental {
template <typename Data, typename... Args, typename... FunctionArgs>
struct coroutine_traits<
cti::continuable_base<Data, cti::detail::traits::identity<Args...>>,
cti::continuable_base<Data, cti::detail::identity<Args...>>,
FunctionArgs...> {
using promise_type =

View File

@ -32,6 +32,7 @@
#define CONTINUABLE_PRIMITIVES_HPP_INCLUDED
#include <continuable/detail/core/types.hpp>
#include <continuable/detail/utility/identity.hpp>
namespace cti {
/// \defgroup Primitives Primitives
@ -56,6 +57,13 @@ namespace cti {
/// ```
/// \{
/// Represents the tag type that is used to specify the signature hint
/// of a continuable_base or promise_base.
///
/// \since 4.0.0
template <typename... Args>
using signature_arg_t = detail::identity<Args...>;
/// Represents the tag type that is used to query the continuation
/// for whether it resolves the callback instantly with its arguments
/// without having side effects.

View File

@ -62,7 +62,7 @@ class promise_base
/// \cond false
;
template <typename Data, typename... Args>
class promise_base<Data, detail::traits::identity<Args...>>
class promise_base<Data, detail::identity<Args...>>
: detail::util::non_copyable
/// \endcond
{ // clang-format on

View File

@ -158,7 +158,7 @@
/// \since 1.0.0
#define ASSERT_ASYNC_TYPES(CONTINUABLE, ...) \
cti::detail::testing::assert_async_types( \
CONTINUABLE, cti::detail::traits::identity<__VA_ARGS__>{})
CONTINUABLE, cti::detail::identity<__VA_ARGS__>{})
/// Asserts that the continuable is finished with the given exception
///

View File

@ -59,17 +59,12 @@ namespace cti {
template <template <std::size_t, typename...> class CallbackWrapper,
template <std::size_t, typename...> class ContinuationWrapper,
typename... Args>
class continuable_trait {
struct continuable_trait {
using callback = CallbackWrapper<0U, void(Args...)&&,
void(exception_arg_t, exception_t) &&>;
public:
/// The promise type which is used to resolve continuations
using promise = promise_base<callback, detail::traits::identity<Args...>>;
/// The continuable type for the given parameters.
using continuable = continuable_base<
using continuation = continuable_base<
ContinuationWrapper<
// Size the buffer for the small functor optimization so the
// result itself fits in and guarantee that a pointer can
@ -81,7 +76,7 @@ public:
bool(is_ready_arg_t) const, //
std::tuple<Args...>(query_arg_t) //
>,
detail::traits::identity<Args...>>;
detail::identity<Args...>>;
};
/// \}
} // namespace cti

View File

@ -33,7 +33,10 @@
#include <cstddef>
#include <function2/function2.hpp>
#include <continuable/continuable-trait.hpp>
#include <continuable/continuable-base.hpp>
#include <continuable/continuable-primitives.hpp>
#include <continuable/continuable-promise-base.hpp>
#include <continuable/detail/other/erasure.hpp>
namespace cti {
/// \defgroup Types Types
@ -41,66 +44,40 @@ namespace cti {
/// cti::promise promise\endlink facility for type erasure.
/// \{
namespace detail {
/// A type erasure which isn't size adjusted and move only
template <std::size_t, typename... Args>
class type_erasure : public fu2::unique_function<Args...> {
public:
using fu2::unique_function<Args...>::unique_function;
using fu2::unique_function<Args...>::operator=;
using fu2::unique_function<Args...>::operator();
};
/// A function which is size adjusted and move only
template <std::size_t Size, typename... Args>
class sized_type_erasure
: public fu2::function_base<true, false, Size, true, false, Args...> {
public:
using fu2::function_base<true, false, Size, //
true, false, Args...>::function_base;
using fu2::function_base<true, false, Size, //
true, false, Args...>::operator=;
using fu2::function_base<true, false, Size, //
true, false, Args...>::operator();
};
/// We adjust the internal capacity of the outer function wrapper so
/// we don't have to allocate twice when using `continuable<...>`.
template <typename... Args>
using unique_trait_of = continuable_trait< //
type_erasure, sized_type_erasure,
Args... //
>;
/// A type erasure for work objects
class work_type_erasure : public fu2::unique_function<void()> {
public:
using fu2::unique_function<void()>::unique_function;
using fu2::unique_function<void()>::operator=;
using fu2::unique_function<void()>::operator();
};
} // namespace detail
/// Deduces to the preferred continuation capacity for a possible
/// small functor optimization. The given capacity size is always enough to
/// to avoid any allocation when storing ready a continuable_base.
///
/// \since 4.0.0
// template <typename... Args>
// using continuation_capacity = detail::erasure::continuation_capacity<Args...>;
/// Defines a non-copyable continuation type which uses the
/// function2 backend for type erasure.
///
/// Usable like: `continuable<int, float>`
template <typename... Args>
using continuable = typename detail::unique_trait_of<Args...>::continuable;
using continuable = continuable_base<detail::erasure::continuation<Args...>, //
signature_arg_t<Args...>>;
/// Defines a non-copyable promise type which is using the
/// function2 backend for type erasure.
///
/// Usable like: `promise<int, float>`
template <typename... Args>
using promise = typename detail::unique_trait_of<Args...>::promise;
using promise = promise_base<detail::erasure::callback<Args...>, //
signature_arg_t<Args...>>;
/// Defines a non-copyable type erasure which is capable of carrying
/// callable objects passed to executors.
///
/// \since 4.0.0
using work = detail::work_type_erasure;
class work : public fu2::unique_function<void()> {
public:
using fu2::unique_function<void()>::unique_function;
using fu2::unique_function<void()>::operator=;
using fu2::unique_function<void()>::operator();
};
// TODO channel
// TODO sink

View File

@ -52,7 +52,6 @@ namespace cti {}
#include <continuable/continuable-promise-base.hpp>
#include <continuable/continuable-promisify.hpp>
#include <continuable/continuable-result.hpp>
#include <continuable/continuable-trait.hpp>
#include <continuable/continuable-transforms.hpp>
#include <continuable/continuable-traverse-async.hpp>
#include <continuable/continuable-traverse.hpp>

View File

@ -75,13 +75,13 @@ T&& unpack_lazy(container::flat_variant<T>&& value) {
template <typename Continuable>
class continuable_box;
template <typename Data>
class continuable_box<continuable_base<Data, traits::identity<>>> {
class continuable_box<continuable_base<Data, identity<>>> {
continuable_base<Data, traits::identity<>> continuable_;
continuable_base<Data, identity<>> continuable_;
public:
explicit continuable_box(
continuable_base<Data, traits::identity<>>&& continuable)
continuable_base<Data, identity<>>&& continuable)
: continuable_(std::move(continuable)) {
}
@ -101,14 +101,14 @@ public:
}
};
template <typename Data, typename First>
class continuable_box<continuable_base<Data, traits::identity<First>>> {
class continuable_box<continuable_base<Data, identity<First>>> {
continuable_base<Data, traits::identity<First>> continuable_;
continuable_base<Data, identity<First>> continuable_;
lazy_value_t<First> first_;
public:
explicit continuable_box(
continuable_base<Data, traits::identity<First>>&& continuable)
continuable_base<Data, identity<First>>&& continuable)
: continuable_(std::move(continuable)) {
}
@ -130,14 +130,14 @@ public:
};
template <typename Data, typename First, typename Second, typename... Rest>
class continuable_box<
continuable_base<Data, traits::identity<First, Second, Rest...>>> {
continuable_base<Data, identity<First, Second, Rest...>>> {
continuable_base<Data, traits::identity<First, Second, Rest...>> continuable_;
continuable_base<Data, identity<First, Second, Rest...>> continuable_;
lazy_value_t<std::tuple<First, Second, Rest...>> args_;
public:
explicit continuable_box(
continuable_base<Data, traits::identity<First, Second, Rest...>>&&
continuable_base<Data, identity<First, Second, Rest...>>&&
continuable)
: continuable_(std::move(continuable)) {
}
@ -209,12 +209,12 @@ constexpr auto unbox_continuables(Args&&... args) {
namespace detail {
template <typename Callback, typename Data>
constexpr auto finalize_impl(traits::identity<void>, Callback&& callback,
constexpr auto finalize_impl(identity<void>, Callback&& callback,
Data&&) {
return std::forward<Callback>(callback)();
}
template <typename... Args, typename Callback, typename Data>
constexpr auto finalize_impl(traits::identity<std::tuple<Args...>>,
constexpr auto finalize_impl(identity<std::tuple<Args...>>,
Callback&& callback, Data&& data) {
// Call the final callback with the cleaned result
return traits::unpack(std::forward<Callback>(callback),
@ -223,7 +223,7 @@ constexpr auto finalize_impl(traits::identity<std::tuple<Args...>>,
struct hint_mapper {
template <typename... T>
constexpr auto operator()(T...) -> traits::identity<T...> {
constexpr auto operator()(T...) -> identity<T...> {
return {};
}
};
@ -233,7 +233,7 @@ template <typename Callback, typename Data>
constexpr auto finalize_data(Callback&& callback, Data&& data) {
using result_t = decltype(unbox_continuables(std::forward<Data>(data)));
// Guard the final result against void
return detail::finalize_impl(traits::identity<std::decay_t<result_t>>{},
return detail::finalize_impl(identity<std::decay_t<result_t>>{},
std::forward<Callback>(callback),
std::forward<Data>(data));
}

View File

@ -88,30 +88,30 @@ private:
struct result_deducer {
template <typename T>
static auto deduce_one(std::false_type, traits::identity<T>) {
static auto deduce_one(std::false_type, identity<T>) {
static_assert(traits::fail<T>::value,
"Non continuable types except tuple like and homogeneous "
"containers aren't allowed inside an any expression!");
}
template <typename T>
static auto deduce_one(std::true_type, traits::identity<T> id) {
static auto deduce_one(std::true_type, identity<T> id) {
return base::annotation_of(id);
}
template <typename T>
static auto deduce(traversal::container_category_tag<false, false>,
traits::identity<T> id) {
identity<T> id) {
return deduce_one<T>(base::is_continuable<T>{}, id);
}
/// Deduce a homogeneous container
template <bool IsTupleLike, typename T>
static auto deduce(traversal::container_category_tag<true, IsTupleLike>,
traits::identity<T>) {
identity<T>) {
// Deduce the containing type
using element_t = std::decay_t<decltype(*std::declval<T>().begin())>;
return deduce(traversal::container_category_of_t<element_t>{},
traits::identity<element_t>{});
identity<element_t>{});
}
template <typename First, typename... T>
@ -125,19 +125,19 @@ struct result_deducer {
template <std::size_t... I, typename T>
static auto deduce_tuple_like(std::integer_sequence<std::size_t, I...>,
traits::identity<T>) {
identity<T>) {
return deduce_same_hints(deduce(
traversal::container_category_of_t<
std::decay_t<decltype(std::get<I>(std::declval<T>()))>>{},
traits::identity<
identity<
std::decay_t<decltype(std::get<I>(std::declval<T>()))>>{})...);
}
/// Traverse tuple like container
template <typename T>
static auto deduce(traversal::container_category_tag<false, true>,
traits::identity<T> id) {
identity<T> id) {
constexpr auto const size = std::tuple_size<T>::value;
return deduce_tuple_like(std::make_index_sequence<size>{}, id);
@ -172,7 +172,7 @@ struct connection_finalizer<connection_strategy_any_tag> {
static auto finalize(Connection&& connection, util::ownership ownership) {
constexpr auto const signature = decltype(any::result_deducer::deduce(
traversal::container_category_of_t<std::decay_t<Connection>>{},
traits::identity<std::decay_t<Connection>>{})){};
identity<std::decay_t<Connection>>{})){};
return base::attorney::create_from(
[connection =

View File

@ -42,7 +42,7 @@ struct annotation_trait;
/// Specialization for a present signature hint
template <typename... Args>
struct annotation_trait<traits::identity<Args...>> {
struct annotation_trait<identity<Args...>> {
template <typename Continuable>
static Continuable&& finish(Continuable&& continuable) {
return std::forward<Continuable>(continuable);
@ -55,9 +55,9 @@ namespace hints {
///
/// This is the overload taking an arbitrary amount of args
template <typename... HintArgs>
struct from_args : std::common_type<traits::identity<HintArgs...>> {};
struct from_args : std::common_type<identity<HintArgs...>> {};
template <>
struct from_args<void> : std::common_type<traits::identity<>> {};
struct from_args<void> : std::common_type<identity<>> {};
} // namespace hints
} // namespace detail
} // namespace cti

View File

@ -122,7 +122,7 @@ struct ready_continuation<> {
template <typename Hint, typename Continuation>
struct proxy_continuable;
template <typename... Args, typename Continuation>
struct proxy_continuable<traits::identity<Args...>, Continuation>
struct proxy_continuable<identity<Args...>, Continuation>
: Continuation {
explicit proxy_continuable(Continuation continuation)
@ -192,9 +192,9 @@ struct attorney {
/// Returns the signature hint of the given continuable
template <typename Data, typename... Args>
constexpr traits::identity<Args...>
annotation_of(traits::identity<continuable_base<Data, //
traits::identity<Args...>>>) {
constexpr identity<Args...>
annotation_of(identity<continuable_base<Data, //
identity<Args...>>>) {
return {};
}
@ -275,30 +275,30 @@ constexpr void invoke_no_except(T&& callable, Args&&... args) noexcept {
}
template <typename... Args, typename T>
void invoke_void_no_except(traits::identity<exception_arg_t, Args...>,
void invoke_void_no_except(identity<exception_arg_t, Args...>,
T&& /*callable*/) noexcept {
// Don't invoke the next failure handler when being in an exception handler
}
template <typename... Args, typename T>
void invoke_void_no_except(traits::identity<Args...>, T&& callable) noexcept {
void invoke_void_no_except(identity<Args...>, T&& callable) noexcept {
std::forward<T>(callable)();
}
template <typename T, typename... Args>
constexpr auto make_invoker(T&& invoke, traits::identity<Args...>) {
return invoker<std::decay_t<T>, traits::identity<Args...>>(
constexpr auto make_invoker(T&& invoke, identity<Args...>) {
return invoker<std::decay_t<T>, identity<Args...>>(
std::forward<T>(invoke));
}
/// - continuable<?...> -> result(next_callback);
template <typename Data, typename Annotation>
constexpr auto
invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
invoker_of(identity<continuable_base<Data, Annotation>>) {
/// Get the hint of the unwrapped returned continuable
using Type =
decltype(std::declval<continuable_base<Data, Annotation>>().finish());
auto constexpr const hint = base::annotation_of(traits::identify<Type>{});
auto constexpr const hint = base::annotation_of(identify<Type>{});
return make_invoker(
[](auto&& callback, auto&& next_callback, auto&&... args) {
@ -317,7 +317,7 @@ invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
/// - ? -> next_callback(?)
template <typename T>
constexpr auto invoker_of(traits::identity<T>) {
constexpr auto invoker_of(identity<T>) {
return make_invoker(
[](auto&& callback, auto&& next_callback, auto&&... args) {
CONTINUABLE_BLOCK_TRY_BEGIN
@ -329,26 +329,26 @@ constexpr auto invoker_of(traits::identity<T>) {
std::move(result));
CONTINUABLE_BLOCK_TRY_END
},
traits::identify<T>{});
identify<T>{});
}
/// - void -> next_callback()
inline auto invoker_of(traits::identity<void>) {
inline auto invoker_of(identity<void>) {
return make_invoker(
[](auto&& callback, auto&& next_callback, auto&&... args) {
CONTINUABLE_BLOCK_TRY_BEGIN
invoke_callback(std::forward<decltype(callback)>(callback),
std::forward<decltype(args)>(args)...);
invoke_void_no_except(
traits::identity<traits::unrefcv_t<decltype(args)>...>{},
identity<traits::unrefcv_t<decltype(args)>...>{},
std::forward<decltype(next_callback)>(next_callback));
CONTINUABLE_BLOCK_TRY_END
},
traits::identity<>{});
identity<>{});
}
/// - empty_result -> <cancel>
inline auto invoker_of(traits::identity<empty_result>) {
inline auto invoker_of(identity<empty_result>) {
return make_invoker(
[](auto&& callback, auto&& next_callback, auto&&... args) {
(void)next_callback;
@ -362,11 +362,11 @@ inline auto invoker_of(traits::identity<empty_result>) {
(void)result;
CONTINUABLE_BLOCK_TRY_END
},
traits::identity<>{});
identity<>{});
}
/// - exceptional_result -> <throw>
inline auto invoker_of(traits::identity<exceptional_result>) {
inline auto invoker_of(identity<exceptional_result>) {
return make_invoker(
[](auto&& callback, auto&& next_callback, auto&&... args) {
util::unused(callback, next_callback, args...);
@ -381,12 +381,12 @@ inline auto invoker_of(traits::identity<exceptional_result>) {
std::move(result).get_exception());
CONTINUABLE_BLOCK_TRY_END
},
traits::identity<>{});
identity<>{});
}
/// - result<?...> -> next_callback(?...)
template <typename... Args>
auto invoker_of(traits::identity<result<Args...>>) {
auto invoker_of(identity<result<Args...>>) {
return make_invoker(
[](auto&& callback, auto&& next_callback, auto&&... args) {
CONTINUABLE_BLOCK_TRY_BEGIN
@ -416,7 +416,7 @@ auto invoker_of(traits::identity<result<Args...>>) {
// asynchronous chain.
CONTINUABLE_BLOCK_TRY_END
},
traits::identity<Args...>{});
identity<Args...>{});
}
/// Returns a sequenced invoker which is able to invoke
@ -443,15 +443,15 @@ inline auto sequenced_unpack_invoker() {
// - std::pair<?, ?> -> next_callback(?, ?)
template <typename First, typename Second>
constexpr auto invoker_of(traits::identity<std::pair<First, Second>>) {
constexpr auto invoker_of(identity<std::pair<First, Second>>) {
return make_invoker(sequenced_unpack_invoker(),
traits::identity<First, Second>{});
identity<First, Second>{});
}
// - std::tuple<?...> -> next_callback(?...)
template <typename... Args>
constexpr auto invoker_of(traits::identity<std::tuple<Args...>>) {
return make_invoker(sequenced_unpack_invoker(), traits::identity<Args...>{});
constexpr auto invoker_of(identity<std::tuple<Args...>>) {
return make_invoker(sequenced_unpack_invoker(), identity<Args...>{});
}
#undef CONTINUABLE_BLOCK_TRY_BEGIN
@ -510,7 +510,7 @@ template <handle_results HandleResults, typename Base, typename Hint>
struct result_handler_base;
template <typename Base, typename... Args>
struct result_handler_base<handle_results::no, Base,
traits::identity<Args...>> {
identity<Args...>> {
void operator()(Args... args) && {
// Forward the arguments to the next callback
std::move(static_cast<Base*>(this)->next_callback_)(std::move(args)...);
@ -518,13 +518,13 @@ struct result_handler_base<handle_results::no, Base,
};
template <typename Base, typename... Args>
struct result_handler_base<handle_results::yes, Base,
traits::identity<Args...>> {
identity<Args...>> {
/// The operator which is called when the result was provided
void operator()(Args... args) && {
// In order to retrieve the correct decorator we must know what the
// result type is.
constexpr auto result =
traits::identify<decltype(decoration::invoke_callback(
identify<decltype(decoration::invoke_callback(
std::move(static_cast<Base*>(this)->callback_),
std::move(args)...))>{};
@ -556,7 +556,7 @@ struct error_handler_base<handle_errors::forward, Base> {
/// The operator which is called when an error occurred
void operator()(exception_arg_t, exception_t exception) && {
constexpr auto result =
traits::identify<decltype(decoration::invoke_callback(
identify<decltype(decoration::invoke_callback(
std::move(static_cast<Base*>(this)->callback_), exception_arg_t{},
std::move(exception)))>{};
@ -580,16 +580,16 @@ struct callback_base;
template <typename... Args, handle_results HandleResults,
handle_errors HandleErrors, typename Callback, typename Executor,
typename NextCallback>
struct callback_base<traits::identity<Args...>, HandleResults, HandleErrors,
struct callback_base<identity<Args...>, HandleResults, HandleErrors,
Callback, Executor, NextCallback>
: proto::result_handler_base<
HandleResults,
callback_base<traits::identity<Args...>, HandleResults, HandleErrors,
callback_base<identity<Args...>, HandleResults, HandleErrors,
Callback, Executor, NextCallback>,
traits::identity<Args...>>,
identity<Args...>>,
proto::error_handler_base<
HandleErrors,
callback_base<traits::identity<Args...>, HandleResults, HandleErrors,
callback_base<identity<Args...>, HandleResults, HandleErrors,
Callback, Executor, NextCallback>>,
util::non_copyable {
@ -606,14 +606,14 @@ struct callback_base<traits::identity<Args...>, HandleResults, HandleErrors,
/// Pull the result handling operator() in
using proto::result_handler_base<
HandleResults,
callback_base<traits::identity<Args...>, HandleResults, HandleErrors,
callback_base<identity<Args...>, HandleResults, HandleErrors,
Callback, Executor, NextCallback>,
traits::identity<Args...>>::operator();
identity<Args...>>::operator();
/// Pull the error handling operator() in
using proto::error_handler_base<
HandleErrors,
callback_base<traits::identity<Args...>, HandleResults, HandleErrors,
callback_base<identity<Args...>, HandleResults, HandleErrors,
Callback, Executor, NextCallback>>::operator();
/// Resolves the continuation with the given values
@ -684,21 +684,21 @@ struct final_callback : util::non_copyable {
template <typename T, typename... Args>
constexpr auto
next_hint_of(std::integral_constant<handle_results, handle_results::yes>,
traits::identity<T> /*callback*/,
traits::identity<Args...> /*current*/) {
identity<T> /*callback*/,
identity<Args...> /*current*/) {
// Partial Invoke the given callback
using Result = decltype(
decoration::invoke_callback(std::declval<T>(), std::declval<Args>()...));
// Return the hint of thr given invoker
return decltype(decoration::invoker_of(traits::identify<Result>{}).hint()){};
return decltype(decoration::invoker_of(identify<Result>{}).hint()){};
}
/// Don't progress the hint when we don't continue
template <typename T, typename... Args>
constexpr auto
next_hint_of(std::integral_constant<handle_results, handle_results::no>,
traits::identity<T> /*callback*/,
traits::identity<Args...> current) {
identity<T> /*callback*/,
identity<Args...> current) {
return current;
}
@ -730,8 +730,8 @@ struct chained_continuation;
template <typename... Args, typename... NextArgs, handle_results HandleResults,
handle_errors HandleErrors, typename Continuation, typename Callback,
typename Executor>
struct chained_continuation<traits::identity<Args...>,
traits::identity<NextArgs...>, HandleResults,
struct chained_continuation<identity<Args...>,
identity<NextArgs...>, HandleResults,
HandleErrors, Continuation, Callback, Executor> {
Continuation continuation_;
@ -761,7 +761,7 @@ struct chained_continuation<traits::identity<Args...>,
// - Continuation: continuation<[](auto&& callback) { callback("hi"); }>
// - Callback: [](std::string) { }
// - NextCallback: []() { }
auto proxy = callbacks::make_callback<traits::identity<Args...>,
auto proxy = callbacks::make_callback<identity<Args...>,
HandleResults, HandleErrors>(
std::move(callback_), std::move(executor_),
std::forward<decltype(next_callback)>(next_callback));
@ -793,7 +793,7 @@ struct chained_continuation<traits::identity<Args...>,
template <typename... Args, typename... NextArgs, handle_results HandleResults,
handle_errors HandleErrors, typename Callback, typename Executor>
struct chained_continuation<
traits::identity<Args...>, traits::identity<NextArgs...>, HandleResults,
identity<Args...>, identity<NextArgs...>, HandleResults,
HandleErrors, ready_continuation<Args...>, Callback, Executor> {
ready_continuation<Args...> continuation_;
@ -815,7 +815,7 @@ struct chained_continuation<
template <typename NextCallback>
void operator()(NextCallback&& next_callback) {
auto proxy = callbacks::make_callback<traits::identity<Args...>,
auto proxy = callbacks::make_callback<identity<Args...>,
HandleResults, HandleErrors>(
std::move(callback_), std::move(executor_),
std::forward<decltype(next_callback)>(next_callback));
@ -851,10 +851,10 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
static_assert(is_continuable<std::decay_t<Continuation>>{},
"Expected a continuation!");
using Hint = decltype(base::annotation_of(traits::identify<Continuation>()));
using Hint = decltype(base::annotation_of(identify<Continuation>()));
constexpr auto next_hint =
next_hint_of(std::integral_constant<handle_results, HandleResults>{},
traits::identify<decltype(callback)>{}, Hint{});
identify<decltype(callback)>{}, Hint{});
auto ownership = attorney::ownership_of(continuation);
auto data =
@ -885,11 +885,11 @@ void finalize_continuation(Continuation&& continuation) {
template <typename Data, typename Annotation, typename Continuation>
struct can_accept_continuation : std::false_type {};
template <typename Data, typename... Args, typename Continuation>
struct can_accept_continuation<Data, traits::identity<Args...>, Continuation>
struct can_accept_continuation<Data, identity<Args...>, Continuation>
: traits::conjunction<
traits::is_invocable<Continuation, callbacks::final_callback>,
std::is_convertible<
proxy_continuable<traits::identity<Args...>, Continuation>,
proxy_continuable<identity<Args...>, Continuation>,
Data>> {};
/// Workaround for GCC bug:

View File

@ -33,6 +33,7 @@
#include <utility>
#include <continuable/detail/features.hpp>
#include <continuable/detail/utility/identity.hpp>
#ifndef CONTINUABLE_WITH_CUSTOM_ERROR_TYPE
#ifndef CONTINUABLE_WITH_NO_EXCEPTIONS

View File

@ -57,7 +57,7 @@ using std::experimental::coroutine_handle;
template <typename T>
struct result_from_identity;
template <typename... T>
struct result_from_identity<traits::identity<T...>> {
struct result_from_identity<identity<T...>> {
using result_t = result<T...>;
};
@ -65,7 +65,7 @@ struct result_from_identity<traits::identity<T...>> {
/// for waiting on a continuable in a stackless coroutine.
template <typename Continuable>
class awaitable {
using hint_t = decltype(base::annotation_of(traits::identify<Continuable>{}));
using hint_t = decltype(base::annotation_of(identify<Continuable>{}));
using result_t = typename result_from_identity<hint_t>::result_t;
/// The continuable which is invoked upon suspension

View File

@ -0,0 +1,97 @@
/*
/~` _ _ _|_. _ _ |_ | _
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.0.0
Copyright(c) 2015 - 2018 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**/
#ifndef CONTINUABLE_DETAIL_ERASURE_HPP_INCLUDED
#define CONTINUABLE_DETAIL_ERASURE_HPP_INCLUDED
#include <type_traits>
#include <function2/function2.hpp>
#include <continuable/detail/core/base.hpp>
#include <continuable/detail/features.hpp>
#include <continuable/detail/utility/traits.hpp>
#include <continuable/detail/utility/util.hpp>
namespace cti {
namespace detail {
namespace erasure {
/*template <typename... Args>
using continuation_capacity = std::integral_constant<
std::size_t, (sizeof(base::ready_continuation<Args...>) < sizeof(void*)
? sizeof(void*)
: sizeof(base::ready_continuation<Args...>))>;*/
template <std::size_t Size>
struct sized {
template <typename... Args>
using erasure_base_t = //
fu2::function_base<true, false, Size, //
true, false, Args...>;
};
template <template <typename...> class Wrapper, typename... Args>
using callback_of_t = Wrapper<void(Args...)&&, //
void(exception_arg_t, exception_t) &&>;
template <typename... Args>
using callback_base_t = callback_of_t<sized<0>::erasure_base_t, Args...>;
template <typename... Args>
class callback : public callback_base_t<Args...> {
public:
using callback_base_t<Args...>::callback_base_t;
using callback_base_t<Args...>::operator=;
using callback_base_t<Args...>::operator();
};
template <template <typename...> class Wrapper, typename Promise,
typename... Args>
using continuation_of_t = Wrapper<void(Promise), //
bool(is_ready_arg_t) const, //
std::tuple<Args...>(query_arg_t)>;
template <typename... Args>
using continuation_base_t =
continuation_of_t<sized<0 /*
continuation_capacity<Args...>::value*/>::erasure_base_t,
promise_base<callback<Args...>, signature_arg_t<Args>...>,
Args...>;
template <typename... Args>
class continuation : public continuation_base_t<Args...> {
public:
using continuation_base_t<Args...>::callback_base_t;
using continuation_base_t<Args...>::operator=;
using continuation_base_t<Args...>::operator();
};
} // namespace erasure
} // namespace detail
} // namespace cti
#endif // CONTINUABLE_DETAIL_ERASURE_HPP_INCLUDED

View File

@ -179,15 +179,15 @@ template <typename... Expected>
struct assert_async_types_validator {
template <typename... Actual>
void operator()(Actual...) {
static_assert(std::is_same<traits::identity<Actual...>,
traits::identity<Expected...>>::value,
static_assert(std::is_same<identity<Actual...>,
identity<Expected...>>::value,
"The called arguments don't match with the expected ones!");
}
};
template <typename C, typename... Args>
void assert_async_types(C&& continuable,
traits::identity<Args...> /*expected*/) {
identity<Args...> /*expected*/) {
assert_async_validation(std::forward<C>(continuable),
assert_async_types_validator<Args...>{});
}

View File

@ -77,7 +77,7 @@ template <typename Hint>
class promise_callback;
template <typename... Args>
class promise_callback<traits::identity<Args...>>
class promise_callback<identity<Args...>>
: public future_trait<Args...> {
typename future_trait<Args...>::promise_t promise_;
@ -119,7 +119,7 @@ template <typename Data, typename Annotation>
auto as_future(continuable_base<Data, Annotation>&& continuable) {
// Create the promise which is able to supply the current arguments
constexpr auto const hint =
base::annotation_of(traits::identify<decltype(continuable)>{});
base::annotation_of(identify<decltype(continuable)>{});
promise_callback<std::decay_t<decltype(hint)>> callback;
(void)hint;

View File

@ -62,7 +62,7 @@ template <typename T>
using align_of_helper = std::integral_constant<std::size_t, alignof(T)>;
template <typename... T>
constexpr auto storage_of_impl(traits::identity<T...>) {
constexpr auto storage_of_impl(identity<T...>) {
constexpr auto size = max_element_of({(size_of_helper<T>::value)...});
constexpr auto align = max_element_of({(align_of_helper<T>::value)...});
return std::aligned_storage_t<size, align>{};
@ -70,7 +70,7 @@ constexpr auto storage_of_impl(traits::identity<T...>) {
/// Declares the aligned storage union for the given types
template <typename... T>
using storage_of_t = decltype(storage_of_impl(traits::identity<T...>{}));
using storage_of_t = decltype(storage_of_impl(identity<T...>{}));
/// The value fpr the empty slot
using slot_t = std::uint8_t;

View File

@ -0,0 +1,54 @@
/*
/~` _ _ _|_. _ _ |_ | _
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.0.0
Copyright(c) 2015 - 2018 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**/
#ifndef CONTINUABLE_DETAIL_IDENTITY_HPP_INCLUDED
#define CONTINUABLE_DETAIL_IDENTITY_HPP_INCLUDED
#include <type_traits>
#include <continuable/detail/features.hpp>
namespace cti {
namespace detail {
/// A tagging type for wrapping other types
template <typename... T>
struct identity {};
template <typename>
struct is_identity : std::false_type {};
template <typename... Args>
struct is_identity<identity<Args...>> : std::true_type {};
template <typename T>
using identify = std::conditional_t<is_identity<std::decay_t<T>>::value, T,
identity<std::decay_t<T>>>;
} // namespace detail
} // namespace cti
#endif // CONTINUABLE_DETAIL_IDENTITY_HPP_INCLUDED

View File

@ -36,6 +36,7 @@
#include <type_traits>
#include <utility>
#include <continuable/detail/features.hpp>
#include <continuable/detail/utility/identity.hpp>
namespace cti {
namespace detail {
@ -69,19 +70,6 @@ auto make_flat_tuple(T&&... args) {
return std::tuple<T...>{std::forward<T>(args)...};
}
/// A tagging type for wrapping other types
template <typename... T>
struct identity {};
template <typename>
struct is_identity : std::false_type {};
template <typename... Args>
struct is_identity<identity<Args...>> : std::true_type {};
template <typename T>
using identify = std::conditional_t<is_identity<std::decay_t<T>>::value, T,
identity<std::decay_t<T>>>;
#if defined(CONTINUABLE_HAS_CXX17_VOID_T)
using std::void_t;
#else

View File

@ -134,7 +134,7 @@ TYPED_TEST(single_dimension_tests, are_exceptions_partial_applyable) {
handled = false;
ASSERT_ASYNC_INCOMPLETION(
this->supply_exception(supply_test_exception(),
detail::traits::identity<int, int>{})
detail::identity<int, int>{})
.fail([&]() -> result<int, int> {
EXPECT_FALSE(handled);
handled = true;

View File

@ -34,7 +34,7 @@
#include <continuable/continuable-testing.hpp>
#include <continuable/continuable.hpp>
using cti::detail::traits::identity;
using cti::detail::identity;
using cti::detail::util::unused;
inline auto to_hint(identity<> /*hint*/) {
@ -113,9 +113,9 @@ struct provide_copyable {
struct provide_unique {
template <typename... Args, typename... Hint, typename T>
auto make(identity<Args...>, identity<Hint...>, T&& callback) {
return cti::make_continuable<Hint...>(
[callback = std::forward<T>(callback),
guard = std::make_unique<int>(0)](auto&&... args) mutable {
return cti::make_continuable<Hint...>([
callback = std::forward<T>(callback), guard = std::make_unique<int>(0)
](auto&&... args) mutable {
(void)(*guard);
return std::move(callback)(std::forward<decltype(args)>(args)...);
});