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