1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // UNSUPPORTED: libcpp-has-no-threads
11 
12 // <future>
13 
14 // class packaged_task<R(ArgTypes...)>
15 
16 // template <class F, class Allocator>
17 //     explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
18 
19 #include <future>
20 #include <cassert>
21 
22 #include "../../test_allocator.h"
23 #include "min_allocator.h"
24 
25 class A
26 {
27     long data_;
28 
29 public:
30     static int n_moves;
31     static int n_copies;
32 
A(long i)33     explicit A(long i) : data_(i) {}
A(A && a)34     A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;}
A(const A & a)35     A(const A& a) : data_(a.data_) {++n_copies;}
36 
operator ()(long i,long j) const37     long operator()(long i, long j) const {return data_ + i + j;}
38 };
39 
40 int A::n_moves = 0;
41 int A::n_copies = 0;
42 
func(int i)43 int func(int i) { return i; }
44 
main()45 int main()
46 {
47     {
48         std::packaged_task<double(int, char)> p(std::allocator_arg,
49                                                 test_allocator<A>(), A(5));
50         assert(test_alloc_base::count > 0);
51         assert(p.valid());
52         std::future<double> f = p.get_future();
53         p(3, 'a');
54         assert(f.get() == 105.0);
55         assert(A::n_copies == 0);
56         assert(A::n_moves > 0);
57     }
58     assert(test_alloc_base::count == 0);
59     A::n_copies = 0;
60     A::n_moves  = 0;
61     {
62         A a(5);
63         std::packaged_task<double(int, char)> p(std::allocator_arg,
64                                                 test_allocator<A>(), a);
65         assert(test_alloc_base::count > 0);
66         assert(p.valid());
67         std::future<double> f = p.get_future();
68         p(3, 'a');
69         assert(f.get() == 105.0);
70         assert(A::n_copies > 0);
71         assert(A::n_moves > 0);
72     }
73     assert(test_alloc_base::count == 0);
74     A::n_copies = 0;
75     A::n_moves  = 0;
76     {
77         A a(5);
78         std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), &func);
79         assert(test_alloc_base::count > 0);
80         assert(p.valid());
81         std::future<int> f = p.get_future();
82         p(4);
83         assert(f.get() == 4);
84     }
85     assert(test_alloc_base::count == 0);
86     A::n_copies = 0;
87     A::n_moves  = 0;
88     {
89         A a(5);
90         std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), func);
91         assert(test_alloc_base::count > 0);
92         assert(p.valid());
93         std::future<int> f = p.get_future();
94         p(4);
95         assert(f.get() == 4);
96     }
97     assert(test_alloc_base::count == 0);
98     A::n_copies = 0;
99     A::n_moves  = 0;
100     {
101         std::packaged_task<double(int, char)> p(std::allocator_arg,
102                                                 bare_allocator<void>(), A(5));
103         assert(p.valid());
104         std::future<double> f = p.get_future();
105         p(3, 'a');
106         assert(f.get() == 105.0);
107         assert(A::n_copies == 0);
108         assert(A::n_moves > 0);
109     }
110     A::n_copies = 0;
111     A::n_moves  = 0;
112     {
113         std::packaged_task<double(int, char)> p(std::allocator_arg,
114                                                 min_allocator<void>(), A(5));
115         assert(p.valid());
116         std::future<double> f = p.get_future();
117         p(3, 'a');
118         assert(f.get() == 105.0);
119         assert(A::n_copies == 0);
120         assert(A::n_moves > 0);
121     }
122     A::n_copies = 0;
123     A::n_moves  = 0;
124 }
125