static auto all()

in demo_example/asio/asio/experimental/promise.hpp [400:486]


  static auto all(Executor1 exec, Range  range)
    -> promise<
        void(
          std::vector<
            typename std::decay_t<
              decltype(*std::begin(range))
            >::value_type
          >
        ), Executor1>
  {
    using var_t = typename std::decay_t<
      decltype(*std::begin(range))>::value_type;
    using pi = detail::promise_impl<void(std::vector<var_t>), Executor1>;

    struct impl_t : pi
    {
      impl_t(Executor1 exec, Range&& range)
        : pi(std::move(exec)),
          range(std::move(range))
      {
        this->slot.template emplace<cancel_handler>(this);
      }

      struct cancel_handler
      {
        impl_t* self;

        cancel_handler(impl_t* self)
          : self(self)
        {
        }

        void operator()(cancellation_type ct)
        {
          for (auto& r : self->range)
            r.cancel(ct);
        }
      };

      Range range;
      std::vector<std::optional<var_t>> partial_result;
      cancellation_slot slot{this->cancel.slot()};
    };

    const auto size = std::distance(std::begin(range), std::end(range));
    auto impl =  std::allocate_shared<impl_t>(
        get_associated_allocator(exec), exec, std::move(range));
    impl->executor = exec;
    impl->partial_result.resize(size);

    if (size == 0u)
    {
      impl->result.emplace();
      impl->done = true;
      if (auto f = std::exchange(impl->completion, nullptr); !!f)
        asio::post(exec, [impl, f = std::move(f)]() mutable
            {
              std::apply(std::move(f), std::move(*impl->result));
            });
      return {impl};
    }
    auto idx = 0u;
    for (auto& val : impl->range) {
      val.async_wait(bind_executor(
          exec,
          [idx, impl]<typename... Args>(Args&&... args) {

            impl->partial_result[idx].emplace(std::forward<Args>(args)...);
            if (std::all_of(impl->partial_result.begin(),
                  impl->partial_result.end(),
                  [](auto &opt) {return opt.has_value();}))
            {
              impl->result.emplace();
              get<0>(*impl->result).reserve(impl->partial_result.size());
              for (auto& p : impl->partial_result)
                get<0>(*impl->result).push_back(std::move(*p));

              impl->done = true;
              if (auto f = std::exchange(impl->completion, nullptr); !!f)
                std::apply(std::move(f), std::move(*impl->result));
            }

          }));
      idx++;
    }
    return {impl};
  }