535 lines
15 KiB
C++
535 lines
15 KiB
C++
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#if !defined(RXCPP_RX_OPERATORS_HPP)
|
||
|
#define RXCPP_RX_OPERATORS_HPP
|
||
|
|
||
|
#include "rx-includes.hpp"
|
||
|
|
||
|
namespace rxcpp {
|
||
|
|
||
|
namespace operators {
|
||
|
|
||
|
struct tag_operator {};
|
||
|
template<class T>
|
||
|
struct operator_base
|
||
|
{
|
||
|
typedef T value_type;
|
||
|
typedef tag_operator operator_tag;
|
||
|
};
|
||
|
|
||
|
namespace detail {
|
||
|
|
||
|
template<class T, class =rxu::types_checked>
|
||
|
struct is_operator : std::false_type
|
||
|
{
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct is_operator<T, rxu::types_checked_t<typename T::operator_tag>>
|
||
|
: std::is_convertible<typename T::operator_tag*, tag_operator*>
|
||
|
{
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
template<class T, class Decayed = rxu::decay_t<T>>
|
||
|
struct is_operator : detail::is_operator<Decayed>
|
||
|
{
|
||
|
};
|
||
|
|
||
|
|
||
|
}
|
||
|
namespace rxo=operators;
|
||
|
|
||
|
template<class Tag>
|
||
|
struct member_overload
|
||
|
{
|
||
|
template<class... AN>
|
||
|
static auto member(AN&&...) ->
|
||
|
typename Tag::template include_header<std::false_type> {
|
||
|
return typename Tag::template include_header<std::false_type>();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template<class T, class... AN>
|
||
|
struct delayed_type{using value_type = T; static T value(AN**...) {return T{};}};
|
||
|
|
||
|
template<class T, class... AN>
|
||
|
using delayed_type_t = rxu::value_type_t<delayed_type<T, AN...>>;
|
||
|
|
||
|
template<class Tag, class... AN, class Overload = member_overload<rxu::decay_t<Tag>>>
|
||
|
auto observable_member(Tag, AN&&... an) ->
|
||
|
decltype(Overload::member(std::forward<AN>(an)...)) {
|
||
|
return Overload::member(std::forward<AN>(an)...);
|
||
|
}
|
||
|
|
||
|
template<class Tag, class... AN>
|
||
|
class operator_factory
|
||
|
{
|
||
|
using this_type = operator_factory<Tag, AN...>;
|
||
|
using tag_type = rxu::decay_t<Tag>;
|
||
|
using tuple_type = std::tuple<rxu::decay_t<AN>...>;
|
||
|
|
||
|
tuple_type an;
|
||
|
|
||
|
public:
|
||
|
operator_factory(tuple_type an)
|
||
|
: an(std::move(an))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
template<class... ZN>
|
||
|
auto operator()(tag_type t, ZN&&... zn) const
|
||
|
-> decltype(observable_member(t, std::forward<ZN>(zn)...)) {
|
||
|
return observable_member(t, std::forward<ZN>(zn)...);
|
||
|
}
|
||
|
|
||
|
template<class Observable>
|
||
|
auto operator()(Observable source) const
|
||
|
-> decltype(rxu::apply(std::tuple_cat(std::make_tuple(tag_type{}, source), (*(tuple_type*)nullptr)), (*(this_type*)nullptr))) {
|
||
|
return rxu::apply(std::tuple_cat(std::make_tuple(tag_type{}, source), an), *this);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
#include "operators/rx-lift.hpp"
|
||
|
#include "operators/rx-subscribe.hpp"
|
||
|
|
||
|
namespace rxcpp {
|
||
|
|
||
|
struct amb_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-amb.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct all_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-all.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct is_empty_tag : all_tag {};
|
||
|
|
||
|
struct any_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-any.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct exists_tag : any_tag {};
|
||
|
struct contains_tag : any_tag {};
|
||
|
|
||
|
struct buffer_count_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_count.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct buffer_with_time_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_time.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct buffer_with_time_or_count_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_time_count.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct combine_latest_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-combine_latest.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct concat_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-concat.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct concat_map_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-concat_map.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct connect_forever_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-connect_forever.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct debounce_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-debounce.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct delay_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-delay.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct distinct_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-distinct.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct distinct_until_changed_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-distinct_until_changed.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct element_at_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-element_at.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct filter_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-filter.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct finally_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-finally.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct flat_map_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-flat_map.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct group_by_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-group_by.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct ignore_elements_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-ignore_elements.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct map_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-map.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct merge_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-merge.hpp>");
|
||
|
};
|
||
|
};
|
||
|
struct merge_delay_error_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-merge_delay_error.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct multicast_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-multicast.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct observe_on_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-observe_on.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct on_error_resume_next_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-on_error_resume_next.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
class empty_error: public std::runtime_error
|
||
|
{
|
||
|
public:
|
||
|
explicit empty_error(const std::string& msg):
|
||
|
std::runtime_error(msg)
|
||
|
{}
|
||
|
};
|
||
|
struct reduce_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-reduce.hpp>");
|
||
|
};
|
||
|
};
|
||
|
struct first_tag : reduce_tag {};
|
||
|
struct last_tag : reduce_tag {};
|
||
|
struct sum_tag : reduce_tag {};
|
||
|
struct average_tag : reduce_tag {};
|
||
|
struct min_tag : reduce_tag {};
|
||
|
struct max_tag : reduce_tag {};
|
||
|
|
||
|
struct ref_count_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-ref_count.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct pairwise_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-pairwise.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct publish_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-publish.hpp>");
|
||
|
};
|
||
|
};
|
||
|
struct publish_synchronized_tag : publish_tag {};
|
||
|
|
||
|
struct repeat_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-repeat.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct replay_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-replay.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct retry_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-retry.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct sample_with_time_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sample_time.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct scan_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-scan.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct sequence_equal_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sequence_equal.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct skip_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct skip_while_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_while.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct skip_last_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_last.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct skip_until_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_until.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct start_with_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-start_with.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct subscribe_on_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-subscribe_on.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct switch_if_empty_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-switch_if_empty.hpp>");
|
||
|
};
|
||
|
};
|
||
|
struct default_if_empty_tag : switch_if_empty_tag {};
|
||
|
|
||
|
struct switch_on_next_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-switch_on_next.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct take_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct take_last_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_last.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct take_while_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_while.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct take_until_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_until.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct tap_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-tap.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct timeout_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-timeout.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct time_interval_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-time_interval.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct timestamp_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-timestamp.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct window_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct window_with_time_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_time.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct window_with_time_or_count_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_time_count.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct window_toggle_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_toggle.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct with_latest_from_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-with_latest_from.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct zip_tag {
|
||
|
template<class Included>
|
||
|
struct include_header{
|
||
|
static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-zip.hpp>");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
#include "operators/rx-multicast.hpp"
|
||
|
#include "operators/rx-publish.hpp"
|
||
|
#include "operators/rx-ref_count.hpp"
|
||
|
|
||
|
#endif
|