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