From 201dd99b6494564c9e8990d0a5c32b23431128d4 Mon Sep 17 00:00:00 2001 From: Kirk Shoop Date: Mon, 10 Apr 2017 16:03:58 -0700 Subject: Kirkshoop/filterimprovement (#371) * filter: mutable predicate and value forwarding * add as_const to protect predicate from stealing --- Rx/v2/src/rxcpp/operators/rx-filter.hpp | 11 ++++++---- 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 dest_type; typedef observer 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 + 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(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::value && std::is_pod::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 +/*constexpr*/ T const &as_const(T & t) /*noexcept*/ +{ + return t; +} +template +void as_const(T const &&) = delete; + template struct values {}; @@ -157,7 +167,7 @@ using types_checked_t = typename types_checked_from::type; template struct expand_value_types { struct type; }; template -struct expand_value_types, types_checked_t::type::value_type...>> +struct expand_value_types, types_checked_t::type::value_type...>> { using type = types::type::value_type...>; }; @@ -517,7 +527,7 @@ inline std::string what(std::exception_ptr ep) { } return std::string(); } - + namespace detail { template @@ -754,7 +764,7 @@ struct is_string : std::false_type { }; template -struct is_string to work. // // NOTE: this should eventually be removed! // -template +template struct filtered_hash; #if RXCPP_HASH_ENUM -template +template struct filtered_hash::value>::type> : std::hash { }; #elif RXCPP_HASH_ENUM_UNDERLYING -template +template struct filtered_hash::value>::type> : std::hash::type> { }; #endif -template +template struct filtered_hash::value>::type> : std::hash { }; -template +template struct filtered_hash::value>::type> : std::hash { }; -template +template struct filtered_hash::value>::type> : std::hash { }; template @@ -850,10 +860,10 @@ struct is_hashable : std::false_type {}; template -struct is_hashable::result_type, - typename filtered_hash::argument_type, + typename filtered_hash::result_type, + typename filtered_hash::argument_type, typename std::result_of(T)>::type>::type> : std::true_type {}; -- cgit v1.2.3