xref: /llvm-project/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp (revision e3dd9f7e66fec22986605da2dcd8120a7864455d)
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: c++03 && !stdlib=libc++
10 
11 // <vector>
12 
13 // template <class... Args> reference emplace_back(Args&&... args);
14 // return type is 'reference' in C++17; 'void' before
15 
16 #include <vector>
17 #include <cassert>
18 #include "test_macros.h"
19 #include "test_allocator.h"
20 #include "min_allocator.h"
21 #include "test_allocator.h"
22 #include "asan_testing.h"
23 
24 class A
25 {
26     int i_;
27     double d_;
28 
29 public:
30     A(const A&) = delete;
31     A& operator=(const A&) = delete;
32 
A(int i,double d)33     TEST_CONSTEXPR_CXX14 A(int i, double d)
34         : i_(i), d_(d) {}
35 
A(A && a)36     TEST_CONSTEXPR_CXX14 A(A&& a)
37         : i_(a.i_),
38           d_(a.d_)
39     {
40         a.i_ = 0;
41         a.d_ = 0;
42     }
43 
operator =(A && a)44     TEST_CONSTEXPR_CXX14 A& operator=(A&& a)
45     {
46         i_ = a.i_;
47         d_ = a.d_;
48         a.i_ = 0;
49         a.d_ = 0;
50         return *this;
51     }
52 
geti() const53     TEST_CONSTEXPR_CXX14 int geti() const {return i_;}
getd() const54     TEST_CONSTEXPR_CXX14 double getd() const {return d_;}
55 };
56 
tests()57 TEST_CONSTEXPR_CXX20 bool tests()
58 {
59     {
60         std::vector<A> c;
61 #if TEST_STD_VER > 14
62         A& r1 = c.emplace_back(2, 3.5);
63         assert(c.size() == 1);
64         assert(&r1 == &c.back());
65         assert(c.front().geti() == 2);
66         assert(c.front().getd() == 3.5);
67         assert(is_contiguous_container_asan_correct(c));
68         A& r2 = c.emplace_back(3, 4.5);
69         assert(c.size() == 2);
70         assert(&r2 == &c.back());
71 #else
72         c.emplace_back(2, 3.5);
73         assert(c.size() == 1);
74         assert(c.front().geti() == 2);
75         assert(c.front().getd() == 3.5);
76         assert(is_contiguous_container_asan_correct(c));
77         c.emplace_back(3, 4.5);
78         assert(c.size() == 2);
79 #endif
80         assert(c.front().geti() == 2);
81         assert(c.front().getd() == 3.5);
82         assert(c.back().geti() == 3);
83         assert(c.back().getd() == 4.5);
84         assert(is_contiguous_container_asan_correct(c));
85     }
86     {
87         std::vector<A, limited_allocator<A, 4> > c;
88 #if TEST_STD_VER > 14
89         A& r1 = c.emplace_back(2, 3.5);
90         assert(c.size() == 1);
91         assert(&r1 == &c.back());
92         assert(c.front().geti() == 2);
93         assert(c.front().getd() == 3.5);
94         assert(is_contiguous_container_asan_correct(c));
95         A& r2 = c.emplace_back(3, 4.5);
96         assert(c.size() == 2);
97         assert(&r2 == &c.back());
98 #else
99         c.emplace_back(2, 3.5);
100         assert(c.size() == 1);
101         assert(c.front().geti() == 2);
102         assert(c.front().getd() == 3.5);
103         assert(is_contiguous_container_asan_correct(c));
104         c.emplace_back(3, 4.5);
105         assert(c.size() == 2);
106 #endif
107         assert(c.front().geti() == 2);
108         assert(c.front().getd() == 3.5);
109         assert(c.back().geti() == 3);
110         assert(c.back().getd() == 4.5);
111         assert(is_contiguous_container_asan_correct(c));
112     }
113     {
114         std::vector<A, min_allocator<A> > c;
115 #if TEST_STD_VER > 14
116         A& r1 = c.emplace_back(2, 3.5);
117         assert(c.size() == 1);
118         assert(&r1 == &c.back());
119         assert(c.front().geti() == 2);
120         assert(c.front().getd() == 3.5);
121         assert(is_contiguous_container_asan_correct(c));
122         A& r2 = c.emplace_back(3, 4.5);
123         assert(c.size() == 2);
124         assert(&r2 == &c.back());
125 #else
126         c.emplace_back(2, 3.5);
127         assert(c.size() == 1);
128         assert(c.front().geti() == 2);
129         assert(c.front().getd() == 3.5);
130         assert(is_contiguous_container_asan_correct(c));
131         c.emplace_back(3, 4.5);
132         assert(c.size() == 2);
133 #endif
134         assert(c.front().geti() == 2);
135         assert(c.front().getd() == 3.5);
136         assert(c.back().geti() == 3);
137         assert(c.back().getd() == 4.5);
138         assert(is_contiguous_container_asan_correct(c));
139     }
140     {
141       std::vector<A, safe_allocator<A> > c;
142 #if TEST_STD_VER > 14
143       A& r1 = c.emplace_back(2, 3.5);
144       assert(c.size() == 1);
145       assert(&r1 == &c.back());
146       assert(c.front().geti() == 2);
147       assert(c.front().getd() == 3.5);
148       assert(is_contiguous_container_asan_correct(c));
149       A& r2 = c.emplace_back(3, 4.5);
150       assert(c.size() == 2);
151       assert(&r2 == &c.back());
152 #else
153         c.emplace_back(2, 3.5);
154         assert(c.size() == 1);
155         assert(c.front().geti() == 2);
156         assert(c.front().getd() == 3.5);
157         assert(is_contiguous_container_asan_correct(c));
158         c.emplace_back(3, 4.5);
159         assert(c.size() == 2);
160 #endif
161         assert(c.front().geti() == 2);
162         assert(c.front().getd() == 3.5);
163         assert(c.back().geti() == 3);
164         assert(c.back().getd() == 4.5);
165         assert(is_contiguous_container_asan_correct(c));
166     }
167     {
168         std::vector<Tag_X, TaggingAllocator<Tag_X> > c;
169         c.emplace_back();
170         assert(c.size() == 1);
171         c.emplace_back(1, 2, 3);
172         assert(c.size() == 2);
173         assert(is_contiguous_container_asan_correct(c));
174     }
175 
176     { // LWG 2164
177         int arr[] = {0, 1, 2, 3, 4};
178         int sz = 5;
179         std::vector<int> c(arr, arr+sz);
180         while (c.size() < c.capacity())
181             c.push_back(sz++);
182         c.emplace_back(c.front());
183         assert(c.back() == 0);
184         for (int i = 0; i < sz; ++i)
185             assert(c[i] == i);
186     }
187     return true;
188 }
189 
main(int,char **)190 int main(int, char**)
191 {
192     tests();
193 #if TEST_STD_VER > 17
194     static_assert(tests());
195 #endif
196     return 0;
197 }
198