| 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 | }
|
|---|