Unverified Commit 75dd3dc8 authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #1536

Remove obsolete type traits
parents b3478445 3ace88b4
...@@ -51,13 +51,13 @@ public: ...@@ -51,13 +51,13 @@ public:
actor(const scoped_actor&); actor(const scoped_actor&);
template <class T, template <class T,
class = detail::enable_if_t<actor_traits<T>::is_dynamically_typed>> class = std::enable_if_t<actor_traits<T>::is_dynamically_typed>>
actor(T* ptr) : ptr_(ptr->ctrl()) { actor(T* ptr) : ptr_(ptr->ctrl()) {
CAF_ASSERT(ptr != nullptr); CAF_ASSERT(ptr != nullptr);
} }
template <class T, template <class T,
class = detail::enable_if_t<actor_traits<T>::is_dynamically_typed>> class = std::enable_if_t<actor_traits<T>::is_dynamically_typed>>
actor& operator=(intrusive_ptr<T> ptr) { actor& operator=(intrusive_ptr<T> ptr) {
actor tmp{std::move(ptr)}; actor tmp{std::move(ptr)};
swap(tmp); swap(tmp);
...@@ -65,7 +65,7 @@ public: ...@@ -65,7 +65,7 @@ public:
} }
template <class T, template <class T,
class = detail::enable_if_t<actor_traits<T>::is_dynamically_typed>> class = std::enable_if_t<actor_traits<T>::is_dynamically_typed>>
actor& operator=(T* ptr) { actor& operator=(T* ptr) {
actor tmp{ptr}; actor tmp{ptr};
swap(tmp); swap(tmp);
......
...@@ -142,7 +142,7 @@ actor_factory_result dyn_spawn_class(actor_config& cfg, message& msg) { ...@@ -142,7 +142,7 @@ actor_factory_result dyn_spawn_class(actor_config& cfg, message& msg) {
template <class T, class... Ts> template <class T, class... Ts>
actor_factory make_actor_factory() { actor_factory make_actor_factory() {
static_assert(detail::conjunction_v<std::is_lvalue_reference_v<Ts>...>, static_assert((std::is_lvalue_reference_v<Ts> && ...),
"all Ts must be lvalue references"); "all Ts must be lvalue references");
static_assert(std::is_base_of_v<local_actor, T>, static_assert(std::is_base_of_v<local_actor, T>,
"T is not derived from local_actor"); "T is not derived from local_actor");
......
...@@ -97,8 +97,8 @@ public: ...@@ -97,8 +97,8 @@ public:
config_value(const config_value& other) = default; config_value(const config_value& other) = default;
template <class T, class E = detail::enable_if_t< template <class T, class = std::enable_if_t<
!std::is_same_v<detail::decay_t<T>, config_value>>> !std::is_same_v<std::decay_t<T>, config_value>>>
explicit config_value(T&& x) : data_(lift(std::forward<T>(x))) { explicit config_value(T&& x) : data_(lift(std::forward<T>(x))) {
// nop // nop
} }
...@@ -107,8 +107,8 @@ public: ...@@ -107,8 +107,8 @@ public:
config_value& operator=(const config_value& other) = default; config_value& operator=(const config_value& other) = default;
template <class T, class E = detail::enable_if_t< template <class T, class = std::enable_if_t<
!std::is_same_v<detail::decay_t<T>, config_value>>> !std::is_same_v<std::decay_t<T>, config_value>>>
config_value& operator=(T&& x) { config_value& operator=(T&& x) {
data_ = lift(std::forward<T>(x)); data_ = lift(std::forward<T>(x));
return *this; return *this;
......
...@@ -72,8 +72,7 @@ CAF_CORE_EXPORT void parse(string_parser_state& ps, uint64_t& x); ...@@ -72,8 +72,7 @@ CAF_CORE_EXPORT void parse(string_parser_state& ps, uint64_t& x);
// -- non-fixed size integer types --------------------------------------------- // -- non-fixed size integer types ---------------------------------------------
template <class T> template <class T>
detail::enable_if_t<std::is_integral_v<T>> std::enable_if_t<std::is_integral_v<T>> parse(string_parser_state& ps, T& x) {
parse(string_parser_state& ps, T& x) {
using squashed_type = squashed_int_t<T>; using squashed_type = squashed_int_t<T>;
return parse(ps, reinterpret_cast<squashed_type&>(x)); return parse(ps, reinterpret_cast<squashed_type&>(x));
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "caf/detail/type_traits.hpp" #include "caf/detail/type_traits.hpp"
#include <limits> #include <limits>
#include <type_traits>
namespace caf::detail::parser { namespace caf::detail::parser {
...@@ -18,7 +19,8 @@ namespace caf::detail::parser { ...@@ -18,7 +19,8 @@ namespace caf::detail::parser {
// @pre `isdigit(c) || (Base == 16 && isxdigit(c))` // @pre `isdigit(c) || (Base == 16 && isxdigit(c))`
// @warning can leave `x` in an intermediate state when retuning `false` // @warning can leave `x` in an intermediate state when retuning `false`
template <int Base, class T> template <int Base, class T>
bool add_ascii(T& x, char c, enable_if_tt<std::is_integral<T>, int> u = 0) { bool add_ascii(T& x, char c,
std::enable_if_t<std::is_integral_v<T>, int> u = 0) {
CAF_IGNORE_UNUSED(u); CAF_IGNORE_UNUSED(u);
if (x > (std::numeric_limits<T>::max() / Base)) if (x > (std::numeric_limits<T>::max() / Base))
return false; return false;
...@@ -33,7 +35,7 @@ bool add_ascii(T& x, char c, enable_if_tt<std::is_integral<T>, int> u = 0) { ...@@ -33,7 +35,7 @@ bool add_ascii(T& x, char c, enable_if_tt<std::is_integral<T>, int> u = 0) {
template <int Base, class T> template <int Base, class T>
bool add_ascii(T& x, char c, bool add_ascii(T& x, char c,
enable_if_tt<std::is_floating_point<T>, int> u = 0) { std::enable_if_t<std::is_floating_point_v<T>, int> u = 0) {
CAF_IGNORE_UNUSED(u); CAF_IGNORE_UNUSED(u);
ascii_to_int<Base, T> f; ascii_to_int<Base, T> f;
x = (x * Base) + f(c); x = (x * Base) + f(c);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "caf/detail/type_traits.hpp" #include "caf/detail/type_traits.hpp"
#include <limits> #include <limits>
#include <type_traits>
namespace caf::detail::parser { namespace caf::detail::parser {
...@@ -17,7 +18,8 @@ namespace caf::detail::parser { ...@@ -17,7 +18,8 @@ namespace caf::detail::parser {
// @pre `isdigit(c) || (Base == 16 && isxdigit(c))` // @pre `isdigit(c) || (Base == 16 && isxdigit(c))`
// @warning can leave `x` in an intermediate state when retuning `false` // @warning can leave `x` in an intermediate state when retuning `false`
template <int Base, class T> template <int Base, class T>
bool sub_ascii(T& x, char c, enable_if_tt<std::is_integral<T>, int> u = 0) { bool sub_ascii(T& x, char c,
std::enable_if_t<std::is_integral_v<T>, int> u = 0) {
CAF_IGNORE_UNUSED(u); CAF_IGNORE_UNUSED(u);
if (x < (std::numeric_limits<T>::min() / Base)) if (x < (std::numeric_limits<T>::min() / Base))
return false; return false;
...@@ -32,7 +34,7 @@ bool sub_ascii(T& x, char c, enable_if_tt<std::is_integral<T>, int> u = 0) { ...@@ -32,7 +34,7 @@ bool sub_ascii(T& x, char c, enable_if_tt<std::is_integral<T>, int> u = 0) {
template <int Base, class T> template <int Base, class T>
bool sub_ascii(T& x, char c, bool sub_ascii(T& x, char c,
enable_if_tt<std::is_floating_point<T>, int> u = 0) { std::enable_if_t<std::is_floating_point_v<T>, int> u = 0) {
CAF_IGNORE_UNUSED(u); CAF_IGNORE_UNUSED(u);
ascii_to_int<Base, T> f; ascii_to_int<Base, T> f;
x = static_cast<T>((x * Base) - f(c)); x = static_cast<T>((x * Base) - f(c));
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#pragma once #pragma once
#include "caf/detail/type_traits.hpp"
#include "caf/infer_handle.hpp" #include "caf/infer_handle.hpp"
#include <type_traits> #include <type_traits>
...@@ -15,8 +14,7 @@ namespace caf::detail { ...@@ -15,8 +14,7 @@ namespace caf::detail {
/// implementation `Impl` with arguments of type `Ts...`. /// implementation `Impl` with arguments of type `Ts...`.
template <class F, class Impl, class... Ts> template <class F, class Impl, class... Ts>
constexpr bool spawnable() { constexpr bool spawnable() {
return is_callable_with<F, Ts...>::value return std::is_invocable_v<F, Ts...> || std::is_invocable_v<F, Impl*, Ts...>;
|| is_callable_with<F, Impl*, Ts...>::value;
} }
} // namespace caf::detail } // namespace caf::detail
...@@ -60,25 +60,8 @@ namespace caf::detail { ...@@ -60,25 +60,8 @@ namespace caf::detail {
template <class T> template <class T>
constexpr T* null_v = nullptr; constexpr T* null_v = nullptr;
// -- backport of C++14 additions ----------------------------------------------
template <class T>
using decay_t = std::decay_t<T>;
template <bool B, class T, class F>
using conditional_t = typename std::conditional<B, T, F>::type;
template <bool V, class T = void>
using enable_if_t = std::enable_if_t<V, T>;
// -- custom traits ------------------------------------------------------------ // -- custom traits ------------------------------------------------------------
template <class Trait, class T = void>
using enable_if_tt = std::enable_if_t<Trait::value, T>;
template <class T>
using remove_reference_t = std::remove_reference_t<T>;
/// Checks whether `T` defines a free function `to_string`. /// Checks whether `T` defines a free function `to_string`.
template <class T> template <class T>
class has_to_string { class has_to_string {
...@@ -105,42 +88,6 @@ using bool_token = std::integral_constant<bool, X>; ...@@ -105,42 +88,6 @@ using bool_token = std::integral_constant<bool, X>;
template <int X> template <int X>
using int_token = std::integral_constant<int, X>; using int_token = std::integral_constant<int, X>;
/// Joins all bool constants using operator &&.
template <bool... BoolConstants>
struct conjunction;
template <>
struct conjunction<> {
static constexpr bool value = true;
};
template <bool X, bool... Xs>
struct conjunction<X, Xs...> {
static constexpr bool value = X && conjunction<Xs...>::value;
};
/// Convenience alias for `conjunction<BoolConstants...>::value`.
template <bool... BoolConstants>
bool constexpr conjunction_v = conjunction<BoolConstants...>::value;
/// Joins all bool constants using operator ||.
template <bool... BoolConstants>
struct disjunction;
template <>
struct disjunction<> {
static constexpr bool value = false;
};
template <bool X, bool... Xs>
struct disjunction<X, Xs...> {
static constexpr bool value = X || disjunction<Xs...>::value;
};
/// Convenience alias for `disjunction<BoolConstants...>::value`.
template <bool... BoolConstants>
bool constexpr disjunction_v = disjunction<BoolConstants...>::value;
/// Checks whether `T` is a `std::chrono::duration`. /// Checks whether `T` is a `std::chrono::duration`.
template <class T> template <class T>
struct is_duration : std::false_type {}; struct is_duration : std::false_type {};
...@@ -182,8 +129,7 @@ class is_comparable { ...@@ -182,8 +129,7 @@ class is_comparable {
static void cmp_help_fun(const A*, const B*, void*, C); static void cmp_help_fun(const A*, const B*, void*, C);
using result_type = decltype(cmp_help_fun( using result_type = decltype(cmp_help_fun(
static_cast<T1*>(nullptr), static_cast<T2*>(nullptr), null_v<T1>, null_v<T2>, null_v<bool>,
static_cast<bool*>(nullptr),
std::integral_constant<bool, std::is_arithmetic_v<T1> std::integral_constant<bool, std::is_arithmetic_v<T1>
&& std::is_arithmetic_v<T2>>{})); && std::is_arithmetic_v<T2>>{}));
...@@ -201,13 +147,13 @@ class is_forward_iterator { ...@@ -201,13 +147,13 @@ class is_forward_iterator {
template <class C> template <class C>
static bool sfinae(C& x, C& y, static bool sfinae(C& x, C& y,
// check for operator* // check for operator*
decay_t<decltype(*x)>* = nullptr, std::decay_t<decltype(*x)>* = nullptr,
// check for operator++ returning an iterator // check for operator++ returning an iterator
decay_t<decltype(x = ++y)>* = nullptr, std::decay_t<decltype(x = ++y)>* = nullptr,
// check for operator== // check for operator==
decay_t<decltype(x == y)>* = nullptr, std::decay_t<decltype(x == y)>* = nullptr,
// check for operator!= // check for operator!=
decay_t<decltype(x != y)>* = nullptr); std::decay_t<decltype(x != y)>* = nullptr);
static void sfinae(...); static void sfinae(...);
...@@ -217,23 +163,27 @@ public: ...@@ -217,23 +163,27 @@ public:
static constexpr bool value = std::is_same_v<bool, result_type>; static constexpr bool value = std::is_same_v<bool, result_type>;
}; };
/// Convenience alias for `is_forward_iterator<T>::value`.
template <class T>
inline constexpr bool is_forward_iterator_v = is_forward_iterator<T>::value;
/// Checks whether `T` has `begin()` and `end()` member /// Checks whether `T` has `begin()` and `end()` member
/// functions returning forward iterators. /// functions returning forward iterators.
template <class T> template <class T>
class is_iterable { class is_iterable {
// this horrible code would just disappear if we had concepts // this horrible code would just disappear if we had concepts
template <class C> template <class C>
static bool static bool sfinae(
sfinae(C* cc, C* cc,
// check if 'C::begin()' returns a forward iterator // check if 'C::begin()' returns a forward iterator
enable_if_tt<is_forward_iterator<decltype(cc->begin())>>* = nullptr, std::enable_if_t<is_forward_iterator_v<decltype(cc->begin())>>* = nullptr,
// check if begin() and end() both exist and are comparable // check if begin() and end() both exist and are comparable
decltype(cc->begin() != cc->end())* = nullptr); decltype(cc->begin() != cc->end())* = nullptr);
// SFNINAE default // SFNINAE default
static void sfinae(void*); static void sfinae(void*);
using result_type = decltype(sfinae(static_cast<decay_t<T>*>(nullptr))); using result_type = decltype(sfinae(null_v<std::decay_t<T>>));
public: public:
static constexpr bool value = is_primitive<T>::value == false static constexpr bool value = is_primitive<T>::value == false
...@@ -366,12 +316,12 @@ struct get_callable_trait_helper<T, false, false> {}; ...@@ -366,12 +316,12 @@ struct get_callable_trait_helper<T, false, false> {};
/// i.e., a function, member function, or a class providing /// i.e., a function, member function, or a class providing
/// the call operator. /// the call operator.
template <class T> template <class T>
struct get_callable_trait : get_callable_trait_helper<decay_t<T>> {}; struct get_callable_trait : get_callable_trait_helper<std::decay_t<T>> {};
template <class T> template <class T>
using get_callable_trait_t = typename get_callable_trait<T>::type; using get_callable_trait_t = typename get_callable_trait<T>::type;
/// Checks whether `T` is a function or member function. /// Checks whether `T` is a function, function object or member function.
template <class T> template <class T>
struct is_callable { struct is_callable {
template <class C> template <class C>
...@@ -379,7 +329,7 @@ struct is_callable { ...@@ -379,7 +329,7 @@ struct is_callable {
static void _fun(void*); static void _fun(void*);
using result_type = decltype(_fun(static_cast<decay_t<T>*>(nullptr))); using result_type = decltype(_fun(null_v<std::decay_t<T>>));
public: public:
static constexpr bool value = std::is_same_v<bool, result_type>; static constexpr bool value = std::is_same_v<bool, result_type>;
...@@ -390,20 +340,6 @@ public: ...@@ -390,20 +340,6 @@ public:
template <class T> template <class T>
inline constexpr bool is_callable_v = is_callable<T>::value; inline constexpr bool is_callable_v = is_callable<T>::value;
/// Checks whether `F` is callable with arguments of types `Ts...`.
template <class F, class... Ts>
struct is_callable_with {
template <class U>
static auto sfinae(U*)
-> decltype((std::declval<U&>())(std::declval<Ts>()...), std::true_type());
template <class U>
static auto sfinae(...) -> std::false_type;
using type = decltype(sfinae<F>(nullptr));
static constexpr bool value = type::value;
};
/// Checks whether `F` takes mutable references. /// Checks whether `F` takes mutable references.
/// ///
/// A manipulator is a functor that manipulates its arguments via /// A manipulator is a functor that manipulates its arguments via
...@@ -451,7 +387,7 @@ private: ...@@ -451,7 +387,7 @@ private:
static int fun(void*); static int fun(void*);
public: public:
static constexpr bool value = sizeof(fun(static_cast<derived*>(nullptr))) > 1; static constexpr bool value = sizeof(fun(null_v<derived>)) > 1;
}; };
template <class T> template <class T>
...@@ -491,9 +427,6 @@ struct value_type_of<T*> { ...@@ -491,9 +427,6 @@ struct value_type_of<T*> {
template <class T> template <class T>
using value_type_of_t = typename value_type_of<T>::type; using value_type_of_t = typename value_type_of<T>::type;
template <class T>
using is_callable_t = typename std::enable_if<is_callable_v<T>>::type;
template <class F, class T> template <class F, class T>
using is_handler_for_ef = typename std::enable_if<is_handler_for_v<F, T>>::type; using is_handler_for_ef = typename std::enable_if<is_handler_for_v<F, T>>::type;
...@@ -522,7 +455,7 @@ constexpr bool can_insert_elements_impl(void*) { ...@@ -522,7 +455,7 @@ constexpr bool can_insert_elements_impl(void*) {
template <class T> template <class T>
constexpr bool can_insert_elements() { constexpr bool can_insert_elements() {
return can_insert_elements_impl<T>(static_cast<T*>(nullptr)); return can_insert_elements_impl<T>(null_v<T>);
} }
/// Checks whether `Tpl` is a specialization of `T` or not. /// Checks whether `Tpl` is a specialization of `T` or not.
...@@ -626,23 +559,6 @@ CAF_HAS_ALIAS_TRAIT(mapped_type); ...@@ -626,23 +559,6 @@ CAF_HAS_ALIAS_TRAIT(mapped_type);
// -- constexpr functions for use in enable_if & friends ----------------------- // -- constexpr functions for use in enable_if & friends -----------------------
template <class List1, class List2>
struct all_constructible : std::false_type {};
template <>
struct all_constructible<type_list<>, type_list<>> : std::true_type {};
template <class T, class... Ts, class U, class... Us>
struct all_constructible<type_list<T, Ts...>, type_list<U, Us...>> {
static constexpr bool value
= std::is_constructible_v<T, U>
&& all_constructible<type_list<Ts...>, type_list<Us...>>::value;
};
/// Convenience alias for `all_constructible<Ts, Us>::value`.
template <class Ts, class Us>
inline constexpr bool all_constructible_v = all_constructible<Ts, Us>::value;
/// Checks whether T behaves like `std::map`. /// Checks whether T behaves like `std::map`.
template <class T> template <class T>
struct is_map_like { struct is_map_like {
...@@ -799,38 +715,6 @@ struct is_list_like { ...@@ -799,38 +715,6 @@ struct is_list_like {
template <class T> template <class T>
constexpr bool is_list_like_v = is_list_like<T>::value; constexpr bool is_list_like_v = is_list_like<T>::value;
template <class F, class... Ts>
struct is_invocable {
private:
template <class U>
static auto sfinae(U* f)
-> decltype((*f)(std::declval<Ts>()...), std::true_type());
template <class U>
static auto sfinae(...) -> std::false_type;
using sfinae_type = decltype(sfinae<F>(nullptr));
public:
static constexpr bool value = sfinae_type::value;
};
template <class R, class F, class... Ts>
struct is_invocable_r {
private:
template <class U>
static auto sfinae(U* f)
-> std::is_same<R, decltype((*f)(std::declval<Ts>()...))>;
template <class U>
static auto sfinae(...) -> std::false_type;
using sfinae_type = decltype(sfinae<F>(nullptr));
public:
static constexpr bool value = sfinae_type::value;
};
template <class T, class To> template <class T, class To>
class has_convertible_data_member { class has_convertible_data_member {
private: private:
......
...@@ -231,28 +231,28 @@ bool operator!=(std::nullptr_t, const intrusive_ptr<T>& x) { ...@@ -231,28 +231,28 @@ bool operator!=(std::nullptr_t, const intrusive_ptr<T>& x) {
/// @relates intrusive_ptr /// @relates intrusive_ptr
template <class T, class U> template <class T, class U>
detail::enable_if_t<detail::is_comparable<T*, U*>::value, bool> std::enable_if_t<detail::is_comparable<T*, U*>::value, bool>
operator==(const intrusive_ptr<T>& lhs, const U* rhs) { operator==(const intrusive_ptr<T>& lhs, const U* rhs) {
return lhs.get() == rhs; return lhs.get() == rhs;
} }
/// @relates intrusive_ptr /// @relates intrusive_ptr
template <class T, class U> template <class T, class U>
detail::enable_if_t<detail::is_comparable<T*, U*>::value, bool> std::enable_if_t<detail::is_comparable<T*, U*>::value, bool>
operator==(const T* lhs, const intrusive_ptr<U>& rhs) { operator==(const T* lhs, const intrusive_ptr<U>& rhs) {
return lhs == rhs.get(); return lhs == rhs.get();
} }
/// @relates intrusive_ptr /// @relates intrusive_ptr
template <class T, class U> template <class T, class U>
detail::enable_if_t<detail::is_comparable<T*, U*>::value, bool> std::enable_if_t<detail::is_comparable<T*, U*>::value, bool>
operator!=(const intrusive_ptr<T>& lhs, const U* rhs) { operator!=(const intrusive_ptr<T>& lhs, const U* rhs) {
return lhs.get() != rhs; return lhs.get() != rhs;
} }
/// @relates intrusive_ptr /// @relates intrusive_ptr
template <class T, class U> template <class T, class U>
detail::enable_if_t<detail::is_comparable<T*, U*>::value, bool> std::enable_if_t<detail::is_comparable<T*, U*>::value, bool>
operator!=(const T* lhs, const intrusive_ptr<U>& rhs) { operator!=(const T* lhs, const intrusive_ptr<U>& rhs) {
return lhs != rhs.get(); return lhs != rhs.get();
} }
...@@ -261,14 +261,14 @@ operator!=(const T* lhs, const intrusive_ptr<U>& rhs) { ...@@ -261,14 +261,14 @@ operator!=(const T* lhs, const intrusive_ptr<U>& rhs) {
/// @relates intrusive_ptr /// @relates intrusive_ptr
template <class T, class U> template <class T, class U>
detail::enable_if_t<detail::is_comparable_v<T*, U*>, bool> std::enable_if_t<detail::is_comparable_v<T*, U*>, bool>
operator==(const intrusive_ptr<T>& x, const intrusive_ptr<U>& y) { operator==(const intrusive_ptr<T>& x, const intrusive_ptr<U>& y) {
return x.get() == y.get(); return x.get() == y.get();
} }
/// @relates intrusive_ptr /// @relates intrusive_ptr
template <class T, class U> template <class T, class U>
detail::enable_if_t<detail::is_comparable_v<T*, U*>, bool> std::enable_if_t<detail::is_comparable_v<T*, U*>, bool>
operator!=(const intrusive_ptr<T>& x, const intrusive_ptr<U>& y) { operator!=(const intrusive_ptr<T>& x, const intrusive_ptr<U>& y) {
return x.get() != y.get(); return x.get() != y.get();
} }
......
...@@ -165,7 +165,7 @@ public: ...@@ -165,7 +165,7 @@ public:
line_builder(); line_builder();
template <class T> template <class T>
detail::enable_if_t<!std::is_pointer_v<T>, line_builder&> std::enable_if_t<!std::is_pointer_v<T>, line_builder&>
operator<<(const T& x) { operator<<(const T& x) {
if (!str_.empty()) if (!str_.empty())
str_ += " "; str_ += " ";
......
...@@ -26,4 +26,7 @@ struct may_have_timeout<timeout_definition<F>> { ...@@ -26,4 +26,7 @@ struct may_have_timeout<timeout_definition<F>> {
static constexpr bool value = true; static constexpr bool value = true;
}; };
template <class T>
inline constexpr bool may_have_timeout_v = may_have_timeout<T>::value;
} // namespace caf } // namespace caf
...@@ -61,9 +61,8 @@ public: ...@@ -61,9 +61,8 @@ public:
template <class... Ts> template <class... Ts>
void assign(Ts... xs) { void assign(Ts... xs) {
static_assert(sizeof...(Ts) > 0, "assign without arguments called"); static_assert(sizeof...(Ts) > 0, "assign without arguments called");
static_assert( static_assert(!(may_have_timeout_v<std::decay_t<Ts>> || ...),
!detail::disjunction<may_have_timeout<std::decay_t<Ts>>::value...>::value, "Timeouts are only allowed in behaviors");
"Timeouts are only allowed in behaviors");
impl_ = detail::make_behavior(xs...); impl_ = detail::make_behavior(xs...);
} }
...@@ -83,9 +82,8 @@ public: ...@@ -83,9 +82,8 @@ public:
/// Returns a new handler that concatenates this handler /// Returns a new handler that concatenates this handler
/// with a new handler from `xs...`. /// with a new handler from `xs...`.
template <class... Ts> template <class... Ts>
std::conditional_t< std::conditional_t<(may_have_timeout_v<std::decay_t<Ts>> || ...), behavior,
detail::disjunction_v<may_have_timeout<std::decay_t<Ts>>::value...>, message_handler>
behavior, message_handler>
or_else(Ts&&... xs) const { or_else(Ts&&... xs) const {
// using a behavior is safe here, because we "cast" // using a behavior is safe here, because we "cast"
// it back to a message_handler when appropriate // it back to a message_handler when appropriate
......
...@@ -50,7 +50,7 @@ public: ...@@ -50,7 +50,7 @@ public:
Ts&&... xs) { Ts&&... xs) {
using namespace detail; using namespace detail;
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
using token = type_list<implicit_conversions_t<decay_t<Ts>>...>; using token = type_list<implicit_conversions_t<std::decay_t<Ts>>...>;
static_assert(response_type_unbox<signatures_of_t<Handle>, token>::valid, static_assert(response_type_unbox<signatures_of_t<Handle>, token>::valid,
"receiver does not accept given message"); "receiver does not accept given message");
auto self = static_cast<Subtype*>(this); auto self = static_cast<Subtype*>(this);
...@@ -67,7 +67,7 @@ public: ...@@ -67,7 +67,7 @@ public:
} }
using response_type using response_type
= response_type_t<typename Handle::signatures, = response_type_t<typename Handle::signatures,
detail::implicit_conversions_t<detail::decay_t<Ts>>...>; detail::implicit_conversions_t<std::decay_t<Ts>>...>;
using handle_type using handle_type
= response_handle<Subtype, policy::single_response<response_type>>; = response_handle<Subtype, policy::single_response<response_type>>;
return handle_type{self, req_id.response_id(), std::move(pending_msg)}; return handle_type{self, req_id.response_id(), std::move(pending_msg)};
...@@ -101,7 +101,7 @@ public: ...@@ -101,7 +101,7 @@ public:
using handle_type = typename Container::value_type; using handle_type = typename Container::value_type;
using namespace detail; using namespace detail;
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
using token = type_list<implicit_conversions_t<decay_t<Ts>>...>; using token = type_list<implicit_conversions_t<std::decay_t<Ts>>...>;
static_assert( static_assert(
response_type_unbox<signatures_of_t<handle_type>, token>::valid, response_type_unbox<signatures_of_t<handle_type>, token>::valid,
"receiver does not accept given message"); "receiver does not accept given message");
...@@ -128,7 +128,7 @@ public: ...@@ -128,7 +128,7 @@ public:
} }
using response_type using response_type
= response_type_t<typename handle_type::signatures, = response_type_t<typename handle_type::signatures,
detail::implicit_conversions_t<detail::decay_t<Ts>>...>; detail::implicit_conversions_t<std::decay_t<Ts>>...>;
using result_type = response_handle<Subtype, MergePolicy<response_type>>; using result_type = response_handle<Subtype, MergePolicy<response_type>>;
return result_type{dptr, std::move(ids), return result_type{dptr, std::move(ids),
disposable::make_composite(std::move(pending_msgs))}; disposable::make_composite(std::move(pending_msgs))};
......
...@@ -67,7 +67,7 @@ public: ...@@ -67,7 +67,7 @@ public:
/// Sends `{xs...}` as an asynchronous message to `dest` with priority `mp`. /// Sends `{xs...}` as an asynchronous message to `dest` with priority `mp`.
template <message_priority P = message_priority::normal, class Dest, template <message_priority P = message_priority::normal, class Dest,
class... Ts> class... Ts>
detail::enable_if_t<!std::is_same_v<group, Dest>> std::enable_if_t<!std::is_same_v<group, Dest>>
send(const Dest& dest, Ts&&... xs) { send(const Dest& dest, Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
static_assert((detail::sendable<Ts> && ...), static_assert((detail::sendable<Ts> && ...),
...@@ -99,7 +99,7 @@ public: ...@@ -99,7 +99,7 @@ public:
/// passed already). /// passed already).
template <message_priority P = message_priority::normal, class Dest = actor, template <message_priority P = message_priority::normal, class Dest = actor,
class... Ts> class... Ts>
detail::enable_if_t<!std::is_same_v<Dest, group>, disposable> std::enable_if_t<!std::is_same_v<Dest, group>, disposable>
scheduled_send(const Dest& dest, actor_clock::time_point timeout, scheduled_send(const Dest& dest, actor_clock::time_point timeout,
Ts&&... xs) { Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
...@@ -139,7 +139,7 @@ public: ...@@ -139,7 +139,7 @@ public:
/// Sends a message after a relative timeout. /// Sends a message after a relative timeout.
template <message_priority P = message_priority::normal, class Rep = int, template <message_priority P = message_priority::normal, class Rep = int,
class Period = std::ratio<1>, class Dest = actor, class... Ts> class Period = std::ratio<1>, class Dest = actor, class... Ts>
detail::enable_if_t<!std::is_same_v<Dest, group>, disposable> std::enable_if_t<!std::is_same_v<Dest, group>, disposable>
delayed_send(const Dest& dest, std::chrono::duration<Rep, Period> rel_timeout, delayed_send(const Dest& dest, std::chrono::duration<Rep, Period> rel_timeout,
Ts&&... xs) { Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
...@@ -230,12 +230,12 @@ private: ...@@ -230,12 +230,12 @@ private:
} }
template <class T = Base> template <class T = Base>
detail::enable_if_t<std::is_base_of_v<abstract_actor, T>, Subtype*> dptr() { std::enable_if_t<std::is_base_of_v<abstract_actor, T>, Subtype*> dptr() {
return static_cast<Subtype*>(this); return static_cast<Subtype*>(this);
} }
template <class T = Subtype, class = detail::enable_if_t<std::is_base_of< template <class T = Subtype, class = std::enable_if_t<
typed_actor_view_base, T>::value>> std::is_base_of_v<typed_actor_view_base, T>>>
typename T::pointer dptr() { typename T::pointer dptr() {
return static_cast<Subtype*>(this)->internal_ptr(); return static_cast<Subtype*>(this)->internal_ptr();
} }
......
...@@ -140,7 +140,7 @@ public: ...@@ -140,7 +140,7 @@ public:
template <class Fun> template <class Fun>
using type_checker using type_checker
= detail::type_checker<response_type, = detail::type_checker<response_type,
detail::select_all_helper_t<detail::decay_t<Fun>>>; detail::select_all_helper_t<std::decay_t<Fun>>>;
explicit select_all(message_id_list ids, disposable pending_timeouts) explicit select_all(message_id_list ids, disposable pending_timeouts)
: ids_(std::move(ids)), pending_timeouts_(std::move(pending_timeouts)) { : ids_(std::move(ids)), pending_timeouts_(std::move(pending_timeouts)) {
...@@ -171,7 +171,7 @@ public: ...@@ -171,7 +171,7 @@ public:
template <class Self, class F, class G> template <class Self, class F, class G>
void receive(Self* self, F&& f, G&& g) { void receive(Self* self, F&& f, G&& g) {
CAF_LOG_TRACE(CAF_ARG(ids_)); CAF_LOG_TRACE(CAF_ARG(ids_));
using helper_type = detail::select_all_helper_t<detail::decay_t<F>>; using helper_type = detail::select_all_helper_t<std::decay_t<F>>;
helper_type helper{ids_.size(), pending_timeouts_, std::forward<F>(f)}; helper_type helper{ids_.size(), pending_timeouts_, std::forward<F>(f)};
auto error_handler = [&](error& err) mutable { auto error_handler = [&](error& err) mutable {
if (*helper.pending > 0) { if (*helper.pending > 0) {
...@@ -200,7 +200,7 @@ private: ...@@ -200,7 +200,7 @@ private:
template <class F, class OnError> template <class F, class OnError>
behavior make_behavior(F&& f, OnError&& g) { behavior make_behavior(F&& f, OnError&& g) {
using namespace detail; using namespace detail;
using helper_type = select_all_helper_t<decay_t<F>>; using helper_type = select_all_helper_t<std::decay_t<F>>;
helper_type helper{ids_.size(), pending_timeouts_, std::forward<F>(f)}; helper_type helper{ids_.size(), pending_timeouts_, std::forward<F>(f)};
auto pending = helper.pending; auto pending = helper.pending;
auto error_handler = [pending{std::move(pending)}, auto error_handler = [pending{std::move(pending)},
......
...@@ -55,8 +55,7 @@ public: ...@@ -55,8 +55,7 @@ public:
using message_id_list = std::vector<message_id>; using message_id_list = std::vector<message_id>;
template <class Fun> template <class Fun>
using type_checker using type_checker = detail::type_checker<response_type, std::decay_t<Fun>>;
= detail::type_checker<response_type, detail::decay_t<Fun>>;
explicit select_any(message_id_list ids, disposable pending_timeouts) explicit select_any(message_id_list ids, disposable pending_timeouts)
: ids_(std::move(ids)), pending_timeouts_(std::move(pending_timeouts)) { : ids_(std::move(ids)), pending_timeouts_(std::move(pending_timeouts)) {
......
...@@ -55,13 +55,13 @@ public: ...@@ -55,13 +55,13 @@ public:
// -- non-blocking API ------------------------------------------------------- // -- non-blocking API -------------------------------------------------------
template <class T = traits, class F, class OnError> template <class T = traits, class F, class OnError>
detail::enable_if_t<T::is_non_blocking> await(F f, OnError g) { std::enable_if_t<T::is_non_blocking> await(F f, OnError g) {
static_assert(detail::has_add_awaited_response_handler_v<ActorType>, static_assert(detail::has_add_awaited_response_handler_v<ActorType>,
"this actor type does not support awaiting responses, " "this actor type does not support awaiting responses, "
"try using .then instead"); "try using .then instead");
static_assert(detail::is_callable<F>::value, static_assert(detail::is_callable_v<F>,
"F must provide a single, non-template operator()"); "F must provide a single, non-template operator()");
static_assert(detail::is_callable_with<OnError, error&>::value, static_assert(std::is_invocable_v<OnError, error&>,
"OnError must provide an operator() that takes a caf::error"); "OnError must provide an operator() that takes a caf::error");
using result_type = typename detail::get_callable_trait<F>::result_type; using result_type = typename detail::get_callable_trait<F>::result_type;
static_assert(std::is_same_v<void, result_type>, static_assert(std::is_same_v<void, result_type>,
...@@ -72,21 +72,21 @@ public: ...@@ -72,21 +72,21 @@ public:
} }
template <class T = traits, class F> template <class T = traits, class F>
detail::enable_if_t<detail::has_call_error_handler_v<ActorType> // std::enable_if_t<detail::has_call_error_handler_v<ActorType> //
&& T::is_non_blocking> && T::is_non_blocking>
await(F f) { await(F f) {
auto self = self_; auto self = self_;
await(std::move(f), [self](error& err) { self->call_error_handler(err); }); await(std::move(f), [self](error& err) { self->call_error_handler(err); });
} }
template <class T = traits, class F, class OnError> template <class T = traits, class F, class OnError>
detail::enable_if_t<T::is_non_blocking> then(F f, OnError g) { std::enable_if_t<T::is_non_blocking> then(F f, OnError g) {
static_assert(detail::has_add_multiplexed_response_handler_v<ActorType>, static_assert(detail::has_add_multiplexed_response_handler_v<ActorType>,
"this actor type does not support multiplexed responses, " "this actor type does not support multiplexed responses, "
"try using .await instead"); "try using .await instead");
static_assert(detail::is_callable<F>::value, static_assert(detail::is_callable_v<F>,
"F must provide a single, non-template operator()"); "F must provide a single, non-template operator()");
static_assert(detail::is_callable_with<OnError, error&>::value, static_assert(std::is_invocable_v<OnError, error&>,
"OnError must provide an operator() that takes a caf::error"); "OnError must provide an operator() that takes a caf::error");
using result_type = typename detail::get_callable_trait<F>::result_type; using result_type = typename detail::get_callable_trait<F>::result_type;
static_assert(std::is_same_v<void, result_type>, static_assert(std::is_same_v<void, result_type>,
...@@ -97,8 +97,8 @@ public: ...@@ -97,8 +97,8 @@ public:
} }
template <class T = traits, class F> template <class T = traits, class F>
detail::enable_if_t<detail::has_call_error_handler_v<ActorType> // std::enable_if_t<detail::has_call_error_handler_v<ActorType> //
&& T::is_non_blocking> && T::is_non_blocking>
then(F f) { then(F f) {
auto self = self_; auto self = self_;
then(std::move(f), [self](error& err) { self->call_error_handler(err); }); then(std::move(f), [self](error& err) { self->call_error_handler(err); });
...@@ -121,11 +121,11 @@ public: ...@@ -121,11 +121,11 @@ public:
// -- blocking API ----------------------------------------------------------- // -- blocking API -----------------------------------------------------------
template <class T = traits, class F = none_t, class OnError = none_t, template <class T = traits, class F = none_t, class OnError = none_t,
class = detail::enable_if_t<T::is_blocking>> class = std::enable_if_t<T::is_blocking>>
detail::is_handler_for_ef<OnError, error> receive(F f, OnError g) { detail::is_handler_for_ef<OnError, error> receive(F f, OnError g) {
static_assert(detail::is_callable<F>::value, static_assert(detail::is_callable_v<F>,
"F must provide a single, non-template operator()"); "F must provide a single, non-template operator()");
static_assert(detail::is_callable_with<OnError, error&>::value, static_assert(std::is_invocable_v<OnError, error&>,
"OnError must provide an operator() that takes a caf::error"); "OnError must provide an operator() that takes a caf::error");
using result_type = typename detail::get_callable_trait<F>::result_type; using result_type = typename detail::get_callable_trait<F>::result_type;
static_assert(std::is_same_v<void, result_type>, static_assert(std::is_same_v<void, result_type>,
...@@ -136,7 +136,7 @@ public: ...@@ -136,7 +136,7 @@ public:
} }
template <class T = traits, class OnError = none_t, class F = none_t, template <class T = traits, class OnError = none_t, class F = none_t,
class = detail::enable_if_t<T::is_blocking>> class = std::enable_if_t<T::is_blocking>>
detail::is_handler_for_ef<OnError, error> receive(OnError g, F f) { detail::is_handler_for_ef<OnError, error> receive(OnError g, F f) {
// TODO: allowing blocking actors to pass the error handler in first may be // TODO: allowing blocking actors to pass the error handler in first may be
// more flexible, but it makes the API asymmetric. Consider // more flexible, but it makes the API asymmetric. Consider
...@@ -146,7 +146,7 @@ public: ...@@ -146,7 +146,7 @@ public:
template <class T = policy_type, class OnError = none_t, class F = none_t, template <class T = policy_type, class OnError = none_t, class F = none_t,
class E = detail::is_handler_for_ef<OnError, error>, class E = detail::is_handler_for_ef<OnError, error>,
class = detail::enable_if_t<T::is_trivial>> class = std::enable_if_t<T::is_trivial>>
void receive(OnError g, catch_all<F> f) { void receive(OnError g, catch_all<F> f) {
// TODO: this bypasses the policy. Either we deprecate `catch_all` or *all* // TODO: this bypasses the policy. Either we deprecate `catch_all` or *all*
// policies must support it. Currently, we only enable this member // policies must support it. Currently, we only enable this member
...@@ -157,7 +157,7 @@ public: ...@@ -157,7 +157,7 @@ public:
// -- properties ------------------------------------------------------------- // -- properties -------------------------------------------------------------
template <class T = policy_type, class = detail::enable_if_t<T::is_trivial>> template <class T = policy_type, class = std::enable_if_t<T::is_trivial>>
message_id id() const noexcept { message_id id() const noexcept {
return policy_.id(); return policy_.id();
} }
......
...@@ -90,7 +90,7 @@ void anon_send(const Dest& dest, Ts&&... xs) { ...@@ -90,7 +90,7 @@ void anon_send(const Dest& dest, Ts&&... xs) {
template <message_priority P = message_priority::normal, class Dest = actor, template <message_priority P = message_priority::normal, class Dest = actor,
class Rep = int, class Period = std::ratio<1>, class... Ts> class Rep = int, class Period = std::ratio<1>, class... Ts>
detail::enable_if_t<!std::is_same_v<Dest, group>> std::enable_if_t<!std::is_same_v<Dest, group>>
delayed_anon_send(const Dest& dest, std::chrono::duration<Rep, Period> rtime, delayed_anon_send(const Dest& dest, std::chrono::duration<Rep, Period> rtime,
Ts&&... xs) { Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
......
...@@ -207,7 +207,7 @@ span<std::byte> as_writable_bytes(span<T> xs) { ...@@ -207,7 +207,7 @@ span<std::byte> as_writable_bytes(span<T> xs) {
/// Convenience function to make using `caf::span` more convenient without the /// Convenience function to make using `caf::span` more convenient without the
/// deduction guides. /// deduction guides.
template <class T> template <class T>
auto make_span(T& xs) -> span<detail::remove_reference_t<decltype(xs[0])>> { auto make_span(T& xs) -> span<std::remove_reference_t<decltype(xs[0])>> {
return {xs.data(), xs.size()}; return {xs.data(), xs.size()};
} }
......
...@@ -121,7 +121,7 @@ public: ...@@ -121,7 +121,7 @@ public:
// allow `handle_type{this}` for typed actors // allow `handle_type{this}` for typed actors
template <class T, template <class T,
class = detail::enable_if_t<actor_traits<T>::is_statically_typed>> class = std::enable_if_t<actor_traits<T>::is_statically_typed>>
typed_actor(T* ptr) : ptr_(ptr->ctrl()) { typed_actor(T* ptr) : ptr_(ptr->ctrl()) {
static_assert( static_assert(
detail::tl_subset_of<signatures, typename T::signatures>::value, detail::tl_subset_of<signatures, typename T::signatures>::value,
......
...@@ -23,7 +23,7 @@ public: ...@@ -23,7 +23,7 @@ public:
} }
template <class Supertype, template <class Supertype,
class = detail::enable_if_t< // class = std::enable_if_t< //
detail::tl_subset_of<detail::type_list<Sigs...>, detail::tl_subset_of<detail::type_list<Sigs...>,
typename Supertype::signatures>::value>> typename Supertype::signatures>::value>>
typed_actor_pointer(Supertype* selfptr) : view_(selfptr) { typed_actor_pointer(Supertype* selfptr) : view_(selfptr) {
...@@ -31,7 +31,7 @@ public: ...@@ -31,7 +31,7 @@ public:
} }
template <class... OtherSigs, template <class... OtherSigs,
class = detail::enable_if_t< // class = std::enable_if_t< //
detail::tl_subset_of<detail::type_list<Sigs...>, detail::tl_subset_of<detail::type_list<Sigs...>,
detail::type_list<OtherSigs...>>::value>> detail::type_list<OtherSigs...>>::value>>
typed_actor_pointer(typed_actor_pointer<OtherSigs...> other) typed_actor_pointer(typed_actor_pointer<OtherSigs...> other)
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
} }
template <class... OtherSigs, template <class... OtherSigs,
class = detail::enable_if_t< // class = std::enable_if_t< //
detail::tl_subset_of<detail::type_list<Sigs...>, detail::tl_subset_of<detail::type_list<Sigs...>,
detail::type_list<OtherSigs...>>::value>> detail::type_list<OtherSigs...>>::value>>
typed_actor_pointer& operator=(typed_actor_pointer<OtherSigs...> other) { typed_actor_pointer& operator=(typed_actor_pointer<OtherSigs...> other) {
......
...@@ -165,7 +165,7 @@ public: ...@@ -165,7 +165,7 @@ public:
return *this; return *this;
} }
template <class T, class E = caf::detail::enable_if_t<!std::is_pointer_v<T>>> template <class T, class E = std::enable_if_t<!std::is_pointer_v<T>>>
caf_handle& operator=(const T& x) { caf_handle& operator=(const T& x) {
set(x); set(x);
return *this; return *this;
......
...@@ -119,7 +119,7 @@ public: ...@@ -119,7 +119,7 @@ public:
template <class Iterator> template <class Iterator>
void exec_all_fixtures(Iterator first, Iterator last) { void exec_all_fixtures(Iterator first, Iterator last) {
using fixture_ptr = caf::detail::decay_t<decltype(*first)>; using fixture_ptr = std::decay_t<decltype(*first)>;
auto advance = [](fixture_ptr x) { auto advance = [](fixture_ptr x) {
return x->sched.try_run_once() || x->mpx.read_data() return x->sched.try_run_once() || x->mpx.read_data()
|| x->mpx.try_exec_runnable() || x->mpx.try_accept_connection(); || x->mpx.try_exec_runnable() || x->mpx.try_accept_connection();
......
...@@ -68,7 +68,7 @@ struct equality_operator { ...@@ -68,7 +68,7 @@ struct equality_operator {
template < template <
class T, class U, class T, class U,
detail::enable_if_t< std::enable_if_t<
((std::is_floating_point_v<T> && std::is_convertible_v<U, double>) ((std::is_floating_point_v<T> && std::is_convertible_v<U, double>)
|| (std::is_floating_point_v<U> && std::is_convertible_v<T, double>) ) || (std::is_floating_point_v<U> && std::is_convertible_v<T, double>) )
&& detail::is_comparable_v<T, U>, && detail::is_comparable_v<T, U>,
...@@ -84,7 +84,7 @@ struct equality_operator { ...@@ -84,7 +84,7 @@ struct equality_operator {
template < template <
class T, class U, class T, class U,
detail::enable_if_t< std::enable_if_t<
!((std::is_floating_point_v<T> && std::is_convertible_v<U, double>) !((std::is_floating_point_v<T> && std::is_convertible_v<U, double>)
|| (std::is_floating_point_v<U> && std::is_convertible_v<T, double>) ) || (std::is_floating_point_v<U> && std::is_convertible_v<T, double>) )
&& detail::is_comparable_v<T, U>, && detail::is_comparable_v<T, U>,
......
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