ReactivePlusPlus
One more implementation of ReactiveX approach in C++ with care about performance and templates in mind
 
Loading...
Searching...
No Matches
dynamic_observable.hpp
1// ReactivePlusPlus library
2//
3// Copyright Aleksey Loginov 2022 - present.
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// https://www.boost.org/LICENSE_1_0.txt)
7//
8// Project home: https://github.com/victimsnino/ReactivePlusPlus
9//
10
11#pragma once
12
13#include <rpp/defs.hpp>
14#include <rpp/observables/specific_observable.hpp> // base
15#include <rpp/utils/operator_declaration.hpp> // for header include
16
17#include <memory>
18
19IMPLEMENTATION_FILE(dynamic_observable_tag);
20
21namespace rpp::details
22{
23template<constraint::decayed_type Type>
25{
26public:
27 template<constraint::observable_of_type<Type> TObs>
28 dynamic_observable_state(TObs&& obs)
29 : m_impl{std::make_shared<dynamic_observable_state_impl<std::decay_t<TObs>>>(std::forward<TObs>(obs))} {}
30
31 template<constraint::on_subscribe_fn<Type> TOnSub>
32 requires (!constraint::decayed_same_as<TOnSub, dynamic_observable_state<Type>>)
33 dynamic_observable_state(TOnSub&& on_sub)
34 : m_impl{ std::make_shared<dynamic_observable_state_impl<specific_observable<Type, std::decay_t<TOnSub>>>>(std::forward<TOnSub>(on_sub)) } {}
35
37 dynamic_observable_state(dynamic_observable_state&& other) noexcept = default;
38 dynamic_observable_state& operator=(const dynamic_observable_state& other) = default;
39 dynamic_observable_state& operator=(dynamic_observable_state&& other) noexcept = default;
40
41 composite_subscription operator()(const dynamic_subscriber<Type>& subscriber) const
42 {
43 return (*m_impl)(subscriber);
44 }
45private:
46 struct interface_dynamic_observable_state_impl
47 {
48 virtual ~interface_dynamic_observable_state_impl() = default;
49
50 virtual composite_subscription operator()(const dynamic_subscriber<Type>& subscriber) const = 0;
51 };
52
53 template<constraint::observable TObs>
54 class dynamic_observable_state_impl final : public interface_dynamic_observable_state_impl
55 {
56 public:
57 dynamic_observable_state_impl(TObs&& observable)
58 : m_observable{std::move(observable)} {}
59
60 dynamic_observable_state_impl(const TObs& observable)
61 : m_observable{observable} {}
62
63 composite_subscription operator()(const dynamic_subscriber<Type>& subscriber) const override
64 {
65 return m_observable.subscribe(subscriber);
66 }
67
68 private:
69 RPP_NO_UNIQUE_ADDRESS TObs m_observable{};
70 };
71
72 std::shared_ptr<interface_dynamic_observable_state_impl> m_impl{};
73};
74} // namespace rpp::details
75
76namespace rpp
77{
87template<constraint::decayed_type Type>
88class dynamic_observable : public specific_observable<Type, details::dynamic_observable_state<Type>>
89{
90public:
92 using base::base;
93
94 explicit dynamic_observable(constraint::on_subscribe_fn<Type> auto&& on_subscribe)
95 : base{std::forward<decltype(on_subscribe)>(on_subscribe)} {}
96
97 template<constraint::observable_of_type<Type> TObs>
98 requires (!std::is_same_v<std::decay_t<TObs>, dynamic_observable<Type>>)
99 dynamic_observable(TObs&& observable)
100 : base{std::forward<TObs>(observable)} {}
101};
102
103template<constraint::observable TObs>
105
106template<typename OnSub>
108} // namespace rpp
rpp::subscription_base with ability to add some dependent subscriptions as a part of this one: in cas...
Definition: composite_subscription.hpp:30
Definition: dynamic_observable.hpp:25
Type-less observable (or partially untyped) that has the notion of Type but hides the notion of on_su...
Definition: dynamic_observable.hpp:89
subscriber which uses dynamic_observer<T> to hide original callbacks
Definition: dynamic_subscriber.hpp:24
Type-full observable (or typed) that has the notion of Type and upstream observables for C++ compiler...
Definition: specific_observable.hpp:39
Definition: fwd.hpp:27