xref: /llvm-project/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp (revision 9ed20568e7de53dce85f1631d7d8c1415e7930ae)
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 #include "asan_testing.h"
27 
28 template <class S, class SV>
test(SV sv,std::size_t pos,std::size_t n)29 TEST_CONSTEXPR_CXX20 void test(SV sv, std::size_t pos, std::size_t n) {
30   typedef typename S::traits_type T;
31   typedef typename S::allocator_type A;
32   typedef typename S::size_type Size;
33   if (pos <= sv.size()) {
34     S s2(sv, static_cast<Size>(pos), static_cast<Size>(n));
35     LIBCPP_ASSERT(s2.__invariants());
36     assert(pos <= sv.size());
37     std::size_t rlen = std::min(sv.size() - pos, n);
38     assert(s2.size() == rlen);
39     assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
40     assert(s2.get_allocator() == A());
41     assert(s2.capacity() >= s2.size());
42     LIBCPP_ASSERT(is_string_asan_correct(s2));
43   }
44 #ifndef TEST_HAS_NO_EXCEPTIONS
45   else if (!TEST_IS_CONSTANT_EVALUATED) {
46     try {
47       S s2(sv, static_cast<Size>(pos), static_cast<Size>(n));
48       assert(false);
49     } catch (std::out_of_range&) {
50       assert(pos > sv.size());
51     }
52   }
53 #endif
54 }
55 
56 template <class S, class SV>
test(SV sv,std::size_t pos,std::size_t n,const typename S::allocator_type & a)57 TEST_CONSTEXPR_CXX20 void test(SV sv, std::size_t pos, std::size_t n, const typename S::allocator_type& a) {
58   typedef typename S::traits_type T;
59   typedef typename S::size_type Size;
60   if (pos <= sv.size()) {
61     S s2(sv, static_cast<Size>(pos), static_cast<Size>(n), a);
62     LIBCPP_ASSERT(s2.__invariants());
63     assert(pos <= sv.size());
64     std::size_t rlen = std::min(sv.size() - pos, n);
65     assert(s2.size() == rlen);
66     assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
67     assert(s2.get_allocator() == a);
68     assert(s2.capacity() >= s2.size());
69   }
70 #ifndef TEST_HAS_NO_EXCEPTIONS
71   else if (!TEST_IS_CONSTANT_EVALUATED) {
72     try {
73       S s2(sv, static_cast<Size>(pos), static_cast<Size>(n), a);
74       assert(false);
75     } catch (std::out_of_range&) {
76       assert(pos > sv.size());
77     }
78   }
79 #endif
80 }
81 
82 template <class Alloc>
test_string(const Alloc & a)83 TEST_CONSTEXPR_CXX20 void test_string(const Alloc& a) {
84   typedef std::basic_string_view<char, std::char_traits<char> > SV;
85   typedef std::basic_string<char, std::char_traits<char>, Alloc> S;
86 
87   test<S, SV>(SV(), 0, 0);
88   test<S, SV>(SV(), 0, 1);
89   test<S, SV>(SV(), 1, 0);
90   test<S, SV>(SV(), 1, 1);
91   test<S, SV>(SV(), 1, 2);
92   test<S, SV>(SV("1"), 0, 0);
93   test<S, SV>(SV("1"), 0, 1);
94   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0);
95   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1);
96   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10);
97   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100);
98 
99   test<S, SV>(SV(), 0, 0, Alloc(a));
100   test<S, SV>(SV(), 0, 1, Alloc(a));
101   test<S, SV>(SV(), 1, 0, Alloc(a));
102   test<S, SV>(SV(), 1, 1, Alloc(a));
103   test<S, SV>(SV(), 1, 2, Alloc(a));
104   test<S, SV>(SV("1"), 0, 0, Alloc(a));
105   test<S, SV>(SV("1"), 0, 1, Alloc(a));
106   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 0, Alloc(a));
107   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 1, Alloc(a));
108   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 10, Alloc(a));
109   test<S, SV>(SV("1234567890123456789012345678901234567890123456789012345678901234567890"), 50, 100, Alloc(a));
110 }
111 
test()112 TEST_CONSTEXPR_CXX20 bool test() {
113   test_string(std::allocator<char>());
114   test_string(test_allocator<char>());
115   test_string(test_allocator<char>(8));
116 #if TEST_STD_VER >= 11
117   test_string(min_allocator<char>());
118   test_string(safe_allocator<char>());
119 #endif
120 
121   {
122     typedef std::string S;
123     typedef std::string_view SV;
124     S s        = "ABCD";
125     SV sv      = "EFGH";
126     char arr[] = "IJKL";
127 
128     S s1("CDEF", 4); // calls ctor(const char *, len)
129     assert(s1 == "CDEF");
130 
131     S s2("QRST", 0, 3); // calls ctor(string("QRST", pos, len)
132     assert(s2 == "QRS");
133 
134     S s3(sv, 0, std::string::npos); // calls ctor(T, pos, npos)
135     assert(s3 == sv);
136 
137     S s4(sv, 0, 3); // calls ctor(T, pos, len)
138     assert(s4 == "EFG");
139 
140     S s5(arr, 0, 2); // calls ctor(const char *, len)
141     assert(s5 == "IJ");
142 
143     S s6(arr, 0); // calls ctor(const char *, len)
144     assert(s6 == "");
145 
146     S s7(s.data(), 2); // calls ctor(const char *, len)
147     assert(s7 == "AB");
148   }
149 
150   return true;
151 }
152 
main(int,char **)153 int main(int, char**) {
154   test();
155 #if TEST_STD_VER > 17
156   static_assert(test());
157 #endif
158 
159   return 0;
160 }
161