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 // <string>
10
11 // basic_string(const basic_string<charT,traits,Allocator>& str,
12 // size_type pos, size_type n,
13 // const Allocator& a = Allocator()); // constexpr since C++20
14 //
15 // basic_string(const basic_string<charT,traits,Allocator>& str,
16 // size_type pos,
17 // const Allocator& a = Allocator()); // constexpr since C++20
18
19 #include <string>
20 #include <stdexcept>
21 #include <algorithm>
22 #include <vector>
23 #include <scoped_allocator>
24 #include <cassert>
25
26 #include "test_macros.h"
27 #include "test_allocator.h"
28 #include "min_allocator.h"
29
30 template <class S>
31 TEST_CONSTEXPR_CXX20 void
test(S str,unsigned pos)32 test(S str, unsigned pos)
33 {
34 typedef typename S::traits_type T;
35 typedef typename S::allocator_type A;
36
37 if (pos <= str.size())
38 {
39 S s2(str, pos);
40 LIBCPP_ASSERT(s2.__invariants());
41 typename S::size_type rlen = str.size() - pos;
42 assert(s2.size() == rlen);
43 assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
44 assert(s2.get_allocator() == A());
45 assert(s2.capacity() >= s2.size());
46 }
47 #ifndef TEST_HAS_NO_EXCEPTIONS
48 else if (!TEST_IS_CONSTANT_EVALUATED)
49 {
50 try
51 {
52 S s2(str, pos);
53 assert(false);
54 }
55 catch (std::out_of_range&)
56 {
57 assert(pos > str.size());
58 }
59 }
60 #endif
61 }
62
63 template <class S>
64 TEST_CONSTEXPR_CXX20 void
test(S str,unsigned pos,unsigned n)65 test(S str, unsigned pos, unsigned n)
66 {
67 typedef typename S::traits_type T;
68 typedef typename S::allocator_type A;
69 if (pos <= str.size())
70 {
71 S s2(str, pos, n);
72 LIBCPP_ASSERT(s2.__invariants());
73 typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);
74 assert(s2.size() == rlen);
75 assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
76 assert(s2.get_allocator() == A());
77 assert(s2.capacity() >= s2.size());
78 }
79 #ifndef TEST_HAS_NO_EXCEPTIONS
80 else if (!TEST_IS_CONSTANT_EVALUATED)
81 {
82 try
83 {
84 S s2(str, pos, n);
85 assert(false);
86 }
87 catch (std::out_of_range&)
88 {
89 assert(pos > str.size());
90 }
91 }
92 #endif
93 }
94
95 template <class S>
96 TEST_CONSTEXPR_CXX20 void
test(S str,unsigned pos,unsigned n,const typename S::allocator_type & a)97 test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a)
98 {
99 typedef typename S::traits_type T;
100
101 if (pos <= str.size())
102 {
103 S s2(str, pos, n, a);
104 LIBCPP_ASSERT(s2.__invariants());
105 typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);
106 assert(s2.size() == rlen);
107 assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
108 assert(s2.get_allocator() == a);
109 assert(s2.capacity() >= s2.size());
110 }
111 #ifndef TEST_HAS_NO_EXCEPTIONS
112 else if (!TEST_IS_CONSTANT_EVALUATED)
113 {
114 try
115 {
116 S s2(str, pos, n, a);
117 assert(false);
118 }
119 catch (std::out_of_range&)
120 {
121 assert(pos > str.size());
122 }
123 }
124 #endif
125 }
126
test_lwg2583()127 void test_lwg2583()
128 {
129 #if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
130 typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> StringA;
131 std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA>>> vs;
132 StringA s{"1234"};
133 vs.emplace_back(s, 2);
134
135 try { vs.emplace_back(s, 5); }
136 catch (const std::out_of_range&) { return; }
137 assert(false);
138 #endif
139 }
140
test()141 TEST_CONSTEXPR_CXX20 bool test() {
142 {
143 typedef test_allocator<char> A;
144 typedef std::basic_string<char, std::char_traits<char>, A> S;
145
146 test(S(A(3)), 0);
147 test(S(A(3)), 1);
148 test(S("1", A(5)), 0);
149 test(S("1", A(5)), 1);
150 test(S("1", A(5)), 2);
151 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 0);
152 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 5);
153 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50);
154 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 500);
155
156 test(S(A(3)), 0, 0);
157 test(S(A(3)), 0, 1);
158 test(S(A(3)), 1, 0);
159 test(S(A(3)), 1, 1);
160 test(S(A(3)), 1, 2);
161 test(S("1", A(5)), 0, 0);
162 test(S("1", A(5)), 0, 1);
163 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 0);
164 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1);
165 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10);
166 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100);
167
168 test(S(A(3)), 0, 0, A(4));
169 test(S(A(3)), 0, 1, A(4));
170 test(S(A(3)), 1, 0, A(4));
171 test(S(A(3)), 1, 1, A(4));
172 test(S(A(3)), 1, 2, A(4));
173 test(S("1", A(5)), 0, 0, A(6));
174 test(S("1", A(5)), 0, 1, A(6));
175 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 0, A(8));
176 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1, A(8));
177 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10, A(8));
178 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100, A(8));
179 }
180 #if TEST_STD_VER >= 11
181 {
182 typedef min_allocator<char> A;
183 typedef std::basic_string<char, std::char_traits<char>, A> S;
184
185 test(S(A()), 0);
186 test(S(A()), 1);
187 test(S("1", A()), 0);
188 test(S("1", A()), 1);
189 test(S("1", A()), 2);
190 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 0);
191 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 5);
192 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50);
193 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 500);
194
195 test(S(A()), 0, 0);
196 test(S(A()), 0, 1);
197 test(S(A()), 1, 0);
198 test(S(A()), 1, 1);
199 test(S(A()), 1, 2);
200 test(S("1", A()), 0, 0);
201 test(S("1", A()), 0, 1);
202 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 0);
203 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1);
204 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10);
205 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100);
206
207 test(S(A()), 0, 0, A());
208 test(S(A()), 0, 1, A());
209 test(S(A()), 1, 0, A());
210 test(S(A()), 1, 1, A());
211 test(S(A()), 1, 2, A());
212 test(S("1", A()), 0, 0, A());
213 test(S("1", A()), 0, 1, A());
214 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 0, A());
215 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1, A());
216 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10, A());
217 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100, A());
218 }
219 #endif
220
221 return true;
222 }
223
main(int,char **)224 int main(int, char**)
225 {
226 test();
227 #if TEST_STD_VER > 17
228 static_assert(test());
229 #endif
230 test_lwg2583();
231
232 return 0;
233 }
234