diff options
author | Kirk Shoop <kirk.shoop@microsoft.com> | 2017-04-10 16:03:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-10 16:03:58 -0700 |
commit | 201dd99b6494564c9e8990d0a5c32b23431128d4 (patch) | |
tree | c451295d260bb473041d116b46f5285f65b9c8c8 /Rx/v2/src/rxcpp | |
parent | e024142dc3b23c229e6b375fdf7c5516df7c8437 (diff) | |
download | RxCpp-201dd99b6494564c9e8990d0a5c32b23431128d4.tar.gz |
Kirkshoop/filterimprovement (#371)
* filter: mutable predicate and value forwarding
* add as_const to protect predicate from stealing
Diffstat (limited to 'Rx/v2/src/rxcpp')
-rw-r--r-- | Rx/v2/src/rxcpp/operators/rx-filter.hpp | 11 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-util.hpp | 38 |
2 files changed, 31 insertions, 18 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-filter.hpp b/Rx/v2/src/rxcpp/operators/rx-filter.hpp index ef6e133..86ce649 100644 --- a/Rx/v2/src/rxcpp/operators/rx-filter.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-filter.hpp @@ -58,22 +58,25 @@ struct filter typedef rxu::decay_t<Subscriber> dest_type; typedef observer<value_type, this_type> observer_type; dest_type dest; - test_type test; + mutable test_type test; filter_observer(dest_type d, test_type t) : dest(std::move(d)) , test(std::move(t)) { } - void on_next(source_value_type v) const { + + template <class Value> + void on_next(Value&& v) const { auto filtered = on_exception([&](){ - return !this->test(v);}, + return !this->test(rxu::as_const(v)); + }, dest); if (filtered.empty()) { return; } if (!filtered.get()) { - dest.on_next(v); + dest.on_next(std::forward<Value>(v)); } } void on_error(std::exception_ptr e) const { diff --git a/Rx/v2/src/rxcpp/rx-util.hpp b/Rx/v2/src/rxcpp/rx-util.hpp index 77e0d3f..9c6534f 100644 --- a/Rx/v2/src/rxcpp/rx-util.hpp +++ b/Rx/v2/src/rxcpp/rx-util.hpp @@ -51,6 +51,16 @@ typename std::enable_if<!std::is_array<T0>::value && std::is_pod<T0>::value, std return to_vector({t0, tn...}); } +// lifted from https://github.com/ericniebler/range-v3/blob/630fc70baa07cbfd222f329e44a3122ab64ce364/include/range/v3/range_fwd.hpp +// removed constexpr & noexcept to support older VC compilers +template<typename T> +/*constexpr*/ T const &as_const(T & t) /*noexcept*/ +{ + return t; +} +template<typename T> +void as_const(T const &&) = delete; + template<class T, T... ValueN> struct values {}; @@ -157,7 +167,7 @@ using types_checked_t = typename types_checked_from<TN...>::type; template<class Types, class =types_checked> struct expand_value_types { struct type; }; template<class... TN> -struct expand_value_types<types<TN...>, types_checked_t<typename std::decay<TN>::type::value_type...>> +struct expand_value_types<types<TN...>, types_checked_t<typename std::decay<TN>::type::value_type...>> { using type = types<typename std::decay<TN>::type::value_type...>; }; @@ -517,7 +527,7 @@ inline std::string what(std::exception_ptr ep) { } return std::string(); } - + namespace detail { template <class T> @@ -754,7 +764,7 @@ struct is_string : std::false_type { }; template <typename T> -struct is_string<T, +struct is_string<T, typename types_checked_from< typename T::value_type, typename T::traits_type, @@ -796,32 +806,32 @@ namespace rxu=util; // -// due to an noisy static_assert issue in more than one std lib impl, -// rxcpp maintains a whitelist filter for the types that are allowed +// due to an noisy static_assert issue in more than one std lib impl, +// rxcpp maintains a whitelist filter for the types that are allowed // to be hashed. this allows is_hashable<T> to work. // // NOTE: this should eventually be removed! // -template <class T, typename = void> +template <class T, typename = void> struct filtered_hash; #if RXCPP_HASH_ENUM -template <class T> +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> +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> +template <class T> struct filtered_hash<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::hash<T> { }; -template <class T> +template <class T> struct filtered_hash<T, typename std::enable_if<std::is_pointer<T>::value>::type> : std::hash<T> { }; -template <class T> +template <class T> struct filtered_hash<T, typename std::enable_if<rxu::is_string<T>::value>::type> : std::hash<T> { }; template <class T> @@ -850,10 +860,10 @@ struct is_hashable : std::false_type {}; template<typename T> -struct is_hashable<T, +struct is_hashable<T, typename rxu::types_checked_from< - typename filtered_hash<T>::result_type, - typename filtered_hash<T>::argument_type, + 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 {}; |