Improve the constexprness

This commit is contained in:
Denis Blank 2018-01-30 00:13:54 +01:00
parent 24201d5106
commit 933d773c4c
6 changed files with 39 additions and 35 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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