// Copyright (c) Facebook, Inc. and its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include "yarpl/observable/ObservableOperator.h" namespace yarpl { namespace observable { namespace details { template < typename U, typename OnSubscribeFunc, typename OnNextFunc, typename OnErrorFunc, typename OnCompleteFunc, typename OnCancelFunc> class DoOperator : public ObservableOperator { using Super = ObservableOperator; static_assert( std::is_same, OnSubscribeFunc>::value, "undecayed"); static_assert( std::is_same, OnNextFunc>::value, "undecayed"); static_assert( std::is_same, OnErrorFunc>::value, "undecayed"); static_assert( std::is_same, OnCompleteFunc>::value, "undecayed"); static_assert( std::is_same, OnCancelFunc>::value, "undecayed"); public: template < typename FSubscribe, typename FNext, typename FError, typename FComplete, typename FCancel> DoOperator( std::shared_ptr> upstream, FSubscribe&& onSubscribeFunc, FNext&& onNextFunc, FError&& onErrorFunc, FComplete&& onCompleteFunc, FCancel&& onCancelFunc) : upstream_(std::move(upstream)), onSubscribeFunc_(std::forward(onSubscribeFunc)), onNextFunc_(std::forward(onNextFunc)), onErrorFunc_(std::forward(onErrorFunc)), onCompleteFunc_(std::forward(onCompleteFunc)), onCancelFunc_(std::forward(onCancelFunc)) {} std::shared_ptr subscribe( std::shared_ptr> observer) override { auto subscription = std::make_shared( this->ref_from_this(this), std::move(observer)); upstream_->subscribe( // Note: implicit cast to a reference to a observer. subscription); return subscription; } private: class DoSubscription : public Super::OperatorSubscription { using SuperSub = typename Super::OperatorSubscription; public: DoSubscription( std::shared_ptr observable, std::shared_ptr> observer) : SuperSub(std::move(observer)), observable_(std::move(observable)) {} void onSubscribe(std::shared_ptr subscription) override { observable_->onSubscribeFunc_(); SuperSub::onSubscribe(std::move(subscription)); } void onNext(U value) override { const auto& valueRef = value; observable_->onNextFunc_(valueRef); SuperSub::observerOnNext(std::move(value)); } void onError(folly::exception_wrapper ex) override { const auto& exRef = ex; observable_->onErrorFunc_(exRef); SuperSub::onError(std::move(ex)); } void onComplete() override { observable_->onCompleteFunc_(); SuperSub::onComplete(); } void cancel() override { observable_->onCancelFunc_(); SuperSub::cancel(); } private: std::shared_ptr observable_; }; std::shared_ptr> upstream_; OnSubscribeFunc onSubscribeFunc_; OnNextFunc onNextFunc_; OnErrorFunc onErrorFunc_; OnCompleteFunc onCompleteFunc_; OnCancelFunc onCancelFunc_; }; template < typename U, typename OnSubscribeFunc, typename OnNextFunc, typename OnErrorFunc, typename OnCompleteFunc, typename OnCancelFunc> inline auto createDoOperator( std::shared_ptr> upstream, OnSubscribeFunc&& onSubscribeFunc, OnNextFunc&& onNextFunc, OnErrorFunc&& onErrorFunc, OnCompleteFunc&& onCompleteFunc, OnCancelFunc&& onCancelFunc) { return std::make_shared, std::decay_t, std::decay_t, std::decay_t, std::decay_t>>( std::move(upstream), std::forward(onSubscribeFunc), std::forward(onNextFunc), std::forward(onErrorFunc), std::forward(onCompleteFunc), std::forward(onCancelFunc)); } } // namespace details } // namespace observable } // namespace yarpl