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