/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2020 Telegram Systems LLP */ #pragma once #include "refcnt.hpp" #include "td/actor/PromiseFuture.h" namespace td { template class BinaryPromiseMerger : public CntObject { Result first_; Result second_; Promise> promise_; std::atomic pending_; public: BinaryPromiseMerger(Promise> promise) : promise_(std::move(promise)), pending_(2) { } static std::pair, Promise> split(Promise> promise) { auto ref = make_ref(std::move(promise)); auto& obj = ref.write(); return std::make_pair(obj.left(), obj.right()); } private: Promise left() { return [this, self = Ref(this)](Result res) { first_ = std::move(res); work(); }; } Promise right() { return [this, self = Ref(this)](Result res) { second_ = std::move(res); work(); }; } void work() { if (!--pending_) { if (first_.is_error()) { promise_.set_error(first_.move_as_error()); } else if (second_.is_error()) { promise_.set_error(second_.move_as_error()); } else { promise_.set_result(std::pair(first_.move_as_ok(), second_.move_as_ok())); } } } }; template std::pair, Promise> split_promise(Promise> promise) { return BinaryPromiseMerger::split(std::move(promise)); } } // namespace td