ledger-core
FutureUtils.hpp
1 /*
2 *
3 * FutureUtils
4 * ledger-core
5 *
6 * Created by Andrii Korol on 22/11/2018.
7 *
8 * The MIT License (MIT)
9 *
10 * Copyright (c) 2018 Ledger
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this software and associated documentation files (the "Software"), to deal
14 * in the Software without restriction, including without limitation the rights
15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the Software is
17 * furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included in all
20 * copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 * SOFTWARE.
29 *
30 */
31 
32 #pragma once
33 
34 #include <exception>
35 #include <memory>
36 #include <functional>
37 #include "Deffered.hpp"
38 #include "../api/ExecutionContext.hpp"
39 #include "../utils/Exception.hpp"
40 #include "../traits/callback_traits.hpp"
41 #include "../api/Error.hpp"
42 #include "Future.hpp"
43 
44 namespace ledger {
45  namespace core {
46 
47  template<typename T>
48  struct Container {
49  std::vector<T> result;
50  std::mutex lock;
51  uint32_t count;
52  };
53 
54  template<typename T>
55  Future<std::vector<T>> executeAll(const std::shared_ptr<api::ExecutionContext>& context, std::vector<Future<T>>& futures) {
56  auto container = std::make_shared<Container<T>>();
57  container->count = 0;
58  container->result.resize(futures.size());
59  auto deffered = std::make_shared<Deffered<std::vector<T>>>();
60  for (int i = 0; i < futures.size(); ++i) {
61  futures[i].onComplete(context, [container, deffered, i](const Try<T>& result) {
62  std::lock_guard<std::mutex> lock(container->lock);
63  if (deffered->hasValue())
64  return;
65  if (result.isSuccess()) {
66  container->result[i] = result.getValue();
67  container->count++;
68  if (container->count == container->result.size())
69  deffered->setValue(container->result);
70  }
71  else {
72  deffered->setError(result.getFailure());
73  }
74  });
75  }
76  return Future<std::vector<T>>(deffered);
77 
78  }
79  }
80 }
Definition: Try.hpp:49
Definition: Deffered.hpp:49
Definition: FutureUtils.hpp:48
Definition: Account.cpp:8