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 // template<class _Tp>
12 //   basic_string(const _Tp& __t, size_type __pos, size_type __n,
13 //                const allocator_type& __a = allocator_type()); // constexpr since C++20
14 //
15 //  Mostly we're testing string_view here
16 
17 #include <string>
18 #include <string_view>
19 #include <stdexcept>
20 #include <algorithm>
21 #include <cassert>
22 
23 #include "test_macros.h"
24 #include "test_allocator.h"
25 #include "min_allocator.h"
26 
27 template <class S, class SV>
28 TEST_CONSTEXPR_CXX20 void
test(SV sv,std::size_t pos,std::size_t n)29 test(SV sv, std::size_t pos, std::size_t n)
30 {
31     typedef typename S::traits_type T;
32     typedef typename S::allocator_type A;
33     typedef typename S::size_type Size;
34     if (pos <= sv.size())
35     {
36         S s2(sv, static_cast<Size>(pos), static_cast<Size>(n));
37         LIBCPP_ASSERT(s2.__invariants());
38         assert(pos <= sv.size());
39         std::size_t rlen = std::min(sv.size() - pos, n);
40         assert(s2.size() == rlen);
41         assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
42         assert(s2.get_allocator() == A());
43         assert(s2.capacity() >= s2.size());
44     }
45 #ifndef TEST_HAS_NO_EXCEPTIONS
46     else if (!TEST_IS_CONSTANT_EVALUATED)
47     {
48         try
49         {
50             S s2(sv, static_cast<Size>(pos), static_cast<Size>(n));
51             assert(false);
52         }
53         catch (std::out_of_range&)
54         {
55             assert(pos > sv.size());
56         }
57     }
58 #endif
59 }
60 
61 template <class S, class SV>
62 TEST_CONSTEXPR_CXX20 void
test(SV sv,std::size_t pos,std::size_t n,const typename S::allocator_type & a)63 test(SV sv, std::size_t pos, std::size_t n, const typename S::allocator_type& a)
64 {
65     typedef typename S::traits_type T;
66     typedef typename S::size_type Size;
67     if (pos <= sv.size())
68     {
69         S s2(sv, static_cast<Size>(pos), static_cast<Size>(n), a);
70         LIBCPP_ASSERT(s2.__invariants());
71         assert(pos <= sv.size());
72         std::size_t rlen = std::min(sv.size() - pos, n);
73         assert(s2.size() == rlen);
74         assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
75         assert(s2.get_allocator() == a);
76         assert(s2.capacity() >= s2.size());
77     }
78 #ifndef TEST_HAS_NO_EXCEPTIONS
79     else if (!TEST_IS_CONSTANT_EVALUATED)
80     {
81         try
82         {
83             S s2(sv, static_cast<Size>(pos), static_cast<Size>(n), a);
84             assert(false);
85         }
86         catch (std::out_of_range&)
87         {
88             assert(pos > sv.size());
89         }
90     }
91 #endif
92 }
93 
test()94 TEST_CONSTEXPR_CXX20 bool test() {
95   {
96     typedef test_allocator<char> A;
97     typedef std::basic_string_view<char, std::char_traits<char> > SV;
98     typedef std::basic_string     <char, std::char_traits<char>, A> S;
99 
100     test<S,SV>(SV(), 0, 0);
101     test<S,SV>(SV(), 0, 1);
102     test<S,SV>(SV(), 1, 0);
103     test<S,SV>(SV(), 1, 1);
104     test<S,SV>(SV(), 1, 2);
105     test<S,SV>(SV("1"), 0, 0);
106     test<S,SV>(SV("1"), 0, 1);
107     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50,   0);
108     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50,   1);
109     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50,  10);
110     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100);
111 
112     test<S,SV>(SV(), 0, 0, A(4));
113     test<S,SV>(SV(), 0, 1, A(4));
114     test<S,SV>(SV(), 1, 0, A(4));
115     test<S,SV>(SV(), 1, 1, A(4));
116     test<S,SV>(SV(), 1, 2, A(4));
117     test<S,SV>(SV("1"), 0, 0, A(6));
118     test<S,SV>(SV("1"), 0, 1, A(6));
119     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50,   0, A(8));
120     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50,   1, A(8));
121     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50,  10, A(8));
122     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100, A(8));
123   }
124 
125 #if TEST_STD_VER >= 11
126   {
127     typedef min_allocator<char> A;
128     typedef std::basic_string_view<char, std::char_traits<char> > SV;
129     typedef std::basic_string     <char, std::char_traits<char>, A> S;
130 
131     test<S,SV>(SV(), 0, 0);
132     test<S,SV>(SV(), 0, 1);
133     test<S,SV>(SV(), 1, 0);
134     test<S,SV>(SV(), 1, 1);
135     test<S,SV>(SV(), 1, 2);
136     test<S,SV>(SV("1"), 0, 0);
137     test<S,SV>(SV("1"), 0, 1);
138     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0);
139     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1);
140     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10);
141     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100);
142 
143     test<S,SV>(SV(), 0, 0, A());
144     test<S,SV>(SV(), 0, 1, A());
145     test<S,SV>(SV(), 1, 0, A());
146     test<S,SV>(SV(), 1, 1, A());
147     test<S,SV>(SV(), 1, 2, A());
148     test<S,SV>(SV("1"), 0, 0, A());
149     test<S,SV>(SV("1"), 0, 1, A());
150     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0, A());
151     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1, A());
152     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10, A());
153     test<S,SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100, A());
154   }
155 #endif
156   {
157     typedef std::string S;
158     typedef std::string_view SV;
159     S s = "ABCD";
160     SV sv = "EFGH";
161     char arr[] = "IJKL";
162 
163     S s1("CDEF", 4);    // calls ctor(const char *, len)
164     assert(s1 == "CDEF");
165 
166     S s2("QRST", 0, 3); // calls ctor(string("QRST", pos, len)
167     assert(s2 == "QRS");
168 
169     S s3(sv, 0, std::string::npos);   // calls ctor(T, pos, npos)
170     assert(s3 == sv);
171 
172     S s4(sv, 0, 3);   // calls ctor(T, pos, len)
173     assert(s4 == "EFG");
174 
175     S s5(arr, 0, 2);     // calls ctor(const char *, len)
176     assert(s5 == "IJ");
177 
178     S s6(arr, 0);     // calls ctor(const char *, len)
179     assert(s6 == "");
180 
181     S s7(s.data(), 2);     // calls ctor(const char *, len)
182     assert(s7 == "AB");
183   }
184 
185   return true;
186 }
187 
main(int,char **)188 int main(int, char**)
189 {
190   test();
191 #if TEST_STD_VER > 17
192   static_assert(test());
193 #endif
194 
195   return 0;
196 }
197