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<Tag_X, TaggingAllocator<Tag_X> > c;
142 c.emplace_back();
143 assert(c.size() == 1);
144 c.emplace_back(1, 2, 3);
145 assert(c.size() == 2);
146 assert(is_contiguous_container_asan_correct(c));
147 }
148
149 { // LWG 2164
150 int arr[] = {0, 1, 2, 3, 4};
151 int sz = 5;
152 std::vector<int> c(arr, arr+sz);
153 while (c.size() < c.capacity())
154 c.push_back(sz++);
155 c.emplace_back(c.front());
156 assert(c.back() == 0);
157 for (int i = 0; i < sz; ++i)
158 assert(c[i] == i);
159 }
160 return true;
161 }
162
main(int,char **)163 int main(int, char**)
164 {
165 tests();
166 #if TEST_STD_VER > 17
167 static_assert(tests());
168 #endif
169 return 0;
170 }
171