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