summaryrefslogtreecommitdiff
path: root/Rx
diff options
context:
space:
mode:
authorKirk Shoop <kirk.shoop@microsoft.com>2016-02-02 18:16:50 -0800
committerKirk Shoop <kirk.shoop@microsoft.com>2016-02-02 18:16:50 -0800
commite11b6eb8419ca56ad31ffa2e66657c1a6eb69289 (patch)
treed5414d870cb51540dab46ec056ce51fd550f53c3 /Rx
parente834330ee38420e6cedcb8f10e37851eb3e1e2e6 (diff)
downloadRxCpp-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.hpp2
-rw-r--r--Rx/v2/src/rxcpp/rx-predef.hpp15
-rw-r--r--Rx/v2/src/rxcpp/rx-util.hpp31
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) \