xref: /llvm-project/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp (revision 85e9b2687a13d1908aa86d1b89c5ce398a06cd39)
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 TEST_CONSTEXPR_CXX20 void
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
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
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 
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 
141 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 
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