diff --git a/src/rpp/rpp/observables/dynamic_observable.hpp b/src/rpp/rpp/observables/dynamic_observable.hpp index 614c39814..5e0b3f83f 100644 --- a/src/rpp/rpp/observables/dynamic_observable.hpp +++ b/src/rpp/rpp/observables/dynamic_observable.hpp @@ -10,7 +10,7 @@ #pragma once #include - +#include #include #include @@ -87,7 +87,16 @@ namespace rpp */ template class dynamic_observable : public observable> { + using base = observable>; public: - using observable>::observable; + using base::base; + + dynamic_observable(base&& b) + : base{std::move(b)} + {} + + dynamic_observable(const base& b) + : base{b} + {} }; } \ No newline at end of file diff --git a/src/rpp/rpp/observables/fwd.hpp b/src/rpp/rpp/observables/fwd.hpp index be2c56ba5..085fd0196 100644 --- a/src/rpp/rpp/observables/fwd.hpp +++ b/src/rpp/rpp/observables/fwd.hpp @@ -19,7 +19,7 @@ namespace rpp::constraint { template -concept observable_strategy = requires(const S& strategy, details::fake_observer&& observer) +concept observable_strategy = requires(const S& strategy, rpp::details::observers::fake_observer&& observer) { {strategy.subscribe(std::move(observer))} -> std::same_as; typename S::value_type; @@ -33,6 +33,14 @@ class dynamic_strategy; template Strategy> class blocking_strategy; + +template +struct fake_strategy +{ + using value_type = Type; + + static void subscribe(const auto&) {} +}; } namespace rpp @@ -85,23 +93,23 @@ concept operator_observable_transform = requires(const Op& op, TObs obs) template concept operator_base = requires(const Op& op) { typename std::decay_t::template result_value; - requires details::observables::constraint::disposable_strategy, typename observable_chain_strategy>::expected_disposable_strategy>>; + requires details::observables::constraint::disposable_strategy, typename observable_chain_strategy>::expected_disposable_strategy>>; }; template -concept operator_subscribe = operator_base && requires(const Op& op, dynamic_observer::template result_value>&& observer, const observable_chain_strategy>& chain) +concept operator_subscribe = operator_base && requires(const Op& op, rpp::details::observers::fake_observer::template result_value>&& observer, const observable_chain_strategy>& chain) { {op.subscribe(std::move(observer), chain)}; }; template -concept operator_lift = operator_base && requires(const Op& op, dynamic_observer::template result_value>&& observer) +concept operator_lift = operator_base && requires(const Op& op, rpp::details::observers::fake_observer::template result_value>&& observer) { {op.template lift(std::move(observer))} -> rpp::constraint::observer_of_type; }; template -concept operator_lift_with_disposable_strategy = operator_base && requires(const Op& op, dynamic_observer::template result_value>&& observer) +concept operator_lift_with_disposable_strategy = operator_base && requires(const Op& op, rpp::details::observers::fake_observer::template result_value>&& observer) { {op.template lift_with_disposable_strategy(std::move(observer))} -> rpp::constraint::observer_of_type; }; diff --git a/src/rpp/rpp/observables/observable.hpp b/src/rpp/rpp/observables/observable.hpp index 4024f0426..085de06d3 100644 --- a/src/rpp/rpp/observables/observable.hpp +++ b/src/rpp/rpp/observables/observable.hpp @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include #include diff --git a/src/rpp/rpp/observers/dynamic_observer.hpp b/src/rpp/rpp/observers/dynamic_observer.hpp index b72190547..646a57ec3 100644 --- a/src/rpp/rpp/observers/dynamic_observer.hpp +++ b/src/rpp/rpp/observers/dynamic_observer.hpp @@ -9,8 +9,9 @@ #pragma once -#include #include +#include +#include #include #include @@ -94,3 +95,31 @@ class dynamic_strategy final const vtable* m_vtable; }; } + + +namespace rpp +{ +/** + * @brief Type-erased version of the `rpp::observer`. Any observer can be converted to dynamic_observer via `rpp::observer::as_dynamic` member function. + * @details To provide type-erasure it uses `std::shared_ptr`. As a result it has worse performance, but it is **ONLY** way to copy observer. + * + * @tparam Type of value this observer can handle + * + * @ingroup observers + */ +template +class dynamic_observer final : public observer> +{ + using base = observer>; +public: + using base::base; + + dynamic_observer(base&& b) + : base{std::move(b)} + {} + + dynamic_observer(const base& b) + : base{b} + {} +}; +} \ No newline at end of file diff --git a/src/rpp/rpp/observers/fwd.hpp b/src/rpp/rpp/observers/fwd.hpp index 020875566..80e6701b9 100644 --- a/src/rpp/rpp/observers/fwd.hpp +++ b/src/rpp/rpp/observers/fwd.hpp @@ -90,16 +90,8 @@ namespace rpp template Strategy> class observer; -/** - * @brief Type-erased version of the `rpp::observer`. Any observer can be converted to dynamic_observer via `rpp::observer::as_dynamic` member function. - * @details To provide type-erasure it uses `std::shared_ptr`. As a result it has worse performance, but it is **ONLY** way to copy observer. - * - * @tparam Type of value this observer can handle - * - * @ingroup observers - */ template -using dynamic_observer = observer>; +class dynamic_observer; /** * @brief Observer specialized with passed callbacks. Most easiesest way to construct observer "on the fly" via lambdas and etc. @@ -209,7 +201,7 @@ auto make_lambda_observer(const rpp::composite_disposable_wrapper& d, } } // namespace rpp -namespace rpp::details +namespace rpp::details::observers { struct fake_strategy { diff --git a/src/rpp/rpp/observers/observer.hpp b/src/rpp/rpp/observers/observer.hpp index 7ab80c0a2..831abccf3 100644 --- a/src/rpp/rpp/observers/observer.hpp +++ b/src/rpp/rpp/observers/observer.hpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -225,7 +224,7 @@ class observer -class observer> final +class observer> : public details::observer_impl, details::observers::none_disposable_strategy> { public: @@ -241,12 +240,12 @@ class observer> final dynamic_observer as_dynamic() && { - return std::move(*this); + return dynamic_observer{std::move(*this)}; } const dynamic_observer& as_dynamic() & { - return *this; + return dynamic_observer{*this}; } }; diff --git a/src/rpp/rpp/sources/fwd.hpp b/src/rpp/rpp/sources/fwd.hpp index 3f91116ea..1242025ef 100644 --- a/src/rpp/rpp/sources/fwd.hpp +++ b/src/rpp/rpp/sources/fwd.hpp @@ -24,7 +24,7 @@ namespace rpp::constraint { template -concept on_subscribe = requires(const S& strategy, rpp::details::fake_observer&& observer) +concept on_subscribe = requires(const S& strategy, rpp::details::observers::fake_observer&& observer) { {strategy(std::move(observer))} -> std::same_as; }; diff --git a/src/rpp/rpp/subjects/fwd.hpp b/src/rpp/rpp/subjects/fwd.hpp index 8ecbf4c7c..7cb50c0bd 100644 --- a/src/rpp/rpp/subjects/fwd.hpp +++ b/src/rpp/rpp/subjects/fwd.hpp @@ -21,7 +21,7 @@ namespace rpp::subjects::details namespace constraint { template -concept subject_strategy = requires(Strategy t, rpp::details::fake_observer&& obs) +concept subject_strategy = requires(Strategy t, rpp::details::observers::fake_observer&& obs) { {t.get_observer()} -> rpp::constraint::observer; t.on_subscribe(std::move(obs)); diff --git a/src/tests/rpp/test_buffer.cpp b/src/tests/rpp/test_buffer.cpp index ca0cf5ed6..2ebcb243b 100644 --- a/src/tests/rpp/test_buffer.cpp +++ b/src/tests/rpp/test_buffer.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "mock_observer.hpp" #include "disposable_observable.hpp" diff --git a/src/tests/rpp/test_concat.cpp b/src/tests/rpp/test_concat.cpp index a0817fd80..8a289cfa9 100644 --- a/src/tests/rpp/test_concat.cpp +++ b/src/tests/rpp/test_concat.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/src/tests/rpp/test_flat_map.cpp b/src/tests/rpp/test_flat_map.cpp index 82bc69e7c..0fe351316 100644 --- a/src/tests/rpp/test_flat_map.cpp +++ b/src/tests/rpp/test_flat_map.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "copy_count_tracker.hpp" #include "mock_observer.hpp" diff --git a/src/tests/rpp/test_group_by.cpp b/src/tests/rpp/test_group_by.cpp index 9388ddab3..9064730e0 100644 --- a/src/tests/rpp/test_group_by.cpp +++ b/src/tests/rpp/test_group_by.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "mock_observer.hpp" #include "disposable_observable.hpp" diff --git a/src/tests/rpp/test_merge.cpp b/src/tests/rpp/test_merge.cpp index 766ae8e08..3a8fcda14 100644 --- a/src/tests/rpp/test_merge.cpp +++ b/src/tests/rpp/test_merge.cpp @@ -10,6 +10,7 @@ #include +#include #include #include #include diff --git a/src/tests/rpp/test_scheduler.cpp b/src/tests/rpp/test_scheduler.cpp index d6ead1b01..6f7906245 100644 --- a/src/tests/rpp/test_scheduler.cpp +++ b/src/tests/rpp/test_scheduler.cpp @@ -15,6 +15,8 @@ #include #include #include +#include + #include #include #include diff --git a/src/tests/rpp/test_subscribe.cpp b/src/tests/rpp/test_subscribe.cpp index 1d5d5a939..e6a141d49 100644 --- a/src/tests/rpp/test_subscribe.cpp +++ b/src/tests/rpp/test_subscribe.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include #include "mock_observer.hpp" diff --git a/src/tests/rpp/test_switch_on_next.cpp b/src/tests/rpp/test_switch_on_next.cpp index 3b937e4c2..9484e88f8 100644 --- a/src/tests/rpp/test_switch_on_next.cpp +++ b/src/tests/rpp/test_switch_on_next.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include diff --git a/src/tests/rppqt/test_main_thread_scheduler.cpp b/src/tests/rppqt/test_main_thread_scheduler.cpp index 1c81f8a3a..9096c1c9b 100644 --- a/src/tests/rppqt/test_main_thread_scheduler.cpp +++ b/src/tests/rppqt/test_main_thread_scheduler.cpp @@ -12,6 +12,7 @@ #include #include +#include #include