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