1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // UNSUPPORTED: no-threads
10 
11 // packaged_task allocator support was removed in C++17 (LWG 2921)
12 // REQUIRES: c++11 || c++14
13 
14 // <future>
15 
16 // class packaged_task<R(ArgTypes...)>
17 
18 // template <class F, class Allocator>
19 //     explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
20 
21 #include <future>
22 #include <cassert>
23 
24 #include "test_macros.h"
25 #include "test_allocator.h"
26 #include "min_allocator.h"
27 
28 class A
29 {
30     long data_;
31 
32 public:
33     static int n_moves;
34     static int n_copies;
35 
A(long i)36     explicit A(long i) : data_(i) {}
A(A && a)37     A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;}
A(const A & a)38     A(const A& a) : data_(a.data_) {++n_copies;}
39 
operator ()(long i,long j) const40     long operator()(long i, long j) const {return data_ + i + j;}
41 };
42 
43 int A::n_moves = 0;
44 int A::n_copies = 0;
45 
func(int i)46 int func(int i) { return i; }
47 
main(int,char **)48 int main(int, char**)
49 {
50     test_allocator_statistics alloc_stats;
51     {
52         std::packaged_task<double(int, char)> p(std::allocator_arg,
53                                                 test_allocator<A>(&alloc_stats), A(5));
54         assert(alloc_stats.alloc_count > 0);
55         assert(p.valid());
56         std::future<double> f = p.get_future();
57         p(3, 'a');
58         assert(f.get() == 105.0);
59         assert(A::n_copies == 0);
60         assert(A::n_moves > 0);
61     }
62     assert(alloc_stats.alloc_count == 0);
63     A::n_copies = 0;
64     A::n_moves  = 0;
65     {
66         A a(5);
67         std::packaged_task<double(int, char)> p(std::allocator_arg,
68                                                 test_allocator<A>(&alloc_stats), a);
69         assert(alloc_stats.alloc_count > 0);
70         assert(p.valid());
71         std::future<double> f = p.get_future();
72         p(3, 'a');
73         assert(f.get() == 105.0);
74         assert(A::n_copies > 0);
75         assert(A::n_moves >= 0);
76     }
77     assert(alloc_stats.alloc_count == 0);
78     A::n_copies = 0;
79     A::n_moves  = 0;
80     {
81         A a(5);
82         std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(&alloc_stats), &func);
83         assert(alloc_stats.alloc_count > 0);
84         assert(p.valid());
85         std::future<int> f = p.get_future();
86         p(4);
87         assert(f.get() == 4);
88     }
89     assert(alloc_stats.alloc_count == 0);
90     A::n_copies = 0;
91     A::n_moves  = 0;
92     {
93         A a(5);
94         std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(&alloc_stats), func);
95         assert(alloc_stats.alloc_count > 0);
96         assert(p.valid());
97         std::future<int> f = p.get_future();
98         p(4);
99         assert(f.get() == 4);
100     }
101     assert(alloc_stats.alloc_count == 0);
102     A::n_copies = 0;
103     A::n_moves  = 0;
104     {
105         std::packaged_task<double(int, char)> p(std::allocator_arg,
106                                                 bare_allocator<void>(), A(5));
107         assert(p.valid());
108         std::future<double> f = p.get_future();
109         p(3, 'a');
110         assert(f.get() == 105.0);
111         assert(A::n_copies == 0);
112         assert(A::n_moves > 0);
113     }
114     A::n_copies = 0;
115     A::n_moves  = 0;
116     {
117         std::packaged_task<double(int, char)> p(std::allocator_arg,
118                                                 min_allocator<void>(), A(5));
119         assert(p.valid());
120         std::future<double> f = p.get_future();
121         p(3, 'a');
122         assert(f.get() == 105.0);
123         assert(A::n_copies == 0);
124         assert(A::n_moves > 0);
125     }
126     A::n_copies = 0;
127     A::n_moves  = 0;
128 
129   return 0;
130 }
131