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());
14 //
15 // basic_string(const basic_string<charT,traits,Allocator>& str,
16 // size_type pos,
17 // const Allocator& a = Allocator());
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 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
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 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
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 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
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
127 #if TEST_STD_VER >= 11
128 #ifndef TEST_HAS_NO_EXCEPTIONS
test2583()129 void test2583()
130 { // LWG #2583
131 typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > StringA;
132 std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA>>> vs;
133 StringA s{"1234"};
134 vs.emplace_back(s, 2);
135
136 try { vs.emplace_back(s, 5); }
137 catch (const std::out_of_range&) { return; }
138 assert(false);
139 }
140 #endif
141 #endif
142
main(int,char **)143 int main(int, char**)
144 {
145 {
146 typedef test_allocator<char> A;
147 typedef std::basic_string<char, std::char_traits<char>, A> S;
148
149 test(S(A(3)), 0);
150 test(S(A(3)), 1);
151 test(S("1", A(5)), 0);
152 test(S("1", A(5)), 1);
153 test(S("1", A(5)), 2);
154 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 0);
155 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 5);
156 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50);
157 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 500);
158
159 test(S(A(3)), 0, 0);
160 test(S(A(3)), 0, 1);
161 test(S(A(3)), 1, 0);
162 test(S(A(3)), 1, 1);
163 test(S(A(3)), 1, 2);
164 test(S("1", A(5)), 0, 0);
165 test(S("1", A(5)), 0, 1);
166 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 0);
167 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1);
168 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10);
169 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100);
170
171 test(S(A(3)), 0, 0, A(4));
172 test(S(A(3)), 0, 1, A(4));
173 test(S(A(3)), 1, 0, A(4));
174 test(S(A(3)), 1, 1, A(4));
175 test(S(A(3)), 1, 2, A(4));
176 test(S("1", A(5)), 0, 0, A(6));
177 test(S("1", A(5)), 0, 1, A(6));
178 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 0, A(8));
179 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1, A(8));
180 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10, A(8));
181 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100, A(8));
182 }
183 #if TEST_STD_VER >= 11
184 {
185 typedef min_allocator<char> A;
186 typedef std::basic_string<char, std::char_traits<char>, A> S;
187
188 test(S(A()), 0);
189 test(S(A()), 1);
190 test(S("1", A()), 0);
191 test(S("1", A()), 1);
192 test(S("1", A()), 2);
193 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 0);
194 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 5);
195 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50);
196 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 500);
197
198 test(S(A()), 0, 0);
199 test(S(A()), 0, 1);
200 test(S(A()), 1, 0);
201 test(S(A()), 1, 1);
202 test(S(A()), 1, 2);
203 test(S("1", A()), 0, 0);
204 test(S("1", A()), 0, 1);
205 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 0);
206 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1);
207 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10);
208 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100);
209
210 test(S(A()), 0, 0, A());
211 test(S(A()), 0, 1, A());
212 test(S(A()), 1, 0, A());
213 test(S(A()), 1, 1, A());
214 test(S(A()), 1, 2, A());
215 test(S("1", A()), 0, 0, A());
216 test(S("1", A()), 0, 1, A());
217 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 0, A());
218 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1, A());
219 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10, A());
220 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100, A());
221 }
222
223 #ifndef TEST_HAS_NO_EXCEPTIONS
224 test2583();
225 #endif
226 #endif
227
228 return 0;
229 }
230