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