Skip to content

Commit

Permalink
Fix C++20 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven WdV committed Jan 25, 2024
1 parent 9075876 commit 2508fab
Showing 1 changed file with 72 additions and 78 deletions.
150 changes: 72 additions & 78 deletions Rx/v2/src/rxcpp/rx-util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#define RXCPP_MAKE_IDENTIFIER(Prefix) RXCPP_CONCAT_EVALUATE(Prefix, __LINE__)

#define RXCPP_DECLVAL(...) static_cast<__VA_ARGS__ (*)() noexcept>(nullptr)()

// Provide replacements for try/catch keywords, using which is a compilation error
// when exceptions are disabled with -fno-exceptions.
#if RXCPP_USE_EXCEPTIONS
Expand All @@ -46,18 +48,13 @@ namespace util {

template<class T> using value_type_t = typename std::decay<T>::type::value_type;
template<class T> using decay_t = typename std::decay<T>::type;
#ifdef __cpp_lib_is_invocable
template <class> struct result_of;

template <class F, class... TN>
struct result_of<F(TN...)>
{
using type = std::invoke_result_t<F, TN...>;
template <typename Fn, typename... ArgTypes>
struct callable_result {
using type = decltype(RXCPP_DECLVAL(Fn&&)(RXCPP_DECLVAL(ArgTypes&&)...));
};
#else
template<class... TN> using result_of = std::result_of<TN...>;
#endif
template<class... TN> using result_of_t = typename result_of<TN...>::type;
template <typename Fn, typename... ArgTypes>
using callable_result_t = typename callable_result<Fn, ArgTypes...>::type;

template<class T, std::size_t size>
std::vector<T> to_vector(const T (&arr) [size]) {
Expand All @@ -70,7 +67,7 @@ std::vector<T> to_vector(std::initializer_list<T> il) {
}

template<class T0, class... TN>
typename std::enable_if<!std::is_array<T0>::value && std::is_pod<T0>::value, std::vector<T0>>::type to_vector(T0 t0, TN... tn) {
typename std::enable_if<!std::is_array<T0>::value && std::is_trivial<T0>::value && std::is_standard_layout<T0>::value, std::vector<T0>>::type to_vector(T0 t0, TN... tn) {
return to_vector({t0, tn...});
}

Expand All @@ -93,13 +90,13 @@ struct values_from;
template<class T, T Step, T Cursor, T... ValueN>
struct values_from<T, 0, Step, Cursor, ValueN...>
{
typedef values<T, ValueN...> type;
using type = values<T, ValueN...>;
};

template<class T, std::size_t Remaining, T Step, T Cursor, T... ValueN>
struct values_from
{
typedef typename values_from<T, Remaining - 1, Step, Cursor + Step, ValueN..., Cursor>::type type;
using type = typename values_from<T, Remaining - 1, Step, Cursor + Step, ValueN..., Cursor>::type;
};

template<bool... BN>
Expand Down Expand Up @@ -138,30 +135,30 @@ using enable_if_all_true_type_t = typename std::enable_if<all_true_type<BN...>::

struct all_values_true {
template<class... ValueN>
bool operator()(ValueN... vn) const;
bool operator()(const ValueN&... vn) const;

template<class Value0>
bool operator()(Value0 v0) const {
bool operator()(const Value0& v0) const {
return v0;
}

template<class Value0, class... ValueN>
bool operator()(Value0 v0, ValueN... vn) const {
bool operator()(const Value0& v0, const ValueN&... vn) const {
return v0 && all_values_true()(vn...);
}
};

struct any_value_true {
template<class... ValueN>
bool operator()(ValueN... vn) const;
bool operator()(const ValueN&... vn) const;

template<class Value0>
bool operator()(Value0 v0) const {
bool operator()(const Value0& v0) const {
return v0;
}

template<class Value0, class... ValueN>
bool operator()(Value0 v0, ValueN... vn) const {
bool operator()(const Value0& v0, const ValueN&... vn) const {
return v0 || any_value_true()(vn...);
}
};
Expand All @@ -177,11 +174,11 @@ struct types {};
struct types_checked {};

namespace detail {
template<class... TN> struct types_checked_from {typedef types_checked type;};
template<class... TN> struct types_checked_from { using type = types_checked; };
}

template<class... TN>
struct types_checked_from {typedef typename detail::types_checked_from<TN...>::type type;};
struct types_checked_from { using type = typename detail::types_checked_from<TN...>::type; };

template<class... TN>
using types_checked_t = typename types_checked_from<TN...>::type;
Expand All @@ -199,17 +196,17 @@ using value_types_t = typename expand_value_types<types<TN...>>::type;


template<class T, class C = types_checked>
struct value_type_from : public std::false_type {typedef types_checked type;};
struct value_type_from : public std::false_type { using type = types_checked; };

template<class T>
struct value_type_from<T, typename types_checked_from<value_type_t<T>>::type>
: public std::true_type {typedef value_type_t<T> type;};
: public std::true_type { using type = value_type_t<T>; };

namespace detail {
template<class F, class... ParamN, int... IndexN>
auto apply(std::tuple<ParamN...> p, values<int, IndexN...>, F&& f)
-> decltype(f(std::forward<ParamN>(std::get<IndexN>(p))...)) {
return f(std::forward<ParamN>(std::get<IndexN>(p))...);
template<class F, class Tuple, int... IndexN>
auto apply(Tuple&& p, values<int, IndexN...>, F&& f)
-> decltype(f(std::get<IndexN>(std::forward<Tuple>(p))...)) {
return f(std::get<IndexN>(std::forward<Tuple>(p))...);
}

template<class F_inner, class F_outer, class... ParamN, int... IndexN>
Expand All @@ -226,11 +223,17 @@ auto apply_to_each(std::tuple<ParamN...>& p, values<int, IndexN...>, const F_inn

}
template<class F, class... ParamN>
auto apply(std::tuple<ParamN...> p, F&& f)
auto apply(std::tuple<ParamN...>&& p, F&& f)
-> decltype(detail::apply(std::move(p), typename values_from<int, sizeof...(ParamN)>::type(), std::forward<F>(f))) {
return detail::apply(std::move(p), typename values_from<int, sizeof...(ParamN)>::type(), std::forward<F>(f));
}

template<class F, class... ParamN>
auto apply(const std::tuple<ParamN...>& p, F&& f)
-> decltype(detail::apply(p, typename values_from<int, sizeof...(ParamN)>::type(), std::forward<F>(f))) {
return detail::apply(p, typename values_from<int, sizeof...(ParamN)>::type(), std::forward<F>(f));
}

template<class F_inner, class F_outer, class... ParamN>
auto apply_to_each(std::tuple<ParamN...>& p, F_inner& f_inner, F_outer& f_outer)
-> decltype(detail::apply_to_each(p, typename values_from<int, sizeof...(ParamN)>::type(), f_inner, f_outer)) {
Expand Down Expand Up @@ -304,14 +307,9 @@ template<int Index>
struct take_at
{
template<class... ParamN>
auto operator()(ParamN... pn)
-> typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
return std::get<Index>(std::make_tuple(std::move(pn)...));
}
template<class... ParamN>
auto operator()(ParamN... pn) const
auto operator()(const ParamN&... pn) const
-> typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
return std::get<Index>(std::make_tuple(std::move(pn)...));
return std::get<Index>(std::tie(pn...));
}
};

Expand All @@ -332,13 +330,13 @@ struct defer_trait
template<bool R>
struct tag_valid {static const bool valid = true; static const bool value = R;};
struct tag_not_valid {static const bool valid = false; static const bool value = false;};
typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
using resolved_type = Deferred<typename resolve_type<AN>::type...>;
template<class... CN>
static auto check(int) -> tag_valid<resolved_type::value>;
template<class... CN>
static tag_not_valid check(...);

typedef decltype(check<AN...>(0)) tag_type;
using tag_type = decltype(check<AN...>(0));
static const bool valid = tag_type::valid;
static const bool value = tag_type::value;
static const bool not_value = valid && !value;
Expand All @@ -348,72 +346,72 @@ template <template<class... TN> class Deferred, class... AN>
struct defer_type
{
template<class R>
struct tag_valid {typedef R type; static const bool value = true;};
struct tag_not_valid {typedef void type; static const bool value = false;};
typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
struct tag_valid { using type = R; static const bool value = true;};
struct tag_not_valid { using type = void; static const bool value = false;};
using resolved_type = Deferred<typename resolve_type<AN>::type...>;
template<class... CN>
static auto check(int) -> tag_valid<resolved_type>;
template<class... CN>
static tag_not_valid check(...);

typedef decltype(check<AN...>(0)) tag_type;
typedef typename tag_type::type type;
using tag_type = decltype(check<AN...>(0));
using type = typename tag_type::type;
static const bool value = tag_type::value;
};

template <template<class... TN> class Deferred, class... AN>
struct defer_value_type
{
template<class R>
struct tag_valid {typedef R type; static const bool value = true;};
struct tag_not_valid {typedef void type; static const bool value = false;};
typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
struct tag_valid { using type = R; static const bool value = true;};
struct tag_not_valid { using type = void; static const bool value = false;};
using resolved_type = Deferred<typename resolve_type<AN>::type...>;
template<class... CN>
static auto check(int) -> tag_valid<value_type_t<resolved_type>>;
template<class... CN>
static tag_not_valid check(...);

typedef decltype(check<AN...>(0)) tag_type;
typedef typename tag_type::type type;
using tag_type = decltype(check<AN...>(0));
using type = typename tag_type::type;
static const bool value = tag_type::value;
};

template <template<class... TN> class Deferred, class... AN>
struct defer_seed_type
{
template<class R>
struct tag_valid {typedef R type; static const bool value = true;};
struct tag_not_valid {typedef void type; static const bool value = false;};
typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
struct tag_valid { using type = R; static const bool value = true;};
struct tag_not_valid { using type = void; static const bool value = false;};
using resolved_type = Deferred<typename resolve_type<AN>::type...>;
template<class... CN>
static auto check(int) -> tag_valid<typename resolved_type::seed_type>;
template<class... CN>
static tag_not_valid check(...);

typedef decltype(check<AN...>(0)) tag_type;
typedef typename tag_type::type type;
using tag_type = decltype(check<AN...>(0));
using type = typename tag_type::type;
static const bool value = tag_type::value;
};

template <class D>
struct resolve_type
{
typedef D type;
using type = D;
};
template <template<class... TN> class Deferred, class... AN>
struct resolve_type<defer_type<Deferred, AN...>>
{
typedef typename defer_type<Deferred, AN...>::type type;
using type = typename defer_type<Deferred, AN...>::type;
};
template <template<class... TN> class Deferred, class... AN>
struct resolve_type<defer_value_type<Deferred, AN...>>
{
typedef typename defer_value_type<Deferred, AN...>::type type;
using type = typename defer_value_type<Deferred, AN...>::type;
};
template <template<class... TN> class Deferred, class... AN>
struct resolve_type<defer_seed_type<Deferred, AN...>>
{
typedef typename defer_seed_type<Deferred, AN...>::type type;
using type = typename defer_seed_type<Deferred, AN...>::type;
};

struct plus
Expand Down Expand Up @@ -579,13 +577,20 @@ class maybe
{
}

maybe(T value)
maybe(const T& value)
: is_set(false)
{
new (reinterpret_cast<T*>(&storage)) T(value);
is_set = true;
}

maybe(T&& value)
: is_set(false)
{
new (reinterpret_cast<T*>(&storage)) T(std::move(value));
is_set = true;
}

maybe(const maybe& other)
: is_set(false)
{
Expand All @@ -609,9 +614,9 @@ class maybe
reset();
}

typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
using value_type = T;
using iterator = T *;
using const_iterator = const T *;

bool empty() const {
return !is_set;
Expand Down Expand Up @@ -699,12 +704,7 @@ namespace detail {
struct surely
{
template<class... T>
auto operator()(T... t)
-> decltype(std::make_tuple(t.get()...)) {
return std::make_tuple(t.get()...);
}
template<class... T>
auto operator()(T... t) const
auto operator()(const T&... t) const
-> decltype(std::make_tuple(t.get()...)) {
return std::make_tuple(t.get()...);
}
Expand Down Expand Up @@ -831,7 +831,7 @@ struct is_duration : detail::is_duration<Decayed> {};
// C++17 negation
namespace detail {
template<class T>
struct not_value : std::conditional<T::value, std::false_type, std::true_type>::type {
struct not_value : std::conditional_t<T::value, std::false_type, std::true_type> {
};
}

Expand Down Expand Up @@ -996,22 +996,16 @@ struct filtered_hash<T, typename std::enable_if<rxu::is_string<T>::value>::type>
};
template <class T>
struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::duration<typename T::rep, typename T::period>>::value>::type> {
using argument_type = T;
using result_type = std::size_t;

result_type operator()(argument_type const & dur) const
std::size_t operator()(T const & dur) const
{
return std::hash<typename argument_type::rep>{}(dur.count());
return std::hash<typename T::rep>{}(dur.count());
}
};
template <class T>
struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::time_point<typename T::clock, typename T::duration>>::value>::type> {
using argument_type = T;
using result_type = std::size_t;

result_type operator()(argument_type const & tp) const
std::size_t operator()(T const & tp) const
{
return std::hash<typename argument_type::rep>{}(tp.time_since_epoch().count());
return std::hash<typename T::rep>{}(tp.time_since_epoch().count());
}
};

Expand All @@ -1024,7 +1018,7 @@ struct is_hashable<T,
typename rxu::types_checked_from<
typename filtered_hash<T>::result_type,
typename filtered_hash<T>::argument_type,
typename rxu::result_of<filtered_hash<T>(T)>::type>::type>
typename rxu::callable_result<filtered_hash<T>, T>::type>::type>
: std::true_type {};

}
Expand Down

0 comments on commit 2508fab

Please sign in to comment.