xref: /llvm-project/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp (revision e96f8b52d92ee7d1d13a7a0e1f22a15c2bc52f5b)
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // XFAIL: libcpp-no-exceptions
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());
16 //
17 // basic_string(const basic_string<charT,traits,Allocator>& str,
18 //              size_type pos,
19 //              const Allocator& a = Allocator());
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 void
34 test(S str, unsigned pos)
35 {
36     typedef typename S::traits_type T;
37     typedef typename S::allocator_type A;
38     try
39     {
40         S s2(str, pos);
41         assert(s2.__invariants());
42         assert(pos <= str.size());
43         unsigned 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     catch (std::out_of_range&)
50     {
51         assert(pos > str.size());
52     }
53 }
54 
55 template <class S>
56 void
57 test(S str, unsigned pos, unsigned n)
58 {
59     typedef typename S::traits_type T;
60     typedef typename S::allocator_type A;
61     try
62     {
63         S s2(str, pos, n);
64         assert(s2.__invariants());
65         assert(pos <= str.size());
66         unsigned rlen = std::min<unsigned>(str.size() - pos, n);
67         assert(s2.size() == rlen);
68         assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
69         assert(s2.get_allocator() == A());
70         assert(s2.capacity() >= s2.size());
71     }
72     catch (std::out_of_range&)
73     {
74         assert(pos > str.size());
75     }
76 }
77 
78 template <class S>
79 void
80 test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a)
81 {
82     typedef typename S::traits_type T;
83     typedef typename S::allocator_type A;
84     try
85     {
86         S s2(str, pos, n, a);
87         assert(s2.__invariants());
88         assert(pos <= str.size());
89         unsigned rlen = std::min<unsigned>(str.size() - pos, n);
90         assert(s2.size() == rlen);
91         assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
92         assert(s2.get_allocator() == a);
93         assert(s2.capacity() >= s2.size());
94     }
95     catch (std::out_of_range&)
96     {
97         assert(pos > str.size());
98     }
99 }
100 
101 #if TEST_STD_VER >= 11
102 void test2583()
103 {   // LWG #2583
104     typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > StringA;
105     std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA>>> vs;
106     StringA s{"1234"};
107     vs.emplace_back(s, 2);
108 
109     try { vs.emplace_back(s, 5); }
110     catch (const std::out_of_range&) { return; }
111     assert(false);
112 }
113 #endif
114 
115 int main()
116 {
117     {
118     typedef test_allocator<char> A;
119     typedef std::basic_string<char, std::char_traits<char>, A> S;
120 
121     test(S(A(3)), 0);
122     test(S(A(3)), 1);
123     test(S("1", A(5)), 0);
124     test(S("1", A(5)), 1);
125     test(S("1", A(5)), 2);
126     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 0);
127     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 5);
128     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50);
129     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 500);
130 
131     test(S(A(3)), 0, 0);
132     test(S(A(3)), 0, 1);
133     test(S(A(3)), 1, 0);
134     test(S(A(3)), 1, 1);
135     test(S(A(3)), 1, 2);
136     test(S("1", A(5)), 0, 0);
137     test(S("1", A(5)), 0, 1);
138     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 0);
139     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1);
140     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10);
141     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100);
142 
143     test(S(A(3)), 0, 0, A(4));
144     test(S(A(3)), 0, 1, A(4));
145     test(S(A(3)), 1, 0, A(4));
146     test(S(A(3)), 1, 1, A(4));
147     test(S(A(3)), 1, 2, A(4));
148     test(S("1", A(5)), 0, 0, A(6));
149     test(S("1", A(5)), 0, 1, A(6));
150     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 0, A(8));
151     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1, A(8));
152     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10, A(8));
153     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100, A(8));
154     }
155 #if TEST_STD_VER >= 11
156     {
157     typedef min_allocator<char> A;
158     typedef std::basic_string<char, std::char_traits<char>, A> S;
159 
160     test(S(A()), 0);
161     test(S(A()), 1);
162     test(S("1", A()), 0);
163     test(S("1", A()), 1);
164     test(S("1", A()), 2);
165     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 0);
166     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 5);
167     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50);
168     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 500);
169 
170     test(S(A()), 0, 0);
171     test(S(A()), 0, 1);
172     test(S(A()), 1, 0);
173     test(S(A()), 1, 1);
174     test(S(A()), 1, 2);
175     test(S("1", A()), 0, 0);
176     test(S("1", A()), 0, 1);
177     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 0);
178     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1);
179     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10);
180     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100);
181 
182     test(S(A()), 0, 0, A());
183     test(S(A()), 0, 1, A());
184     test(S(A()), 1, 0, A());
185     test(S(A()), 1, 1, A());
186     test(S(A()), 1, 2, A());
187     test(S("1", A()), 0, 0, A());
188     test(S("1", A()), 0, 1, A());
189     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 0, A());
190     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1, A());
191     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10, A());
192     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100, A());
193     }
194 
195     test2583();
196 #endif
197 }
198