Commit 625adffa authored by Dominik Charousset's avatar Dominik Charousset

Merge pull request #1526

parents 9f86fccd b4053a20
...@@ -261,7 +261,7 @@ public: ...@@ -261,7 +261,7 @@ public:
using mpi = std::set<std::string>; using mpi = std::set<std::string>;
template <class T, template <class T,
class E = typename std::enable_if<!is_typed_actor<T>::value>::type> class E = typename std::enable_if<!is_typed_actor_v<T>>::type>
mpi message_types(detail::type_list<T>) const { mpi message_types(detail::type_list<T>) const {
return mpi{}; return mpi{};
} }
...@@ -274,8 +274,7 @@ public: ...@@ -274,8 +274,7 @@ public:
} }
template <class T, template <class T,
class E class E = typename std::enable_if<!detail::is_type_list_v<T>>::type>
= typename std::enable_if<!detail::is_type_list<T>::value>::type>
mpi message_types(const T&) const { mpi message_types(const T&) const {
detail::type_list<T> token; detail::type_list<T> token;
return message_types(token); return message_types(token);
......
...@@ -14,6 +14,10 @@ namespace caf::mixin { ...@@ -14,6 +14,10 @@ namespace caf::mixin {
template <class T> template <class T>
struct is_blocking_requester : std::false_type {}; struct is_blocking_requester : std::false_type {};
/// Convenience alias for `is_blocking_requester<T>::value`.
template <class T>
inline constexpr bool is_blocking_requester_v = is_blocking_requester<T>::value;
} // namespace caf::mixin } // namespace caf::mixin
namespace caf { namespace caf {
...@@ -68,7 +72,7 @@ struct default_actor_traits<T, true> { ...@@ -68,7 +72,7 @@ struct default_actor_traits<T, true> {
/// Denotes whether `T` is a blocking actor type. /// Denotes whether `T` is a blocking actor type.
static constexpr bool is_blocking = std::is_base_of_v<blocking_actor_base, T> static constexpr bool is_blocking = std::is_base_of_v<blocking_actor_base, T>
|| mixin::is_blocking_requester<T>::value; || mixin::is_blocking_requester_v<T>;
/// Denotes whether `T` is a non-blocking actor type. /// Denotes whether `T` is a non-blocking actor type.
static constexpr bool is_non_blocking static constexpr bool is_non_blocking
......
...@@ -34,9 +34,9 @@ template <class To, class From> ...@@ -34,9 +34,9 @@ template <class To, class From>
auto no_conversion() { auto no_conversion() {
return [](const From&) { return [](const From&) {
std::string msg = "cannot convert "; std::string msg = "cannot convert ";
msg += type_names[detail::tl_index_of<config_value::types, From>::value]; msg += type_names[detail::tl_index_of_v<config_value::types, From>];
msg += " to "; msg += " to ";
msg += type_names[detail::tl_index_of<config_value::types, To>::value]; msg += type_names[detail::tl_index_of_v<config_value::types, To>];
auto err = make_error(sec::conversion_failed, std::move(msg)); auto err = make_error(sec::conversion_failed, std::move(msg));
return expected<To>{std::move(err)}; return expected<To>{std::move(err)};
}; };
......
...@@ -59,7 +59,7 @@ CAF_ADD_CONFIG_VALUE_TYPE(dictionary<config_value>); ...@@ -59,7 +59,7 @@ CAF_ADD_CONFIG_VALUE_TYPE(dictionary<config_value>);
#undef CAF_ADD_CONFIG_VALUE_TYPE #undef CAF_ADD_CONFIG_VALUE_TYPE
template <class T> template <class T>
constexpr bool is_config_value_type_v = is_config_value_type<T>::value; inline constexpr bool is_config_value_type_v = is_config_value_type<T>::value;
} // namespace caf::detail } // namespace caf::detail
...@@ -252,7 +252,7 @@ public: ...@@ -252,7 +252,7 @@ public:
template <class T> template <class T>
static constexpr std::string_view mapped_type_name() { static constexpr std::string_view mapped_type_name() {
if constexpr (detail::is_complete<caf::type_name<T>>) { if constexpr (detail::is_complete<caf::type_name<T>>) {
return caf::type_name<T>::value; return caf::type_name_v<T>;
} else if constexpr (detail::is_list_like_v<T>) { } else if constexpr (detail::is_list_like_v<T>) {
return "list"; return "list";
} else { } else {
......
...@@ -31,7 +31,7 @@ PRETTY_NAME(caf::config_value_reader::sequence, "sequence"); ...@@ -31,7 +31,7 @@ PRETTY_NAME(caf::config_value_reader::sequence, "sequence");
PRETTY_NAME(caf::config_value_reader::associative_array, "associative array"); PRETTY_NAME(caf::config_value_reader::associative_array, "associative array");
template <class T> template <class T>
constexpr auto pretty_name_v = pretty_name<T>::value; inline constexpr auto pretty_name_v = pretty_name<T>::value;
auto get_pretty_name(const caf::config_value_reader::value_type& x) { auto get_pretty_name(const caf::config_value_reader::value_type& x) {
const char* pretty_names[] = { const char* pretty_names[] = {
......
...@@ -356,9 +356,9 @@ struct tl_exists<empty_type_list, Pred> { ...@@ -356,9 +356,9 @@ struct tl_exists<empty_type_list, Pred> {
static constexpr bool value = false; static constexpr bool value = false;
}; };
// Uncomment after having switched to C++14 /// Convenience alias for `tl_exists<List, Pred>::value`.
// template <class List, template <class> class Pred> template <class List, template <class> class Pred>
// inline constexpr bool tl_exists_v = tl_exists<List, Pred>::value; inline constexpr bool tl_exists_v = tl_exists<List, Pred>::value;
// size_t count(predicate) // size_t count(predicate)
...@@ -925,9 +925,9 @@ template <class T, class... Ts, class X> ...@@ -925,9 +925,9 @@ template <class T, class... Ts, class X>
struct tl_contains<type_list<T, Ts...>, X> : tl_contains<type_list<Ts...>, X> { struct tl_contains<type_list<T, Ts...>, X> : tl_contains<type_list<Ts...>, X> {
}; };
// Uncomment after having switched to C++14 /// Convenience alias for `tl_contains<List, X>::value`.
// template <class List, class X> template <class List, class X>
// inline constexpr bool tl_contains_v = tl_contains<List, X>::value; inline constexpr bool tl_contains_v = tl_contains<List, X>::value;
// subset_of(list, list) // subset_of(list, list)
...@@ -944,17 +944,16 @@ template <class T, class... Ts, class List> ...@@ -944,17 +944,16 @@ template <class T, class... Ts, class List>
struct tl_subset_of<type_list<T, Ts...>, List> struct tl_subset_of<type_list<T, Ts...>, List>
: tl_subset_of<type_list<Ts...>, List, tl_contains<List, T>::value> {}; : tl_subset_of<type_list<Ts...>, List, tl_contains<List, T>::value> {};
// Uncomment after having switched to C++14 /// Convenience alias for `tl_contains<List, X>::value`.
// template <class ListA, class ListB, bool Fwd = true> template <class ListA, class ListB, bool Fwd = true>
// inline constexpr bool tl_subset_of_v = tl_subset_of<ListA, ListB, inline constexpr bool tl_subset_of_v = tl_subset_of<ListA, ListB, Fwd>::value;
// Fwd>::value;
/// Tests whether ListA contains the same elements as ListB /// Tests whether ListA contains the same elements as ListB
/// and vice versa. This comparison ignores element positions. /// and vice versa. This comparison ignores element positions.
template <class ListA, class ListB> template <class ListA, class ListB>
struct tl_equal { struct tl_equal {
static constexpr bool value = tl_subset_of<ListA, ListB>::value static constexpr bool value = tl_subset_of_v<ListA, ListB>
&& tl_subset_of<ListB, ListA>::value; && tl_subset_of_v<ListB, ListA>;
}; };
// Uncomment after having switched to C++14 // Uncomment after having switched to C++14
......
...@@ -841,6 +841,11 @@ public: ...@@ -841,6 +841,11 @@ public:
static constexpr bool value = sfinae_type::value; static constexpr bool value = sfinae_type::value;
}; };
/// Convenience alias for `has_convertible_data_member<T, To>::value`.
template <class T, class To>
inline constexpr bool has_convertible_data_member_v
= has_convertible_data_member<T, To>::value;
/// Evaluates to `true` for all types that specialize `std::tuple_size`, i.e., /// Evaluates to `true` for all types that specialize `std::tuple_size`, i.e.,
/// `std::tuple`, `std::pair`, and `std::array`. /// `std::tuple`, `std::pair`, and `std::array`.
template <class T> template <class T>
...@@ -891,6 +896,11 @@ public: ...@@ -891,6 +896,11 @@ public:
static constexpr bool value = result_type::value; static constexpr bool value = result_type::value;
}; };
/// Convenience alias for `has_inspect_overload<Inspector, T>::value`.
template <class Inspector, class T>
inline constexpr bool has_inspect_overload_v
= has_inspect_overload<Inspector, T>::value;
/// Checks whether the inspector has a `builtin_inspect` overload for `T`. /// Checks whether the inspector has a `builtin_inspect` overload for `T`.
template <class Inspector, class T> template <class Inspector, class T>
class has_builtin_inspect { class has_builtin_inspect {
...@@ -909,6 +919,11 @@ public: ...@@ -909,6 +919,11 @@ public:
static constexpr bool value = sfinae_result::value; static constexpr bool value = sfinae_result::value;
}; };
/// Convenience alias for `has_builtin_inspect<Inspector, T>::value`.
template <class Inspector, class T>
inline constexpr bool has_builtin_inspect_v
= has_builtin_inspect<Inspector, T>::value;
/// Checks whether inspectors are required to provide a `value` overload for T. /// Checks whether inspectors are required to provide a `value` overload for T.
template <bool IsLoading, class T> template <bool IsLoading, class T>
struct is_trivial_inspector_value; struct is_trivial_inspector_value;
......
...@@ -61,11 +61,11 @@ constexpr auto inspect_access_type() { ...@@ -61,11 +61,11 @@ constexpr auto inspect_access_type() {
else if constexpr (detail::is_builtin_inspector_type< else if constexpr (detail::is_builtin_inspector_type<
T, Inspector::is_loading>::value) T, Inspector::is_loading>::value)
return inspector_access_type::builtin{}; return inspector_access_type::builtin{};
else if constexpr (has_builtin_inspect<Inspector, T>::value) else if constexpr (has_builtin_inspect_v<Inspector, T>)
return inspector_access_type::builtin_inspect{}; return inspector_access_type::builtin_inspect{};
else if constexpr (detail::is_complete<inspector_access<T>>) else if constexpr (detail::is_complete<inspector_access<T>>)
return inspector_access_type::specialization{}; return inspector_access_type::specialization{};
else if constexpr (has_inspect_overload<Inspector, T>::value) else if constexpr (has_inspect_overload_v<Inspector, T>)
return inspector_access_type::inspect{}; return inspector_access_type::inspect{};
else if constexpr (std::is_empty<T>::value) else if constexpr (std::is_empty<T>::value)
return inspector_access_type::empty{}; return inspector_access_type::empty{};
......
...@@ -17,4 +17,8 @@ struct is_typed_actor : std::false_type {}; ...@@ -17,4 +17,8 @@ struct is_typed_actor : std::false_type {};
template <class... Ts> template <class... Ts>
struct is_typed_actor<typed_actor<Ts...>> : std::true_type {}; struct is_typed_actor<typed_actor<Ts...>> : std::true_type {};
/// Convenience alias for `is_typed_actor<T>::value`.
template <class T>
inline constexpr bool is_typed_actor_v = is_typed_actor<T>::value;
} // namespace caf } // namespace caf
...@@ -100,9 +100,9 @@ public: ...@@ -100,9 +100,9 @@ public:
template <class... Ts> template <class... Ts>
void deliver(Ts... xs) { void deliver(Ts... xs) {
using arg_types = detail::type_list<Ts...>; using arg_types = detail::type_list<Ts...>;
static_assert(!detail::tl_exists<arg_types, detail::is_result>::value, static_assert(!detail::tl_exists_v<arg_types, detail::is_result>,
"delivering a result<T> is not supported"); "delivering a result<T> is not supported");
static_assert(!detail::tl_exists<arg_types, detail::is_expected>::value, static_assert(!detail::tl_exists_v<arg_types, detail::is_expected>,
"mixing expected<T> with regular values is not supported"); "mixing expected<T> with regular values is not supported");
if (pending()) { if (pending()) {
state_->deliver_impl(make_message(std::move(xs)...)); state_->deliver_impl(make_message(std::move(xs)...));
......
...@@ -64,16 +64,14 @@ public: ...@@ -64,16 +64,14 @@ public:
// nop // nop
} }
template <class C, template <class C, class = std::enable_if_t<
class = std::enable_if_t< detail::has_convertible_data_member_v<C, value_type>>>
detail::has_convertible_data_member<C, value_type>::value>>
span(C& xs) noexcept : begin_(xs.data()), size_(xs.size()) { span(C& xs) noexcept : begin_(xs.data()), size_(xs.size()) {
// nop // nop
} }
template <class C, template <class C, class = std::enable_if_t<
class = std::enable_if_t< detail::has_convertible_data_member_v<C, value_type>>>
detail::has_convertible_data_member<C, value_type>::value>>
span(const C& xs) noexcept : begin_(xs.data()), size_(xs.size()) { span(const C& xs) noexcept : begin_(xs.data()), size_(xs.size()) {
// nop // nop
} }
......
...@@ -103,12 +103,16 @@ struct valid_input { ...@@ -103,12 +103,16 @@ struct valid_input {
adjusted_slist>::template inner>::value; adjusted_slist>::template inner>::value;
}; };
/// Convenience alias for `valid_input<SList, IList>::value`.
template <class SList, class IList>
inline constexpr bool valid_input_v = valid_input<SList, IList>::value;
// this function is called from typed_behavior<...>::set and its whole // this function is called from typed_behavior<...>::set and its whole
// purpose is to give users a nicer error message on a type mismatch // purpose is to give users a nicer error message on a type mismatch
// (this function only has the type information needed to understand the error) // (this function only has the type information needed to understand the error)
template <class SignatureList, class InputList> template <class SignatureList, class InputList>
void static_check_typed_behavior_input() { void static_check_typed_behavior_input() {
constexpr bool is_valid = valid_input<SignatureList, InputList>::value; constexpr bool is_valid = valid_input_v<SignatureList, InputList>;
// note: it might be worth considering to allow a wildcard in the // note: it might be worth considering to allow a wildcard in the
// InputList if its return type is identical to all "missing" // InputList if its return type is identical to all "missing"
// input types ... however, it might lead to unexpected results // input types ... however, it might lead to unexpected results
......
...@@ -54,10 +54,10 @@ CAF_TEST(metaprogramming) { ...@@ -54,10 +54,10 @@ CAF_TEST(metaprogramming) {
/* test tl_subset_of */ { /* test tl_subset_of */ {
using list_a = type_list<int, float, double>; using list_a = type_list<int, float, double>;
using list_b = type_list<float, int, double, std::string>; using list_b = type_list<float, int, double, std::string>;
CHECK((tl_subset_of<list_a, list_b>::value)); CHECK((tl_subset_of_v<list_a, list_b>) );
CHECK(!(tl_subset_of<list_b, list_a>::value)); CHECK(!(tl_subset_of_v<list_b, list_a>) );
CHECK((tl_subset_of<list_a, list_a>::value)); CHECK((tl_subset_of_v<list_a, list_a>) );
CHECK((tl_subset_of<list_b, list_b>::value)); CHECK((tl_subset_of_v<list_b, list_b>) );
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment