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

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