diff options
author | Kirk Shoop <kirk.shoop@microsoft.com> | 2016-02-02 18:16:50 -0800 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2016-02-02 18:16:50 -0800 |
commit | e11b6eb8419ca56ad31ffa2e66657c1a6eb69289 (patch) | |
tree | d5414d870cb51540dab46ec056ce51fd550f53c3 /Rx | |
parent | e834330ee38420e6cedcb8f10e37851eb3e1e2e6 (diff) | |
download | RxCpp-e11b6eb8419ca56ad31ffa2e66657c1a6eb69289.tar.gz |
use whitelist filter on std::hash<> to avoid bad static_assert in multiple std lib implementations
Diffstat (limited to 'Rx')
-rw-r--r-- | Rx/v2/src/rxcpp/operators/rx-distinct.hpp | 2 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-predef.hpp | 15 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-util.hpp | 31 |
3 files changed, 32 insertions, 16 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-distinct.hpp b/Rx/v2/src/rxcpp/operators/rx-distinct.hpp index c2994ca..784c940 100644 --- a/Rx/v2/src/rxcpp/operators/rx-distinct.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-distinct.hpp @@ -29,7 +29,7 @@ struct distinct<T, typename std::enable_if<is_hashable<T>::value>::type> typedef rxu::decay_t<Subscriber> dest_type; typedef observer<value_type, this_type> observer_type; dest_type dest; - mutable std::unordered_set<source_value_type> remembered; + mutable std::unordered_set<source_value_type, rxcpp::filtered_hash<source_value_type>> remembered; distinct_observer(dest_type d) : dest(d) diff --git a/Rx/v2/src/rxcpp/rx-predef.hpp b/Rx/v2/src/rxcpp/rx-predef.hpp index c4f27a6..6d1a394 100644 --- a/Rx/v2/src/rxcpp/rx-predef.hpp +++ b/Rx/v2/src/rxcpp/rx-predef.hpp @@ -261,21 +261,6 @@ struct identity_for } }; -template<typename, typename = void> -struct is_hashable - : std::false_type {}; - -template<typename T> -struct is_hashable<T, typename std::enable_if<!!sizeof(std::declval<std::hash<T>>()(std::declval<T>()))>::type> - : std::true_type {}; - -} - -// disable std::hash for observable<> -namespace std { - template <class T, class Source> struct hash<rxcpp::observable<T, Source>>; - template <class T, class Source> struct hash<rxcpp::connectable_observable<T, Source>>; - template <class K, class T, class Source> struct hash<rxcpp::grouped_observable<K, T, Source>>; } #endif diff --git a/Rx/v2/src/rxcpp/rx-util.hpp b/Rx/v2/src/rxcpp/rx-util.hpp index 8b87175..cbc4956 100644 --- a/Rx/v2/src/rxcpp/rx-util.hpp +++ b/Rx/v2/src/rxcpp/rx-util.hpp @@ -677,6 +677,37 @@ public: } namespace rxu=util; +// +// due to an noisy static_assert issue in more than one std lib impl, +// build a whitelist filter for the types that are allowed to be hashed +// in rxcpp. this allows is_hashable<T> to work. +// +// NOTE: this should eventually be removed! +// +template <class T, typename = void> +struct filtered_hash; +template <class T> +struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<T> { +}; +template <class T> +struct filtered_hash<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::hash<T> { +}; +template <class T> +struct filtered_hash<T, typename std::enable_if<std::is_pointer<T>::value>::type> : std::hash<T> { +}; + +template<typename, typename C = rxu::types_checked> +struct is_hashable + : std::false_type {}; + +template<typename T> +struct is_hashable<T, + typename rxu::types_checked_from< + typename filtered_hash<T>::result_type, + typename filtered_hash<T>::argument_type, + typename std::result_of<filtered_hash<T>(T)>::type>::type> + : std::true_type {}; + } #define RXCPP_UNWIND(Name, Function) \ |