1 // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
2
3 #pragma once
4
5 /*! \file rx-start_with.hpp
6
7 \brief Start with the supplied values, then concatenate this observable.
8
9 \tparam Value0 ...
10 \tparam ValueN the type of sending values
11
12 \param v0 ...
13 \param vn values to send
14
15 \return Observable that emits the specified items and then emits the items emitted by the source observable.
16
17 \sample
18 \snippet start_with.cpp short start_with sample
19 \snippet output.txt short start_with sample
20
21 Another form of this operator, rxcpp::observable<void, void>::start_with, gets the source observable as a parameter:
22 \snippet start_with.cpp full start_with sample
23 \snippet output.txt full start_with sample
24 */
25
26 #if !defined(RXCPP_OPERATORS_RX_START_WITH_HPP)
27 #define RXCPP_OPERATORS_RX_START_WITH_HPP
28
29 #include "../rx-includes.hpp"
30 #include "./rx-concat.hpp"
31
32 namespace rxcpp {
33
34 namespace operators {
35
36 namespace detail {
37
38 template<class... AN>
39 struct start_with_invalid_arguments {};
40
41 template<class... AN>
42 struct start_with_invalid : public rxo::operator_base<start_with_invalid_arguments<AN...>> {
43 using type = observable<start_with_invalid_arguments<AN...>, start_with_invalid<AN...>>;
44 };
45 template<class... AN>
46 using start_with_invalid_t = typename start_with_invalid<AN...>::type;
47
48 }
49
50 /*! @copydoc rx-start_with.hpp
51 */
52 template<class... AN>
start_with(AN &&...an)53 auto start_with(AN&&... an)
54 -> operator_factory<start_with_tag, AN...> {
55 return operator_factory<start_with_tag, AN...>(std::make_tuple(std::forward<AN>(an)...));
56 }
57
58 }
59
60 template<>
61 struct member_overload<start_with_tag>
62 {
63 template<class Observable, class Value0, class... ValueN,
64 class Enabled = rxu::enable_if_all_true_type_t<
65 is_observable<Observable>>,
66 class From = decltype(rxs::from(rxu::decay_t<Value0>(std::declval<Value0>()), rxu::decay_t<ValueN>(std::declval<ValueN>())...))
67 >
memberrxcpp::member_overload68 static auto member(Observable&& o, Value0&& v0, ValueN&&... vn)
69 -> decltype(member_overload<concat_tag>::member(std::declval<From>(), std::forward<Observable>(o))) {
70 auto first = rxs::from(rxu::decay_t<Value0>(v0), rxu::decay_t<ValueN>(vn)...);
71 return member_overload<concat_tag>::member(first, std::forward<Observable>(o));
72 }
73
74 template<class... AN>
memberrxcpp::member_overload75 static operators::detail::start_with_invalid_t<AN...> member(const AN&...) {
76 std::terminate();
77 return {};
78 static_assert(sizeof...(AN) == 10000, "start_with takes (Value0, optional ValueN...)");
79 }
80 };
81
82 }
83
84 #endif
85