mirror of
https://github.com/Naios/continuable.git
synced 2025-12-08 01:36:46 +08:00
Improve the constexprness
This commit is contained in:
parent
24201d5106
commit
933d773c4c
@ -68,7 +68,7 @@ class awaitable {
|
||||
typename trait_t::expected_type result_;
|
||||
|
||||
public:
|
||||
explicit awaitable(Continuable&& continuable)
|
||||
explicit constexpr awaitable(Continuable&& continuable)
|
||||
: continuable_(std::move(continuable)) {
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ private:
|
||||
/// Converts a continuable into an awaitable object as described by
|
||||
/// the C++ coroutine TS.
|
||||
template <typename T>
|
||||
auto create_awaiter(T&& continuable) {
|
||||
constexpr auto create_awaiter(T&& continuable) {
|
||||
return awaitable<std::decay_t<T>>(std::forward<T>(continuable));
|
||||
}
|
||||
} // namespace awaiting
|
||||
|
||||
@ -171,7 +171,7 @@ 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>());
|
||||
auto constexpr const hint = hints::hint_of(traits::identify<Type>{});
|
||||
|
||||
return make_invoker(
|
||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||
@ -202,7 +202,7 @@ constexpr auto invoker_of(traits::identity<T>) {
|
||||
std::move(result));
|
||||
CONTINUABLE_BLOCK_TRY_END
|
||||
},
|
||||
traits::identity_of<T>());
|
||||
traits::identify<T>{});
|
||||
}
|
||||
|
||||
/// - void -> next_callback()
|
||||
@ -322,8 +322,8 @@ struct result_handler_base<handle_results::yes, Base,
|
||||
void operator()(Args... args) && {
|
||||
// In order to retrieve the correct decorator we must know what the
|
||||
// result type is.
|
||||
auto result = traits::identity_of<decltype(util::partial_invoke(
|
||||
std::move(static_cast<Base*>(this)->callback_), std::move(args)...))>();
|
||||
auto result = traits::identify<decltype(util::partial_invoke(
|
||||
std::move(static_cast<Base*>(this)->callback_), std::move(args)...))>{};
|
||||
|
||||
// Pick the correct invoker that handles decorating of the result
|
||||
auto invoker = decoration::invoker_of(result);
|
||||
@ -478,7 +478,7 @@ next_hint_of(std::integral_constant<handle_results, handle_results::yes>,
|
||||
util::partial_invoke(std::declval<T>(), std::declval<Args>()...));
|
||||
|
||||
// Return the hint of thr given invoker
|
||||
return decoration::invoker_of(traits::identity_of<Result>()).hint();
|
||||
return decltype(decoration::invoker_of(traits::identify<Result>{}).hint()){};
|
||||
}
|
||||
/// Don't progress the hint when we don't continue
|
||||
template <typename T, typename... Args>
|
||||
@ -506,9 +506,9 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
|
||||
"Expected a continuation!");
|
||||
|
||||
using Hint = decltype(hints::hint_of(traits::identity_of(continuation)));
|
||||
auto next_hint =
|
||||
constexpr auto next_hint =
|
||||
next_hint_of(std::integral_constant<handle_results, HandleResults>{},
|
||||
traits::identity_of(callback), Hint{});
|
||||
traits::identify<decltype(callback)>{}, Hint{});
|
||||
|
||||
// TODO consume only the data here so the freeze isn't needed
|
||||
auto ownership_ = attorney::ownership_of(continuation);
|
||||
|
||||
@ -170,7 +170,7 @@ class all_result_submitter : public std::enable_shared_from_this<
|
||||
void complete_one() {
|
||||
assert((left_ > 0U) && "Expected that the submitter isn't finished!");
|
||||
|
||||
auto current = --left_;
|
||||
auto const current = --left_;
|
||||
if (!current) {
|
||||
invoke();
|
||||
}
|
||||
@ -330,6 +330,14 @@ auto make_all_result_submitter(Callback&& callback,
|
||||
std::forward<decltype(callback)>(callback));
|
||||
}
|
||||
|
||||
/// A callable object to merge multiple signature hints together
|
||||
struct entry_merger {
|
||||
template <typename... T>
|
||||
constexpr auto operator()(T&... entries) noexcept {
|
||||
return traits::merge(hints::hint_of(traits::identity_of(entries))...);
|
||||
}
|
||||
};
|
||||
|
||||
/// Finalizes the all logic of a given composition
|
||||
template <typename Data>
|
||||
auto finalize_composition(
|
||||
@ -340,9 +348,7 @@ auto finalize_composition(
|
||||
auto composition = base::attorney::consume_data(std::move(continuation));
|
||||
|
||||
// Merge all signature hints together
|
||||
auto signature = traits::unpack(composition, [](auto&... entries) {
|
||||
return traits::merge(hints::hint_of(traits::identity_of(entries))...);
|
||||
});
|
||||
constexpr auto signature = traits::unpack(composition, entry_merger{});
|
||||
|
||||
return base::attorney::create(
|
||||
[ signature,
|
||||
@ -351,10 +357,10 @@ auto finalize_composition(
|
||||
// std::pair<size_constant<?>, size_constant<?>>
|
||||
// ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
|
||||
// Continuation pos Result pos
|
||||
auto begin = std::make_pair(traits::size_constant_of<0>(),
|
||||
traits::size_constant_of<0>());
|
||||
auto pack = traits::identity_of(composition);
|
||||
auto end = traits::pack_size_of(pack);
|
||||
constexpr auto begin = std::make_pair(traits::size_constant_of<0>(),
|
||||
traits::size_constant_of<0>());
|
||||
constexpr auto pack = traits::identify<decltype(composition)>{};
|
||||
constexpr auto end = traits::pack_size_of(pack);
|
||||
auto condition = [=](auto pos) { return pos.first < end; };
|
||||
|
||||
// Create the result submitter which caches all results and invokes
|
||||
@ -368,11 +374,11 @@ auto finalize_composition(
|
||||
std::move(std::get<decltype(current.first)::value>(composition));
|
||||
|
||||
// This is the length of the arguments of the current continuable
|
||||
auto arg_size =
|
||||
constexpr auto arg_size =
|
||||
traits::pack_size_of(hints::hint_of(traits::identity_of(entry)));
|
||||
|
||||
// The next position in the result tuple
|
||||
auto next = current.second + arg_size;
|
||||
constexpr auto next = current.second + arg_size;
|
||||
|
||||
// Invoke the continuation with the associated submission callback
|
||||
base::attorney::invoke_continuation(
|
||||
@ -395,7 +401,7 @@ auto make_any_result_submitter(Callback&& callback) {
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T first_of(traits::identity<T, Args...>) noexcept;
|
||||
constexpr T first_of(traits::identity<T, Args...>) noexcept;
|
||||
|
||||
template <typename Signature, typename... Args>
|
||||
constexpr auto common_result_of(Signature signature,
|
||||
|
||||
@ -387,7 +387,7 @@ struct expected_result_trait<traits::identity<First, Second, Rest...>> {
|
||||
|
||||
template <typename Continuable>
|
||||
using expected_result_trait_t = detail::expected_result_trait<decltype(
|
||||
hints::hint_of(traits::identity_of<Continuable>()))>;
|
||||
hints::hint_of(traits::identify<Continuable>{}))>;
|
||||
} // namespace util
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
|
||||
@ -51,12 +51,12 @@ 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
|
||||
/// 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>();
|
||||
return traits::identity<void>{};
|
||||
}
|
||||
/// Returns the signature hint of the given continuable
|
||||
template <typename Data, typename... Args>
|
||||
|
||||
@ -60,7 +60,7 @@ struct constant : std::integral_constant<T, Value> {
|
||||
/// \cond false
|
||||
#define CTI__INST(CTI__OP) \
|
||||
template <typename OT, OT OValue> \
|
||||
/*constexpr*/ auto operator CTI__OP(std::integral_constant<OT, OValue>) \
|
||||
constexpr auto operator CTI__OP(std::integral_constant<OT, OValue>) \
|
||||
const noexcept { \
|
||||
return constant<decltype((Value CTI__OP OValue)), \
|
||||
(Value CTI__OP OValue)>{}; \
|
||||
@ -68,7 +68,7 @@ struct constant : std::integral_constant<T, Value> {
|
||||
CTI__FOR_EACH_INTEGRAL_BIN_OP(CTI__INST)
|
||||
#undef CTI__INST
|
||||
#define CTI__INST(CTI__OP) \
|
||||
/*constexpr*/ auto operator CTI__OP() const noexcept { \
|
||||
constexpr auto operator CTI__OP() const noexcept { \
|
||||
return constant<decltype((CTI__OP Value)), (CTI__OP Value)>{}; \
|
||||
}
|
||||
CTI__FOR_EACH_INTEGRAL_UNA_OP(CTI__INST)
|
||||
@ -81,14 +81,14 @@ struct constant<bool, Value> : std::integral_constant<bool, Value> {
|
||||
/// \cond false
|
||||
#define CTI__INST(CTI__OP) \
|
||||
template <typename OT, OT OValue> \
|
||||
/*constexpr*/ auto operator CTI__OP(std::integral_constant<bool, OValue>) \
|
||||
constexpr auto operator CTI__OP(std::integral_constant<bool, OValue>) \
|
||||
const noexcept { \
|
||||
return constant<bool, (Value CTI__OP OValue)>{}; \
|
||||
}
|
||||
CTI__FOR_EACH_BOOLEAN_BIN_OP(CTI__INST)
|
||||
#undef CTI__INST
|
||||
#define CTI__INST(CTI__OP) \
|
||||
/*constexpr*/ auto operator CTI__OP() const noexcept { \
|
||||
constexpr auto operator CTI__OP() const noexcept { \
|
||||
return constant<bool, CTI__OP Value>{}; \
|
||||
}
|
||||
CTI__FOR_EACH_BOOLEAN_UNA_OP(CTI__INST)
|
||||
@ -142,7 +142,7 @@ template <typename... Args>
|
||||
struct is_identity<identity<Args...>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
identity<std::decay_t<T>> constexpr identity_of(T const& /*type*/) noexcept {
|
||||
constexpr identity<std::decay_t<T>> identity_of(T const& /*type*/) noexcept {
|
||||
return {};
|
||||
}
|
||||
template <typename... Args>
|
||||
@ -150,14 +150,12 @@ constexpr identity<Args...> identity_of(identity<Args...> /*type*/) noexcept {
|
||||
return {};
|
||||
}
|
||||
template <typename T>
|
||||
constexpr auto identity_of() noexcept {
|
||||
return std::conditional_t<is_identity<std::decay_t<T>>::value, T,
|
||||
identity<std::decay_t<T>>>{};
|
||||
}
|
||||
using identify = std::conditional_t<is_identity<std::decay_t<T>>::value, T,
|
||||
identity<std::decay_t<T>>>;
|
||||
|
||||
template <std::size_t I, typename... T>
|
||||
constexpr auto get(identity<T...>) noexcept {
|
||||
return identity_of<at_t<I, T...>>();
|
||||
return identify<at_t<I, T...>>{};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
@ -327,9 +325,9 @@ constexpr auto unpack(F&& firstSequenceable, S&& secondSequenceable,
|
||||
}
|
||||
/// Calls the given unpacker with the content of the given sequenceable
|
||||
template <typename F, typename U>
|
||||
auto unpack(F&& firstSequenceable, U&& unpacker) {
|
||||
constexpr auto unpack(F&& firstSequenceable, U&& unpacker) {
|
||||
return unpack(std::forward<F>(firstSequenceable), std::forward<U>(unpacker),
|
||||
sequence_of(identity_of(firstSequenceable)));
|
||||
sequence_of(identify<decltype(firstSequenceable)>{}));
|
||||
}
|
||||
/// Calls the given unpacker with the content of the given sequenceables
|
||||
template <typename F, typename S, typename U>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user