summaryrefslogtreecommitdiff
path: root/grpc/src/core/lib/promise/seq.h
diff options
context:
space:
mode:
Diffstat (limited to 'grpc/src/core/lib/promise/seq.h')
-rw-r--r--grpc/src/core/lib/promise/seq.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/grpc/src/core/lib/promise/seq.h b/grpc/src/core/lib/promise/seq.h
new file mode 100644
index 00000000..8ad2c549
--- /dev/null
+++ b/grpc/src/core/lib/promise/seq.h
@@ -0,0 +1,89 @@
+// 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 <grpc/support/port_platform.h>
+
+#include <utility>
+
+#include "absl/types/variant.h"
+
+#include "src/core/lib/promise/detail/basic_seq.h"
+#include "src/core/lib/promise/poll.h"
+
+namespace grpc_core {
+
+namespace promise_detail {
+
+template <typename T>
+struct SeqTraits {
+ using UnwrappedType = T;
+ using WrappedType = T;
+ template <typename Next>
+ static auto CallFactory(Next* next, T&& value)
+ -> decltype(next->Once(std::forward<T>(value))) {
+ return next->Once(std::forward<T>(value));
+ }
+ template <typename F, typename Elem>
+ static auto CallSeqFactory(F& f, Elem&& elem, T&& value)
+ -> decltype(f(std::forward<Elem>(elem), std::forward<T>(value))) {
+ return f(std::forward<Elem>(elem), std::forward<T>(value));
+ }
+ template <typename Result, typename PriorResult, typename RunNext>
+ static Poll<Result> CheckResultAndRunNext(PriorResult prior,
+ RunNext run_next) {
+ return run_next(std::move(prior));
+ }
+};
+
+template <typename... Fs>
+using Seq = BasicSeq<SeqTraits, Fs...>;
+
+} // 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 <typename... Functors>
+promise_detail::Seq<Functors...> Seq(Functors... functors) {
+ return promise_detail::Seq<Functors...>(std::move(functors)...);
+}
+
+template <typename F>
+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 Iter, typename Factory, typename Argument>
+promise_detail::BasicSeqIter<promise_detail::SeqTraits, Factory, Argument, Iter>
+SeqIter(Iter begin, Iter end, Argument argument, Factory factory) {
+ return promise_detail::BasicSeqIter<promise_detail::SeqTraits, Factory,
+ Argument, Iter>(
+ begin, end, std::move(factory), std::move(argument));
+}
+
+} // namespace grpc_core
+
+#endif // GRPC_CORE_LIB_PROMISE_SEQ_H