summaryrefslogtreecommitdiff
path: root/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp')
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp108
1 files changed, 91 insertions, 17 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp b/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp
index cf51109..b9bab52 100644
--- a/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp
@@ -2,6 +2,21 @@
#pragma once
+/*! \file rx-switch_if_empty.hpp
+
+ \brief If the source Observable terminates without emitting any items, emits items from a backup Observable.
+
+ \tparam BackupSource the type of the backup observable.
+
+ \param t a backup observable that is used if the source observable is empty.
+
+ \return Observable that emits items from a backup observable if the source observable is empty.
+
+ \sample
+ \snippet switch_if_empty.cpp switch_if_empty sample
+ \snippet output.txt switch_if_empty sample
+*/
+
#if !defined(RXCPP_OPERATORS_RX_SWITCH_IF_EMPTY_HPP)
#define RXCPP_OPERATORS_RX_SWITCH_IF_EMPTY_HPP
@@ -13,6 +28,16 @@ namespace operators {
namespace detail {
+template<class... AN>
+struct switch_if_empty_invalid_arguments {};
+
+template<class... AN>
+struct switch_if_empty_invalid : public rxo::operator_base<switch_if_empty_invalid_arguments<AN...>> {
+ using type = observable<switch_if_empty_invalid_arguments<AN...>, switch_if_empty_invalid<AN...>>;
+};
+template<class... AN>
+using switch_if_empty_invalid_t = typename switch_if_empty_invalid<AN...>::type;
+
template<class T, class BackupSource>
struct switch_if_empty
{
@@ -75,30 +100,79 @@ struct switch_if_empty
}
};
-template<class BackupSource>
-class switch_if_empty_factory
-{
- typedef rxu::decay_t<BackupSource> backup_source_type;
- backup_source_type backup;
-public:
- switch_if_empty_factory(backup_source_type b) : backup(std::move(b)) {}
- template<class Observable>
- auto operator()(Observable&& source)
- -> decltype(source.template lift<rxu::value_type_t<rxu::decay_t<Observable>>>(switch_if_empty<rxu::value_type_t<rxu::decay_t<Observable>>, backup_source_type>(backup))) {
- return source.template lift<rxu::value_type_t<rxu::decay_t<Observable>>>(switch_if_empty<rxu::value_type_t<rxu::decay_t<Observable>>, backup_source_type>(backup));
- }
-};
+}
+/*! @copydoc rx-switch_if_empty.hpp
+*/
+template<class... AN>
+auto switch_if_empty(AN&&... an)
+ -> operator_factory<switch_if_empty_tag, AN...> {
+ return operator_factory<switch_if_empty_tag, AN...>(std::make_tuple(std::forward<AN>(an)...));
}
-template<class BackupSource>
-auto switch_if_empty(BackupSource&& b)
- -> detail::switch_if_empty_factory<BackupSource> {
- return detail::switch_if_empty_factory<BackupSource>(std::forward<BackupSource>(b));
+/*! \brief If the source Observable terminates without emitting any items, emits a default item and completes.
+
+ \tparam Value the type of the value to emit.
+
+ \param v the default value to emit.
+
+ \return Observable that emits the specified default item if the source observable is empty.
+
+ \sample
+ \snippet default_if_empty.cpp default_if_empty sample
+ \snippet output.txt default_if_empty sample
+*/
+template<class... AN>
+auto default_if_empty(AN&&... an)
+ -> operator_factory<default_if_empty_tag, AN...> {
+ return operator_factory<default_if_empty_tag, AN...>(std::make_tuple(std::forward<AN>(an)...));
}
}
+template<>
+struct member_overload<switch_if_empty_tag>
+{
+ template<class Observable, class BackupSource,
+ class Enabled = rxu::enable_if_all_true_type_t<
+ all_observables<Observable, BackupSource>>,
+ class SourceValue = rxu::value_type_t<Observable>,
+ class SwitchIfEmpty = rxo::detail::switch_if_empty<SourceValue, rxu::decay_t<BackupSource>>>
+ static auto member(Observable&& o, BackupSource&& b)
+ -> decltype(o.template lift<SourceValue>(SwitchIfEmpty(std::forward<BackupSource>(b)))) {
+ return o.template lift<SourceValue>(SwitchIfEmpty(std::forward<BackupSource>(b)));
+ }
+
+ template<class... AN>
+ static operators::detail::switch_if_empty_invalid_t<AN...> member(AN...) {
+ std::terminate();
+ return {};
+ static_assert(sizeof...(AN) == 10000, "switch_if_empty takes (BackupSource)");
+ }
+};
+
+template<>
+struct member_overload<default_if_empty_tag>
+{
+ template<class Observable, class Value,
+ class Enabled = rxu::enable_if_all_true_type_t<
+ is_observable<Observable>>,
+ class SourceValue = rxu::value_type_t<Observable>,
+ class BackupSource = decltype(rxs::from(std::declval<SourceValue>())),
+ class DefaultIfEmpty = rxo::detail::switch_if_empty<SourceValue, BackupSource>>
+ static auto member(Observable&& o, Value v)
+ -> decltype(o.template lift<SourceValue>(DefaultIfEmpty(rxs::from(std::move(v))))) {
+ return o.template lift<SourceValue>(DefaultIfEmpty(rxs::from(std::move(v))));
+ }
+
+ template<class... AN>
+ static operators::detail::switch_if_empty_invalid_t<AN...> member(AN...) {
+ std::terminate();
+ return {};
+ static_assert(sizeof...(AN) == 10000, "default_if_empty takes (Value)");
+ }
+};
+
}
#endif