// Copyright 2021 gRPC authors. // // 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. #ifndef GRPC_CORE_LIB_PROMISE_SEQ_H #define GRPC_CORE_LIB_PROMISE_SEQ_H #include #include #include "src/core/lib/promise/detail/basic_seq.h" #include "src/core/lib/promise/detail/promise_like.h" #include "src/core/lib/promise/poll.h" namespace grpc_core { namespace promise_detail { template struct SeqTraits { using UnwrappedType = T; using WrappedType = T; template static auto CallFactory(Next* next, T&& value) -> decltype(next->Once(std::forward(value))) { return next->Once(std::forward(value)); } template static auto CallSeqFactory(F& f, Elem&& elem, T&& value) -> decltype(f(std::forward(elem), std::forward(value))) { return f(std::forward(elem), std::forward(value)); } template static Poll CheckResultAndRunNext(PriorResult prior, RunNext run_next) { return run_next(std::move(prior)); } }; template using Seq = BasicSeq; template struct SeqIterTraits { using Iter = I; using Factory = F; using Argument = Arg; using IterValue = decltype(*std::declval()); using StateCreated = decltype(std::declval()(std::declval(), std::declval())); using State = PromiseLike; using Wrapped = typename State::Result; using Traits = SeqTraits; }; template struct SeqIterResultTraits { using IterTraits = SeqIterTraits; using Result = BasicSeqIter; }; } // namespace promise_detail // Sequencing combinator. // Run the first promise. // Pass its result to the second, and run the returned promise. // Pass its result to the third, and run the returned promise. // etc // Return the final value. template promise_detail::Seq Seq(Functors... functors) { return promise_detail::Seq(std::move(functors)...); } template F Seq(F functor) { return functor; } // Execute a sequence of operations of unknown length. // Asynchronously: // for (element in (begin, end)) { // argument = wait_for factory(element, argument); // } // return argument; template typename promise_detail::SeqIterResultTraits::Result SeqIter(Iter begin, Iter end, Argument argument, Factory factory) { using Result = typename promise_detail::SeqIterResultTraits::Result; return Result(begin, end, std::move(factory), std::move(argument)); } } // namespace grpc_core #endif // GRPC_CORE_LIB_PROMISE_SEQ_H