10#include <userver/engine/deadline.hpp> 
   11#include <userver/utils/meta.hpp> 
   12#include <userver/utils/span.hpp> 
   14USERVER_NAMESPACE_BEGIN
 
   32template <
typename... Tasks>
 
   33std::optional<std::size_t> 
WaitAny(Tasks&... tasks);
 
   38template <
typename... Tasks, 
typename Rep, 
typename Period>
 
   39std::optional<std::size_t> WaitAnyFor(
 
   40    const std::chrono::duration<Rep, Period>& duration, Tasks&... tasks);
 
   45template <
typename... Tasks, 
typename Clock, 
typename Duration>
 
   46std::optional<std::size_t> WaitAnyUntil(
 
   47    const std::chrono::time_point<Clock, Duration>& until, Tasks&... tasks);
 
   52template <
typename... Tasks>
 
   53std::optional<std::size_t> WaitAnyUntil(Deadline, Tasks&... tasks);
 
   55template <
typename... Tasks>
 
   56std::optional<std::size_t> 
WaitAny(Tasks&... tasks) {
 
   57  return engine::WaitAnyUntil(Deadline
{}, tasks...);
 
   60template <
typename... Tasks, 
typename Rep, 
typename Period>
 
   61std::optional<std::size_t> WaitAnyFor(
 
   62    const std::chrono::duration<Rep, Period>& duration, Tasks&... tasks) {
 
   63  return engine::WaitAnyUntil(Deadline::FromDuration(duration), tasks...);
 
   66template <
typename... Tasks, 
typename Clock, 
typename Duration>
 
   67std::optional<std::size_t> WaitAnyUntil(
 
   68    const std::chrono::time_point<Clock, Duration>& until, Tasks&... tasks) {
 
   69  return engine::WaitAnyUntil(Deadline::FromTimePoint(until), tasks...);
 
   76std::optional<std::size_t> DoWaitAny(utils::span<ContextAccessor*> targets,
 
   79template <
typename Container>
 
   80std::optional<std::size_t> WaitAnyFromContainer(Deadline deadline,
 
   82  const auto size = std::size(tasks);
 
   83  std::vector<ContextAccessor*> targets;
 
   84  targets.reserve(size);
 
   86  for (
auto& task : tasks) {
 
   87    targets.push_back(task.TryGetContextAccessor());
 
   90  return DoWaitAny(targets, deadline);
 
   93template <
typename... Tasks>
 
   94std::optional<std::size_t> WaitAnyFromTasks(Deadline deadline,
 
   96  ContextAccessor* wa_elements[]{tasks.TryGetContextAccessor()...};
 
   97  return DoWaitAny(wa_elements, deadline);
 
  100inline std::optional<std::size_t> WaitAnyFromTasks(Deadline) { 
return {}; }
 
  104template <
typename... Tasks>
 
  105std::optional<std::size_t> WaitAnyUntil(Deadline deadline, Tasks&... tasks) {
 
  106  if constexpr (meta::impl::IsSingleRange<Tasks...>()) {
 
  107    return impl::WaitAnyFromContainer(deadline, tasks...);
 
  109    return impl::WaitAnyFromTasks(deadline, tasks...);