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