diff options
author | Kirk Shoop <kirk.shoop@microsoft.com> | 2016-03-09 13:10:16 -0800 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2016-03-09 13:12:22 -0800 |
commit | ed0a48f997bf6cbed155643fdb6c746677635067 (patch) | |
tree | 1104bd96be84772d570ad87107081e9a078c11e8 /Rx | |
parent | 3092af8c41d5fb5f8ad9f441c9412bd910045961 (diff) | |
download | RxCpp-ed0a48f997bf6cbed155643fdb6c746677635067.tar.gz |
support hash of enum using underlying_type by default.
can be forced to use hash with the actual enum type
#define RXCPP_FORCE_HASH_ENUM 1
Diffstat (limited to 'Rx')
-rw-r--r-- | Rx/v2/src/rxcpp/rx-includes.hpp | 46 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-util.hpp | 7 | ||||
-rw-r--r-- | Rx/v2/test/operators/distinct.cpp | 50 |
3 files changed, 94 insertions, 9 deletions
diff --git a/Rx/v2/src/rxcpp/rx-includes.hpp b/Rx/v2/src/rxcpp/rx-includes.hpp index cc473f6..51a96eb 100644 --- a/Rx/v2/src/rxcpp/rx-includes.hpp +++ b/Rx/v2/src/rxcpp/rx-includes.hpp @@ -55,12 +55,31 @@ #endif +// +// control std::hash<> of enum +// force with RXCPP_FORCE_HASH_ENUM & RXCPP_FORCE_HASH_ENUM_UNDERLYING +// in time use ifdef to detect library support for std::hash<> of enum +// +#define RXCPP_HASH_ENUM 0 +#define RXCPP_HASH_ENUM_UNDERLYING 1 + #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) #define RXCPP_USE_WINRT 0 #else #define RXCPP_USE_WINRT 1 #endif +#if defined(__APPLE__) && defined(__MACH__) +#include <TargetConditionals.h> +#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) +#define RXCPP_ON_IOS +#endif +#endif + +#if defined(__ANDROID__) +#define RXCPP_ON_ANDROID +#endif + #if defined(RXCPP_FORCE_USE_VARIADIC_TEMPLATES) #undef RXCPP_USE_VARIADIC_TEMPLATES #define RXCPP_USE_VARIADIC_TEMPLATES RXCPP_FORCE_USE_VARIADIC_TEMPLATES @@ -81,20 +100,29 @@ #define RXCPP_USE_WINRT RXCPP_FORCE_USE_WINRT #endif -#if defined(_MSC_VER) && !RXCPP_USE_VARIADIC_TEMPLATES -// resolve args needs enough to store all the possible resolved args -#define _VARIADIC_MAX 10 +#if defined(RXCPP_FORCE_HASH_ENUM) +#undef RXCPP_HASH_ENUM +#define RXCPP_HASH_ENUM RXCPP_FORCE_HASH_ENUM #endif -#if defined(__APPLE__) && defined(__MACH__) -#include <TargetConditionals.h> -#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) -#define RXCPP_ON_IOS +#if defined(RXCPP_FORCE_HASH_ENUM_UNDERLYING) +#undef RXCPP_HASH_ENUM_UNDERLYING +#define RXCPP_HASH_ENUM_UNDERLYING RXCPP_FORCE_HASH_ENUM_UNDERLYING #endif + +#if defined(RXCPP_FORCE_ON_IOS) +#undef RXCPP_ON_IOS +#define RXCPP_ON_IOS RXCPP_FORCE_ON_IOS #endif -#if defined(__ANDROID__) -#define RXCPP_ON_ANDROID +#if defined(RXCPP_FORCE_ON_ANDROID) +#undef RXCPP_ON_ANDROID +#define RXCPP_ON_ANDROID RXCPP_FORCE_ON_ANDROID +#endif + +#if defined(_MSC_VER) && !RXCPP_USE_VARIADIC_TEMPLATES +// resolve args needs enough to store all the possible resolved args +#define _VARIADIC_MAX 10 #endif #pragma push_macro("min") diff --git a/Rx/v2/src/rxcpp/rx-util.hpp b/Rx/v2/src/rxcpp/rx-util.hpp index d25b76f..a4fb758 100644 --- a/Rx/v2/src/rxcpp/rx-util.hpp +++ b/Rx/v2/src/rxcpp/rx-util.hpp @@ -705,9 +705,16 @@ namespace rxu=util; template <class T, typename = void> struct filtered_hash; +#if RXCPP_HASH_ENUM template <class T> struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<T> { }; +#elif RXCPP_HASH_ENUM_UNDERLYING +template <class T> +struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<typename std::underlying_type<T>::type> { +}; +#endif + template <class T> struct filtered_hash<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::hash<T> { }; diff --git a/Rx/v2/test/operators/distinct.cpp b/Rx/v2/test/operators/distinct.cpp index 77c69cd..84ce6ea 100644 --- a/Rx/v2/test/operators/distinct.cpp +++ b/Rx/v2/test/operators/distinct.cpp @@ -338,4 +338,54 @@ SCENARIO("distinct - strings", "[distinct][operators]"){ } } +} + +SCENARIO("distinct - enum", "[distinct][operators]"){ + enum Value { + A, + B, + C + }; + GIVEN("a source"){ + auto sc = rxsc::make_test(); + auto w = sc.create_worker(); + const rxsc::test::messages<Value> on; + + auto xs = sc.make_hot_observable({ + on.next(150, Value::A), + on.next(210, Value::A), + on.next(220, Value::B), + on.next(230, Value::B), + on.next(240, Value::B), + on.completed(250) + }); + + WHEN("distinct values are taken"){ + + auto res = w.start( + [xs]() { + return xs.distinct(); + } + ); + + THEN("the output only contains distinct items sent while subscribed"){ + auto required = rxu::to_vector({ + on.next(210, Value::A), + on.next(220, Value::B), + on.completed(250) + }); + auto actual = res.get_observer().messages(); + REQUIRE(required == actual); + } + + THEN("there was 1 subscription/unsubscription to the source"){ + auto required = rxu::to_vector({ + on.subscribe(200, 250) + }); + auto actual = xs.subscriptions(); + REQUIRE(required == actual); + } + + } + } }
\ No newline at end of file |