| 210 | |
| 211 | template <typename T> |
| 212 | future<std::vector<future<T>>> when_all(std::vector<future<T>> w) { |
| 213 | class Accumulator : public std::enable_shared_from_this<Accumulator> { |
| 214 | public: |
| 215 | Accumulator() : unsatisfied_(0) {} |
| 216 | |
| 217 | future<std::vector<future<T>>> Start(std::vector<future<T>> all) { |
| 218 | auto self = this->shared_from_this(); |
| 219 | unsatisfied_ = all.size(); |
| 220 | accumulator_.resize(all.size()); |
| 221 | std::size_t i = 0; |
| 222 | for (auto& f : all) { |
| 223 | cont_.push_back(f.then([index = i++, self](future<T> g) { |
| 224 | self->OnCompletion(index, std::move(g)); |
| 225 | })); |
| 226 | } |
| 227 | return done_.get_future(); |
| 228 | } |
| 229 | |
| 230 | private: |
| 231 | void OnCompletion(std::size_t index, future<T> g) { |
| 232 | accumulator_[index] = std::move(g); |
| 233 | if (--unsatisfied_ == 0) done_.set_value(std::move(accumulator_)); |
| 234 | } |
| 235 | std::atomic<std::size_t> unsatisfied_; |
| 236 | std::vector<future<T>> accumulator_; |
| 237 | std::vector<future<void>> cont_; |
| 238 | google::cloud::promise<std::vector<future<T>>> done_; |
| 239 | }; |
| 240 | |
| 241 | auto accumulator = std::make_shared<Accumulator>(); |
| 242 | return accumulator->Start(std::move(w)); |
| 243 | } |
| 244 | |
| 245 | template <class... Ts> |
| 246 | struct overloaded : Ts... { |