ReactivePlusPlus
One more implementation of ReactiveX approach in C++ with care about performance and templates in mind
 
Loading...
Searching...
No Matches
combine_latest.hpp
1// ReactivePlusPlus library
2//
3// Copyright Aleksey Loginov 2022 - present.
4// TC Wang 2022 - present.
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// https://www.boost.org/LICENSE_1_0.txt)
8//
9// Project home: https://github.com/victimsnino/ReactivePlusPlus
10
11#pragma once
12
13#include <rpp/observables/constraints.hpp> // constraint::observable
14#include <rpp/observables/details/member_overload.hpp> // member_overload
15#include <rpp/utils/function_traits.hpp> // decayed_invoke_result_t
16#include <rpp/utils/functors.hpp> // pack_to_tuple
17
18#include <tuple>
19
20namespace rpp::details
21{
22struct combine_latest_tag;
23}
24
25namespace rpp::details
26{
27
28template<constraint::decayed_type Type, typename TCombiner, constraint::observable ...TOtherObservable>
29struct combine_latest_impl;
30
31template<constraint::decayed_type Type, typename SpecificObservable>
32struct member_overload<Type, SpecificObservable, combine_latest_tag>
33{
34
70 template<constraint::observable ...TOtherObservable, std::invocable<Type, utils::extract_observable_type_t<TOtherObservable>...> TCombiner>
71 auto combine_latest(TCombiner&& combiner, TOtherObservable&&...observables) const& requires is_header_included<combine_latest_tag, TOtherObservable...>
72 {
73 using DownstreamType = utils::decayed_invoke_result_t<TCombiner, Type, utils::extract_observable_type_t<TOtherObservable>...>;
74
75 return cast_this()->template lift<DownstreamType>(
76 combine_latest_impl<Type, std::decay_t<TCombiner>, std::decay_t<TOtherObservable>...>{
77 std::forward<TCombiner>(combiner),
78 std::tuple{std::forward<TOtherObservable>(observables)...}
79 });
80 }
81
82 template<constraint::observable ...TOtherObservable, std::invocable<Type, utils::extract_observable_type_t<TOtherObservable>...> TCombiner>
83 auto combine_latest(TCombiner&& combiner, TOtherObservable&&...observables) && requires is_header_included<combine_latest_tag, TOtherObservable...>
84 {
85 using DownstreamType = utils::decayed_invoke_result_t<TCombiner, Type, utils::extract_observable_type_t<TOtherObservable>...>;
86
87 return move_this().template lift<DownstreamType>(
88 combine_latest_impl<Type, std::decay_t<TCombiner>, std::decay_t<TOtherObservable>...>{
89 std::forward<TCombiner>(combiner),
90 std::tuple{std::forward<TOtherObservable>(observables)...}
91 });
92 }
93
128 template<constraint::observable ...TOtherObservable>
129 auto combine_latest(TOtherObservable&&...observables) const& requires is_header_included<combine_latest_tag, TOtherObservable...>
130 {
131 return cast_this()->combine_latest(utils::pack_to_tuple{}, std::forward<TOtherObservable>(observables)...);
132 }
133
134 template<constraint::observable ...TOtherObservable>
135 auto combine_latest(TOtherObservable&&...observables) && requires is_header_included<combine_latest_tag, TOtherObservable...>
136 {
137 return move_this().combine_latest(utils::pack_to_tuple{}, std::forward<TOtherObservable>(observables)...);
138 }
139
140private:
141 const SpecificObservable* cast_this() const
142 {
143 return static_cast<const SpecificObservable*>(this);
144 }
145
146 SpecificObservable&& move_this()
147 {
148 return std::move(*static_cast<SpecificObservable*>(this));
149 }
150};
151
152} // namespace rpp::details
Definition: constraints.hpp:19
"combine_latest" operator (an OperatorFn used by "lift").
Definition: combine_latest.hpp:84
Definition: member_overload.hpp:19