mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Add constexpr and noexcept where possible
This commit is contained in:
parent
7a46100b6a
commit
705138dab5
@ -143,16 +143,17 @@ template <bool Value> using bool_constant = constant<bool, Value>;
|
|||||||
template <std::size_t Value> using size_constant = constant<std::size_t, Value>;
|
template <std::size_t Value> using size_constant = constant<std::size_t, Value>;
|
||||||
|
|
||||||
template <typename T, bool Value>
|
template <typename T, bool Value>
|
||||||
auto constant_of(std::integral_constant<T, Value> /*value*/ = {}) {
|
constexpr auto constant_of(std::integral_constant<T, Value> /*value*/ = {}) {
|
||||||
return constant<T, Value>{};
|
return constant<T, Value>{};
|
||||||
}
|
}
|
||||||
template <std::size_t Value>
|
template <std::size_t Value>
|
||||||
auto size_constant_of(
|
constexpr auto
|
||||||
std::integral_constant<std::size_t, Value> /*value*/ = {}) {
|
size_constant_of(std::integral_constant<std::size_t, Value> /*value*/ = {}) {
|
||||||
return size_constant<Value>{};
|
return size_constant<Value>{};
|
||||||
}
|
}
|
||||||
template <bool Value>
|
template <bool Value>
|
||||||
auto bool_constant_of(std::integral_constant<bool, Value> /*value*/ = {}) {
|
constexpr auto
|
||||||
|
bool_constant_of(std::integral_constant<bool, Value> /*value*/ = {}) {
|
||||||
return bool_constant<Value>{};
|
return bool_constant<Value>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,24 +178,26 @@ template <typename> struct is_identity : std::false_type {};
|
|||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
struct is_identity<identity<Args...>> : std::true_type {};
|
struct is_identity<identity<Args...>> : std::true_type {};
|
||||||
|
|
||||||
template <typename T> identity<std::decay_t<T>> identity_of(T const& /*type*/) {
|
template <typename T>
|
||||||
|
identity<std::decay_t<T>> constexpr identity_of(T const& /*type*/) noexcept {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
identity<Args...> identity_of(identity<Args...> /*type*/) {
|
constexpr identity<Args...> identity_of(identity<Args...> /*type*/) noexcept {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
template <typename T> auto identity_of() {
|
template <typename T> constexpr auto identity_of() noexcept {
|
||||||
return std::conditional_t<is_identity<std::decay_t<T>>::value, T,
|
return std::conditional_t<is_identity<std::decay_t<T>>::value, T,
|
||||||
identity<std::decay_t<T>>>{};
|
identity<std::decay_t<T>>>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t I, typename... T> auto get(identity<T...>) {
|
template <std::size_t I, typename... T>
|
||||||
|
constexpr auto get(identity<T...>) noexcept {
|
||||||
return identity_of<at_t<I, T...>>();
|
return identity_of<at_t<I, T...>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to trick compilers about that a parameter pack is used
|
/// Helper to trick compilers about that a parameter pack is used
|
||||||
template <typename... T> void unused(T&&... args) {
|
template <typename... T> constexpr void unused(T&&... args) {
|
||||||
auto use = [](auto&& type) mutable {
|
auto use = [](auto&& type) mutable {
|
||||||
(void)type;
|
(void)type;
|
||||||
return 0;
|
return 0;
|
||||||
@ -225,22 +228,24 @@ struct is_valid_impl<T, Check,
|
|||||||
: std::common_type<std::true_type> {};
|
: std::common_type<std::true_type> {};
|
||||||
|
|
||||||
template <typename Type, typename TrueCallback>
|
template <typename Type, typename TrueCallback>
|
||||||
void static_if_impl(std::true_type, Type&& type, TrueCallback&& trueCallback) {
|
constexpr void static_if_impl(std::true_type, Type&& type,
|
||||||
|
TrueCallback&& trueCallback) {
|
||||||
std::forward<TrueCallback>(trueCallback)(std::forward<Type>(type));
|
std::forward<TrueCallback>(trueCallback)(std::forward<Type>(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type, typename TrueCallback>
|
template <typename Type, typename TrueCallback>
|
||||||
void static_if_impl(std::false_type, Type&& /*type*/,
|
constexpr void static_if_impl(std::false_type, Type&& /*type*/,
|
||||||
TrueCallback&& /*trueCallback*/) {}
|
TrueCallback&& /*trueCallback*/) {}
|
||||||
|
|
||||||
template <typename Type, typename TrueCallback, typename FalseCallback>
|
template <typename Type, typename TrueCallback, typename FalseCallback>
|
||||||
auto static_if_impl(std::true_type, Type&& type, TrueCallback&& trueCallback,
|
constexpr auto static_if_impl(std::true_type, Type&& type,
|
||||||
|
TrueCallback&& trueCallback,
|
||||||
FalseCallback&& /*falseCallback*/) {
|
FalseCallback&& /*falseCallback*/) {
|
||||||
return std::forward<TrueCallback>(trueCallback)(std::forward<Type>(type));
|
return std::forward<TrueCallback>(trueCallback)(std::forward<Type>(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type, typename TrueCallback, typename FalseCallback>
|
template <typename Type, typename TrueCallback, typename FalseCallback>
|
||||||
auto static_if_impl(std::false_type, Type&& type,
|
constexpr auto static_if_impl(std::false_type, Type&& type,
|
||||||
TrueCallback&& /*trueCallback*/,
|
TrueCallback&& /*trueCallback*/,
|
||||||
FalseCallback&& falseCallback) {
|
FalseCallback&& falseCallback) {
|
||||||
return std::forward<FalseCallback>(falseCallback)(std::forward<Type>(type));
|
return std::forward<FalseCallback>(falseCallback)(std::forward<Type>(type));
|
||||||
@ -248,40 +253,44 @@ auto static_if_impl(std::false_type, Type&& type,
|
|||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
|
|
||||||
/// Returns the pack size of the given type
|
/// Returns the pack size of the given type
|
||||||
template <typename... Args> auto pack_size_of(identity<std::tuple<Args...>>) {
|
template <typename... Args>
|
||||||
|
constexpr auto pack_size_of(identity<std::tuple<Args...>>) noexcept {
|
||||||
return size_of_t<Args...>{};
|
return size_of_t<Args...>{};
|
||||||
}
|
}
|
||||||
/// Returns the pack size of the given type
|
/// Returns the pack size of the given type
|
||||||
template <typename First, typename Second>
|
template <typename First, typename Second>
|
||||||
auto pack_size_of(identity<std::pair<First, Second>>) {
|
constexpr auto pack_size_of(identity<std::pair<First, Second>>) noexcept {
|
||||||
return size_of_t<First, Second>{};
|
return size_of_t<First, Second>{};
|
||||||
}
|
}
|
||||||
/// Returns the pack size of the given type
|
/// Returns the pack size of the given type
|
||||||
template <typename... Args> auto pack_size_of(identity<Args...>) {
|
template <typename... Args>
|
||||||
|
constexpr auto pack_size_of(identity<Args...>) noexcept {
|
||||||
return size_of_t<Args...>{};
|
return size_of_t<Args...>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an index sequence of the given type
|
/// Returns an index sequence of the given type
|
||||||
template <typename T> auto sequenceOf(T&& sequenceable) {
|
template <typename T> constexpr auto sequenceOf(T&& /*sequenceable*/) noexcept {
|
||||||
auto size = pack_size_of(std::forward<T>(sequenceable));
|
return std::make_index_sequence<decltype(
|
||||||
(void)size;
|
pack_size_of(std::declval<T>()))::value>();
|
||||||
return std::make_index_sequence<decltype(size)::value>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a check which returns a true type if the current value
|
/// Returns a check which returns a true type if the current value
|
||||||
/// is below the
|
/// is below the
|
||||||
template <std::size_t End> auto isLessThen(size_constant<End> end) {
|
template <std::size_t End>
|
||||||
|
constexpr auto isLessThen(size_constant<End> end) noexcept {
|
||||||
return [=](auto current) { return end > current; };
|
return [=](auto current) { return end > current; };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile-time check for validating a certain expression
|
/// Compile-time check for validating a certain expression
|
||||||
template <typename T, typename Check>
|
template <typename T, typename Check>
|
||||||
auto is_valid(T&& /*type*/, Check&& /*check*/) {
|
constexpr auto is_valid(T&& /*type*/, Check&& /*check*/) noexcept {
|
||||||
return typename detail::is_valid_impl<T, Check>::type{};
|
return typename detail::is_valid_impl<T, Check>::type{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a static functional validator object.
|
/// Creates a static functional validator object.
|
||||||
template <typename Check> auto validatorOf(Check&& check) {
|
template <typename Check>
|
||||||
|
constexpr auto validatorOf(Check&& check) noexcept(
|
||||||
|
std::is_nothrow_move_constructible<std::decay_t<Check>>::value) {
|
||||||
return [check = std::forward<Check>(check)](auto&& matchable) {
|
return [check = std::forward<Check>(check)](auto&& matchable) {
|
||||||
return is_valid(std::forward<decltype(matchable)>(matchable), check);
|
return is_valid(std::forward<decltype(matchable)>(matchable), check);
|
||||||
};
|
};
|
||||||
@ -289,7 +298,8 @@ template <typename Check> auto validatorOf(Check&& check) {
|
|||||||
|
|
||||||
/// Invokes the callback only if the given type matches the check
|
/// Invokes the callback only if the given type matches the check
|
||||||
template <typename Type, typename Check, typename TrueCallback>
|
template <typename Type, typename Check, typename TrueCallback>
|
||||||
void static_if(Type&& type, Check&& check, TrueCallback&& trueCallback) {
|
constexpr void static_if(Type&& type, Check&& check,
|
||||||
|
TrueCallback&& trueCallback) {
|
||||||
detail::static_if_impl(std::forward<Check>(check)(type),
|
detail::static_if_impl(std::forward<Check>(check)(type),
|
||||||
std::forward<Type>(type),
|
std::forward<Type>(type),
|
||||||
std::forward<TrueCallback>(trueCallback));
|
std::forward<TrueCallback>(trueCallback));
|
||||||
@ -298,7 +308,8 @@ void static_if(Type&& type, Check&& check, TrueCallback&& trueCallback) {
|
|||||||
/// Invokes the callback only if the given type matches the check
|
/// Invokes the callback only if the given type matches the check
|
||||||
template <typename Type, typename Check, typename TrueCallback,
|
template <typename Type, typename Check, typename TrueCallback,
|
||||||
typename FalseCallback>
|
typename FalseCallback>
|
||||||
auto static_if(Type&& type, Check&& check, TrueCallback&& trueCallback,
|
constexpr auto static_if(Type&& type, Check&& check,
|
||||||
|
TrueCallback&& trueCallback,
|
||||||
FalseCallback&& falseCallback) {
|
FalseCallback&& falseCallback) {
|
||||||
return detail::static_if_impl(std::forward<Check>(check)(type),
|
return detail::static_if_impl(std::forward<Check>(check)(type),
|
||||||
std::forward<Type>(type),
|
std::forward<Type>(type),
|
||||||
@ -309,7 +320,8 @@ auto static_if(Type&& type, Check&& check, TrueCallback&& trueCallback,
|
|||||||
/// A compile-time while loop, which loops as long the value matches
|
/// A compile-time while loop, which loops as long the value matches
|
||||||
/// the predicate. The handler shall return the next value.
|
/// the predicate. The handler shall return the next value.
|
||||||
template <typename Value, typename Predicate, typename Handler>
|
template <typename Value, typename Predicate, typename Handler>
|
||||||
auto static_while(Value&& value, Predicate&& predicate, Handler&& handler) {
|
constexpr auto static_while(Value&& value, Predicate&& predicate,
|
||||||
|
Handler&& handler) {
|
||||||
return static_if(std::forward<Value>(value), predicate,
|
return static_if(std::forward<Value>(value), predicate,
|
||||||
[&](auto&& result) mutable {
|
[&](auto&& result) mutable {
|
||||||
return static_while(
|
return static_while(
|
||||||
@ -323,7 +335,7 @@ auto static_while(Value&& value, Predicate&& predicate, Handler&& handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a validator which checks whether the given sequenceable is empty
|
/// Returns a validator which checks whether the given sequenceable is empty
|
||||||
inline auto is_empty() {
|
inline auto is_empty() noexcept {
|
||||||
return [](auto const& checkable) {
|
return [](auto const& checkable) {
|
||||||
return pack_size_of(checkable) == size_constant_of<0>();
|
return pack_size_of(checkable) == size_constant_of<0>();
|
||||||
};
|
};
|
||||||
@ -331,13 +343,13 @@ inline auto is_empty() {
|
|||||||
|
|
||||||
/// Calls the given unpacker with the content of the given sequence
|
/// Calls the given unpacker with the content of the given sequence
|
||||||
template <typename U, std::size_t... I>
|
template <typename U, std::size_t... I>
|
||||||
auto unpack(std::integer_sequence<std::size_t, I...>, U&& unpacker) {
|
constexpr auto unpack(std::integer_sequence<std::size_t, I...>, U&& unpacker) {
|
||||||
return std::forward<U>(unpacker)(size_constant_of<I>()...);
|
return std::forward<U>(unpacker)(size_constant_of<I>()...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls the given unpacker with the content of the given sequenceable
|
/// Calls the given unpacker with the content of the given sequenceable
|
||||||
template <typename F, typename U, std::size_t... I>
|
template <typename F, typename U, std::size_t... I>
|
||||||
auto unpack(F&& firstSequenceable, U&& unpacker,
|
constexpr auto unpack(F&& firstSequenceable, U&& unpacker,
|
||||||
std::integer_sequence<std::size_t, I...>) {
|
std::integer_sequence<std::size_t, I...>) {
|
||||||
using std::get;
|
using std::get;
|
||||||
(void)firstSequenceable;
|
(void)firstSequenceable;
|
||||||
@ -347,8 +359,8 @@ auto unpack(F&& firstSequenceable, U&& unpacker,
|
|||||||
/// Calls the given unpacker with the content of the given sequenceable
|
/// Calls the given unpacker with the content of the given sequenceable
|
||||||
template <typename F, typename S, typename U, std::size_t... IF,
|
template <typename F, typename S, typename U, std::size_t... IF,
|
||||||
std::size_t... IS>
|
std::size_t... IS>
|
||||||
auto unpack(F&& firstSequenceable, S&& secondSequenceable, U&& unpacker,
|
constexpr auto unpack(F&& firstSequenceable, S&& secondSequenceable,
|
||||||
std::integer_sequence<std::size_t, IF...>,
|
U&& unpacker, std::integer_sequence<std::size_t, IF...>,
|
||||||
std::integer_sequence<std::size_t, IS...>) {
|
std::integer_sequence<std::size_t, IS...>) {
|
||||||
using std::get;
|
using std::get;
|
||||||
(void)firstSequenceable;
|
(void)firstSequenceable;
|
||||||
@ -365,7 +377,8 @@ auto unpack(F&& firstSequenceable, U&& unpacker) {
|
|||||||
}
|
}
|
||||||
/// Calls the given unpacker with the content of the given sequenceables
|
/// Calls the given unpacker with the content of the given sequenceables
|
||||||
template <typename F, typename S, typename U>
|
template <typename F, typename S, typename U>
|
||||||
auto unpack(F&& firstSequenceable, S&& secondSequenceable, U&& unpacker) {
|
constexpr auto unpack(F&& firstSequenceable, S&& secondSequenceable,
|
||||||
|
U&& unpacker) {
|
||||||
return unpack(std::forward<F>(firstSequenceable),
|
return unpack(std::forward<F>(firstSequenceable),
|
||||||
std::forward<S>(secondSequenceable), std::forward<U>(unpacker),
|
std::forward<S>(secondSequenceable), std::forward<U>(unpacker),
|
||||||
sequenceOf(identity_of(firstSequenceable)),
|
sequenceOf(identity_of(firstSequenceable)),
|
||||||
@ -374,7 +387,8 @@ auto unpack(F&& firstSequenceable, S&& secondSequenceable, U&& unpacker) {
|
|||||||
|
|
||||||
/// Applies the handler function to each element contained in the sequenceable
|
/// Applies the handler function to each element contained in the sequenceable
|
||||||
template <typename Sequenceable, typename Handler>
|
template <typename Sequenceable, typename Handler>
|
||||||
void static_for_each_in(Sequenceable&& sequenceable, Handler&& handler) {
|
constexpr void static_for_each_in(Sequenceable&& sequenceable,
|
||||||
|
Handler&& handler) {
|
||||||
unpack(
|
unpack(
|
||||||
std::forward<Sequenceable>(sequenceable), [&](auto&&... entries) mutable {
|
std::forward<Sequenceable>(sequenceable), [&](auto&&... entries) mutable {
|
||||||
auto consume = [&](auto&& entry) mutable {
|
auto consume = [&](auto&& entry) mutable {
|
||||||
@ -390,7 +404,7 @@ void static_for_each_in(Sequenceable&& sequenceable, Handler&& handler) {
|
|||||||
|
|
||||||
/// Adds the given type at the back of the left sequenceable
|
/// Adds the given type at the back of the left sequenceable
|
||||||
template <typename Left, typename Element>
|
template <typename Left, typename Element>
|
||||||
auto push(Left&& left, Element&& element) {
|
constexpr auto push(Left&& left, Element&& element) {
|
||||||
return unpack(std::forward<Left>(left), [&](auto&&... leftArgs) {
|
return unpack(std::forward<Left>(left), [&](auto&&... leftArgs) {
|
||||||
return std::make_tuple(std::forward<decltype(leftArgs)>(leftArgs)...,
|
return std::make_tuple(std::forward<decltype(leftArgs)>(leftArgs)...,
|
||||||
std::forward<Element>(element));
|
std::forward<Element>(element));
|
||||||
@ -399,44 +413,45 @@ auto push(Left&& left, Element&& element) {
|
|||||||
|
|
||||||
/// Adds the element to the back of the identity
|
/// Adds the element to the back of the identity
|
||||||
template <typename... Args, typename Element>
|
template <typename... Args, typename Element>
|
||||||
auto push(identity<Args...>, identity<Element>) {
|
constexpr auto push(identity<Args...>, identity<Element>) noexcept {
|
||||||
return identity<Args..., Element>{};
|
return identity<Args..., Element>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the first element from the identity
|
/// Removes the first element from the identity
|
||||||
template <typename First, typename... Rest>
|
template <typename First, typename... Rest>
|
||||||
auto pop_first(identity<First, Rest...>) {
|
constexpr auto pop_first(identity<First, Rest...>) noexcept {
|
||||||
return identity<Rest...>{};
|
return identity<Rest...>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the merged sequence
|
/// Returns the merged sequence
|
||||||
template <typename Left> auto merge(Left&& left) {
|
template <typename Left> constexpr auto merge(Left&& left) {
|
||||||
return std::forward<Left>(left);
|
return std::forward<Left>(left);
|
||||||
}
|
}
|
||||||
/// Merges the left sequenceable with the right ones
|
/// Merges the left sequenceable with the right ones
|
||||||
template <typename Left, typename Right, typename... Rest>
|
template <typename Left, typename Right, typename... Rest>
|
||||||
auto merge(Left&& left, Right&& right, Rest&&... rest) {
|
constexpr auto merge(Left&& left, Right&& right, Rest&&... rest) {
|
||||||
// Merge the left with the right sequenceable
|
// Merge the left with the right sequenceable and
|
||||||
auto merged =
|
// merge the result with the rest.
|
||||||
unpack(std::forward<Left>(left), std::forward<Right>(right),
|
return merge(unpack(std::forward<Left>(left), std::forward<Right>(right),
|
||||||
[&](auto&&... args) {
|
[&](auto&&... args) {
|
||||||
// Maybe use: template <template<typename...> class T,
|
// Maybe use: template <template<typename...> class T,
|
||||||
// typename... Args>
|
// typename... Args>
|
||||||
return std::make_tuple(std::forward<decltype(args)>(args)...);
|
return std::make_tuple(
|
||||||
});
|
std::forward<decltype(args)>(args)...);
|
||||||
// And merge it with the rest
|
}),
|
||||||
return merge(std::move(merged), std::forward<Rest>(rest)...);
|
std::forward<Rest>(rest)...);
|
||||||
}
|
}
|
||||||
/// Merges the left identity with the right ones
|
/// Merges the left identity with the right ones
|
||||||
template <typename... LeftArgs, typename... RightArgs, typename... Rest>
|
template <typename... LeftArgs, typename... RightArgs, typename... Rest>
|
||||||
auto merge(identity<LeftArgs...> /*left*/, identity<RightArgs...> /*right*/,
|
constexpr auto merge(identity<LeftArgs...> /*left*/,
|
||||||
Rest&&... rest) {
|
identity<RightArgs...> /*right*/, Rest&&... rest) {
|
||||||
return merge(identity<LeftArgs..., RightArgs...>{},
|
return merge(identity<LeftArgs..., RightArgs...>{},
|
||||||
std::forward<Rest>(rest)...);
|
std::forward<Rest>(rest)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Combines the given arguments with the given folding function
|
/// Combines the given arguments with the given folding function
|
||||||
template <typename F, typename First> auto fold(F&& /*folder*/, First&& first) {
|
template <typename F, typename First>
|
||||||
|
constexpr auto fold(F&& /*folder*/, First&& first) {
|
||||||
return std::forward<First>(first);
|
return std::forward<First>(first);
|
||||||
}
|
}
|
||||||
/// Combines the given arguments with the given folding function
|
/// Combines the given arguments with the given folding function
|
||||||
@ -448,21 +463,21 @@ auto fold(F&& folder, First&& first, Second&& second, Rest&&... rest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a folding function using operator `&&`.
|
/// Returns a folding function using operator `&&`.
|
||||||
inline auto and_folding() {
|
inline auto and_folding() noexcept {
|
||||||
return [](auto&& left, auto&& right) {
|
return [](auto&& left, auto&& right) {
|
||||||
return std::forward<decltype(left)>(left) &&
|
return std::forward<decltype(left)>(left) &&
|
||||||
std::forward<decltype(right)>(right);
|
std::forward<decltype(right)>(right);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/// Returns a folding function using operator `||`.
|
/// Returns a folding function using operator `||`.
|
||||||
inline auto or_folding() {
|
inline auto or_folding() noexcept {
|
||||||
return [](auto&& left, auto&& right) {
|
return [](auto&& left, auto&& right) {
|
||||||
return std::forward<decltype(left)>(left) ||
|
return std::forward<decltype(left)>(left) ||
|
||||||
std::forward<decltype(right)>(right);
|
std::forward<decltype(right)>(right);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/// Returns a folding function using operator `>>`.
|
/// Returns a folding function using operator `>>`.
|
||||||
inline auto seq_folding() {
|
inline auto seq_folding() noexcept {
|
||||||
return [](auto&& left, auto&& right) {
|
return [](auto&& left, auto&& right) {
|
||||||
return std::forward<decltype(left)>(left) >>
|
return std::forward<decltype(left)>(left) >>
|
||||||
std::forward<decltype(right)>(right);
|
std::forward<decltype(right)>(right);
|
||||||
@ -583,18 +598,18 @@ auto partial_invoke(T&& callable, Args&&... args) {
|
|||||||
|
|
||||||
// Class for making child classes non copyable
|
// Class for making child classes non copyable
|
||||||
struct non_copyable {
|
struct non_copyable {
|
||||||
non_copyable() = default;
|
constexpr non_copyable() = default;
|
||||||
non_copyable(non_copyable const&) = delete;
|
non_copyable(non_copyable const&) = delete;
|
||||||
non_copyable(non_copyable&&) = default;
|
constexpr non_copyable(non_copyable&&) = default;
|
||||||
non_copyable& operator=(non_copyable const&) = delete;
|
non_copyable& operator=(non_copyable const&) = delete;
|
||||||
non_copyable& operator=(non_copyable&&) = default;
|
non_copyable& operator=(non_copyable&&) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Class for making child classes non copyable and movable
|
// Class for making child classes non copyable and movable
|
||||||
struct non_movable {
|
struct non_movable {
|
||||||
non_movable() = default;
|
constexpr non_movable() = default;
|
||||||
non_movable(non_movable const&) = delete;
|
non_movable(non_movable const&) = delete;
|
||||||
non_movable(non_movable&&) = delete;
|
constexpr non_movable(non_movable&&) = delete;
|
||||||
non_movable& operator=(non_movable const&) = delete;
|
non_movable& operator=(non_movable const&) = delete;
|
||||||
non_movable& operator=(non_movable&&) = delete;
|
non_movable& operator=(non_movable&&) = delete;
|
||||||
};
|
};
|
||||||
@ -604,9 +619,9 @@ struct non_movable {
|
|||||||
/// is moved to another instance.
|
/// is moved to another instance.
|
||||||
class ownership {
|
class ownership {
|
||||||
public:
|
public:
|
||||||
ownership() = default;
|
constexpr ownership() = default;
|
||||||
explicit ownership(bool isOwning_) : is_owning(isOwning_) {}
|
constexpr explicit ownership(bool isOwning_) : is_owning(isOwning_) {}
|
||||||
ownership(ownership const&) = default;
|
constexpr ownership(ownership const&) = default;
|
||||||
ownership(ownership&& right) noexcept
|
ownership(ownership&& right) noexcept
|
||||||
: is_owning(std::exchange(right.is_owning, false)){};
|
: is_owning(std::exchange(right.is_owning, false)){};
|
||||||
ownership& operator=(ownership const&) = default;
|
ownership& operator=(ownership const&) = default;
|
||||||
@ -619,7 +634,7 @@ public:
|
|||||||
return ownership(has_ownership() && right.has_ownership());
|
return ownership(has_ownership() && right.has_ownership());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_ownership() const noexcept { return is_owning; }
|
constexpr bool has_ownership() const noexcept { return is_owning; }
|
||||||
void invalidate() noexcept { is_owning = false; }
|
void invalidate() noexcept { is_owning = false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -654,15 +669,15 @@ struct this_thread_executor_tag {};
|
|||||||
/// -> void
|
/// -> void
|
||||||
namespace base {
|
namespace base {
|
||||||
/// Returns the signature hint of the given continuable
|
/// Returns the signature hint of the given continuable
|
||||||
template <typename T> auto hint_of(util::identity<T>) {
|
template <typename T> constexpr auto hint_of(util::identity<T>) {
|
||||||
static_assert(util::fail<T>::value,
|
static_assert(util::fail<T>::value,
|
||||||
"Expected a continuation with an existing signature hint!");
|
"Expected a continuation with an existing signature hint!");
|
||||||
return util::identity_of<void>();
|
return util::identity_of<void>();
|
||||||
}
|
}
|
||||||
/// Returns the signature hint of the given continuable
|
/// Returns the signature hint of the given continuable
|
||||||
template <typename Data, typename... Args>
|
template <typename Data, typename... Args>
|
||||||
auto hint_of(
|
constexpr auto
|
||||||
util::identity<continuable_base<Data, signature_hint_tag<Args...>>>) {
|
hint_of(util::identity<continuable_base<Data, signature_hint_tag<Args...>>>) {
|
||||||
return signature_hint_tag<Args...>{};
|
return signature_hint_tag<Args...>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,18 +741,18 @@ public:
|
|||||||
using T::operator();
|
using T::operator();
|
||||||
|
|
||||||
/// Returns the underlaying signature hint
|
/// Returns the underlaying signature hint
|
||||||
Hint hint() const noexcept { return {}; }
|
constexpr Hint hint() const noexcept { return {}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
auto make_invoker(T&& invoke, signature_hint_tag<Args...>) {
|
constexpr auto make_invoker(T&& invoke, signature_hint_tag<Args...>) {
|
||||||
return invoker<std::decay_t<T>, signature_hint_tag<Args...>>(
|
return invoker<std::decay_t<T>, signature_hint_tag<Args...>>(
|
||||||
std::forward<T>(invoke));
|
std::forward<T>(invoke));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// - continuable<?...> -> result(nextCallback);
|
/// - continuable<?...> -> result(nextCallback);
|
||||||
template <typename Data, typename Annotation>
|
template <typename Data, typename Annotation>
|
||||||
auto invokerOf(util::identity<continuable_base<Data, Annotation>>) {
|
constexpr auto invokerOf(util::identity<continuable_base<Data, Annotation>>) {
|
||||||
/// Get the hint of the unwrapped returned continuable
|
/// Get the hint of the unwrapped returned continuable
|
||||||
using Type = decltype(attorney::materialize(
|
using Type = decltype(attorney::materialize(
|
||||||
std::declval<continuable_base<Data, Annotation>>()));
|
std::declval<continuable_base<Data, Annotation>>()));
|
||||||
@ -796,14 +811,14 @@ inline auto sequencedUnpackInvoker() {
|
|||||||
|
|
||||||
// - std::pair<?, ?> -> nextCallback(?, ?)
|
// - std::pair<?, ?> -> nextCallback(?, ?)
|
||||||
template <typename First, typename Second>
|
template <typename First, typename Second>
|
||||||
auto invokerOf(util::identity<std::pair<First, Second>>) {
|
constexpr auto invokerOf(util::identity<std::pair<First, Second>>) {
|
||||||
return make_invoker(sequencedUnpackInvoker(),
|
return make_invoker(sequencedUnpackInvoker(),
|
||||||
util::identity<First, Second>{});
|
util::identity<First, Second>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
// - std::tuple<?...> -> nextCallback(?...)
|
// - std::tuple<?...> -> nextCallback(?...)
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
auto invokerOf(util::identity<std::tuple<Args...>>) {
|
constexpr auto invokerOf(util::identity<std::tuple<Args...>>) {
|
||||||
return make_invoker(sequencedUnpackInvoker(), util::identity<Args...>{});
|
return make_invoker(sequencedUnpackInvoker(), util::identity<Args...>{});
|
||||||
}
|
}
|
||||||
} // end namespace decoration
|
} // end namespace decoration
|
||||||
@ -890,7 +905,7 @@ void invoke_proxy(signature_hint_tag<Args...>, Continuation&& continuation,
|
|||||||
|
|
||||||
/// Returns the next hint when the callback is invoked with the given hint
|
/// Returns the next hint when the callback is invoked with the given hint
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
auto next_hint_of(util::identity<T> /*callback*/,
|
constexpr auto next_hint_of(util::identity<T> /*callback*/,
|
||||||
signature_hint_tag<Args...> /*current*/) {
|
signature_hint_tag<Args...> /*current*/) {
|
||||||
auto result =
|
auto result =
|
||||||
util::identity_of<decltype(std::declval<T>()(std::declval<Args>()...))>();
|
util::identity_of<decltype(std::declval<T>()(std::declval<Args>()...))>();
|
||||||
@ -989,12 +1004,12 @@ template <> struct is_strategy<strategy_any_tag> : std::true_type {};
|
|||||||
namespace annotating {
|
namespace annotating {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
/// Void hints are equal to an empty signature
|
/// Void hints are equal to an empty signature
|
||||||
inline auto make_hint_of(util::identity<void>) {
|
constexpr auto make_hint_of(util::identity<void>) noexcept {
|
||||||
return signature_hint_tag<>{};
|
return signature_hint_tag<>{};
|
||||||
}
|
}
|
||||||
/// All other hints are the obvious hints...
|
/// All other hints are the obvious hints...
|
||||||
template <typename... HintArgs>
|
template <typename... HintArgs>
|
||||||
auto make_hint_of(util::identity<HintArgs...> args) {
|
constexpr auto make_hint_of(util::identity<HintArgs...> args) noexcept {
|
||||||
return args; // Identity is equal to signature_hint_tag
|
return args; // Identity is equal to signature_hint_tag
|
||||||
}
|
}
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
@ -1015,7 +1030,8 @@ auto make_hint_of(util::identity<HintArgs...> args) {
|
|||||||
/// - absent_signature_hint_tag
|
/// - absent_signature_hint_tag
|
||||||
///
|
///
|
||||||
template <typename T, typename... HintArgs>
|
template <typename T, typename... HintArgs>
|
||||||
auto extract(util::identity<T> /*type*/, util::identity<HintArgs...> hint) {
|
constexpr auto extract(util::identity<T> /*type*/,
|
||||||
|
util::identity<HintArgs...> hint) {
|
||||||
return util::static_if(hint, util::is_empty(),
|
return util::static_if(hint, util::is_empty(),
|
||||||
[=](auto /*hint*/) {
|
[=](auto /*hint*/) {
|
||||||
/// When the arguments are the hint is absent
|
/// When the arguments are the hint is absent
|
||||||
@ -1030,7 +1046,7 @@ auto extract(util::identity<T> /*type*/, util::identity<HintArgs...> hint) {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <std::size_t Pos, typename T>
|
template <std::size_t Pos, typename T>
|
||||||
void assign(util::size_constant<Pos> /*pos*/, T& /*storage*/) {
|
constexpr void assign(util::size_constant<Pos> /*pos*/, T& /*storage*/) {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
template <std::size_t Pos, typename T, typename Current, typename... Args>
|
template <std::size_t Pos, typename T, typename Current, typename... Args>
|
||||||
@ -1251,10 +1267,10 @@ auto make_any_result_submitter(Callback&& callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T first_of(util::identity<T, Args...>) noexcept;
|
constexpr T first_of(util::identity<T, Args...>) noexcept;
|
||||||
|
|
||||||
template <typename Signature, typename... Args>
|
template <typename Signature, typename... Args>
|
||||||
auto common_result_of(Signature signature, signature_hint_tag<>,
|
constexpr auto common_result_of(Signature signature, signature_hint_tag<>,
|
||||||
Args... /*args*/) {
|
Args... /*args*/) {
|
||||||
/// Assert that the other signatures are empty too which means all signatures
|
/// Assert that the other signatures are empty too which means all signatures
|
||||||
/// had the same size.
|
/// had the same size.
|
||||||
@ -1271,7 +1287,8 @@ auto common_result_of(Signature signature, signature_hint_tag<>,
|
|||||||
/// c1 with `void(int)` and c22 with `void(float)`, the common result shared
|
/// c1 with `void(int)` and c22 with `void(float)`, the common result shared
|
||||||
/// between both continuations is `void(int)`.
|
/// between both continuations is `void(int)`.
|
||||||
template <typename Signature, typename First, typename... Args>
|
template <typename Signature, typename First, typename... Args>
|
||||||
auto common_result_of(Signature signature, First first, Args... args) {
|
constexpr auto common_result_of(Signature signature, First first,
|
||||||
|
Args... args) {
|
||||||
auto common =
|
auto common =
|
||||||
util::identity<std::common_type_t<decltype(first_of(first)),
|
util::identity<std::common_type_t<decltype(first_of(first)),
|
||||||
decltype(first_of(args))...>>{};
|
decltype(first_of(args))...>>{};
|
||||||
@ -1366,9 +1383,9 @@ class promise_callback<signature_hint_tag<Args...>>
|
|||||||
typename future_trait<Args...>::promise_t promise_;
|
typename future_trait<Args...>::promise_t promise_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
promise_callback() = default;
|
constexpr promise_callback() = default;
|
||||||
promise_callback(promise_callback const&) = delete;
|
promise_callback(promise_callback const&) = delete;
|
||||||
promise_callback(promise_callback&&) = default;
|
constexpr promise_callback(promise_callback&&) = default;
|
||||||
promise_callback& operator=(promise_callback const&) = delete;
|
promise_callback& operator=(promise_callback const&) = delete;
|
||||||
promise_callback& operator=(promise_callback&&) = delete;
|
promise_callback& operator=(promise_callback&&) = delete;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user