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
24class A
25{
26 int i_;
27 double d_;
28
29public:
30 A(const A&) = delete;
31 A& operator=(const A&) = delete;
32
33 TEST_CONSTEXPR_CXX14 A(int i, double d)
34 : i_(i), d_(d) {}
35
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
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
53 TEST_CONSTEXPR_CXX14 int geti() const {return i_;}
54 TEST_CONSTEXPR_CXX14 double getd() const {return d_;}
55};
56
57TEST_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(args: 2, args: 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(args: 3, args: 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(x: sz++);
182 c.emplace_back(args&: 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
190int main(int, char**)
191{
192 tests();
193#if TEST_STD_VER > 17
194 static_assert(tests());
195#endif
196 return 0;
197}
198

source code of libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp