1 | #define BOOST_THREAD_PROVIDES_FUTURE
|
---|
2 | #define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
|
---|
3 | #define BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
|
---|
4 |
|
---|
5 | #include <iostream>
|
---|
6 | #include <iterator>
|
---|
7 | #include <type_traits>
|
---|
8 | #include <boost/assert.hpp>
|
---|
9 | #include <boost/thread.hpp>
|
---|
10 |
|
---|
11 | using boost::future;
|
---|
12 | using boost::promise;
|
---|
13 | using boost::when_all;
|
---|
14 | using boost::make_ready_future;
|
---|
15 |
|
---|
16 | struct Int
|
---|
17 | {
|
---|
18 | size_t n;
|
---|
19 |
|
---|
20 | std::ostream& printme() const { return std::cout << "Int(" << n << ")"; }
|
---|
21 | Int(size_t n) noexcept : n(n) { printme() << " borns" << std::endl; }
|
---|
22 | Int(const Int& other) noexcept : n(other.n) { printme() << " borns" << std::endl; }
|
---|
23 | Int& operator=(const Int& other) noexcept { n = other.n; return *this; }
|
---|
24 | ~Int() noexcept { printme() << " dies" << std::endl; }
|
---|
25 | operator size_t() noexcept { return n; }
|
---|
26 | };
|
---|
27 |
|
---|
28 | template<class T, size_t N = 1000>
|
---|
29 | future<void> iter(int K)
|
---|
30 | {
|
---|
31 | std::cout << K << ": iter() started" << std::endl;
|
---|
32 |
|
---|
33 | static std::vector< promise<T> > p;
|
---|
34 | p.resize(0);
|
---|
35 | p.resize(N);
|
---|
36 |
|
---|
37 | std::cout << K << ": promise cleanup finished" << std::endl;
|
---|
38 |
|
---|
39 | std::vector< future<T> > f;
|
---|
40 | f.reserve(N);
|
---|
41 |
|
---|
42 | for (size_t i = 0; i < N; ++i) {
|
---|
43 | f.push_back(p[i].get_future());
|
---|
44 | }
|
---|
45 |
|
---|
46 | auto ret = when_all(f.begin(), f.end()).then(
|
---|
47 | [=](future< std::vector< future<T> > > fv) {
|
---|
48 | auto v = fv.get();
|
---|
49 | for (size_t i = 0; i < N; ++i) {
|
---|
50 | BOOST_ASSERT(v.at(i).get() == i);
|
---|
51 | }
|
---|
52 |
|
---|
53 | std::cout << K << ": when_all satisfied" << std::endl;
|
---|
54 | }
|
---|
55 | );
|
---|
56 |
|
---|
57 | for (size_t i = 0; i < N; ++i) {
|
---|
58 | p[i].set_value(i);
|
---|
59 | }
|
---|
60 |
|
---|
61 | std::cout << K << ": iter() finished" << std::endl;
|
---|
62 |
|
---|
63 | return std::move(ret);
|
---|
64 | }
|
---|
65 |
|
---|
66 | int main()
|
---|
67 | {
|
---|
68 | // Valgrind test
|
---|
69 | #if 0
|
---|
70 | for (int k = 0; k < 5 ; ++k) {
|
---|
71 | iter<Int, 2>(k).get();
|
---|
72 | }
|
---|
73 | #else
|
---|
74 | for (int k = 0; ; ++k) {
|
---|
75 | iter<size_t, 10000>(k).get();
|
---|
76 | }
|
---|
77 | #endif
|
---|
78 | }
|
---|