1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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
15 // basic_string(const basic_string<charT,traits,Allocator>& str,
17 // const Allocator& a = Allocator()); // constexpr since C++20
23 #include <scoped_allocator>
26 #include "test_macros.h"
27 #include "test_allocator.h"
28 #include "min_allocator.h"
29 #include "asan_testing.h"
32 TEST_CONSTEXPR_CXX20
void test(S str
, unsigned pos
) {
33 typedef typename
S::traits_type T
;
34 typedef typename
S::allocator_type A
;
36 if (pos
<= str
.size()) {
38 LIBCPP_ASSERT(s2
.__invariants());
39 typename
S::size_type rlen
= str
.size() - pos
;
40 assert(s2
.size() == rlen
);
41 assert(T::compare(s2
.data(), str
.data() + pos
, rlen
) == 0);
42 assert(s2
.get_allocator() == A());
43 assert(s2
.capacity() >= s2
.size());
44 LIBCPP_ASSERT(is_string_asan_correct(s2
));
46 #ifndef TEST_HAS_NO_EXCEPTIONS
47 else if (!TEST_IS_CONSTANT_EVALUATED
) {
51 } catch (std::out_of_range
&) {
52 assert(pos
> str
.size());
59 TEST_CONSTEXPR_CXX20
void test(S str
, unsigned pos
, unsigned n
) {
60 typedef typename
S::traits_type T
;
61 typedef typename
S::allocator_type A
;
62 if (pos
<= str
.size()) {
64 LIBCPP_ASSERT(s2
.__invariants());
65 typename
S::size_type rlen
= std::min
<typename
S::size_type
>(str
.size() - pos
, n
);
66 assert(s2
.size() == rlen
);
67 assert(T::compare(s2
.data(), str
.data() + pos
, rlen
) == 0);
68 assert(s2
.get_allocator() == A());
69 assert(s2
.capacity() >= s2
.size());
70 LIBCPP_ASSERT(is_string_asan_correct(s2
));
72 #ifndef TEST_HAS_NO_EXCEPTIONS
73 else if (!TEST_IS_CONSTANT_EVALUATED
) {
77 } catch (std::out_of_range
&) {
78 assert(pos
> str
.size());
85 TEST_CONSTEXPR_CXX20
void test(S str
, unsigned pos
, unsigned n
, const typename
S::allocator_type
& a
) {
86 typedef typename
S::traits_type T
;
88 if (pos
<= str
.size()) {
90 LIBCPP_ASSERT(s2
.__invariants());
91 typename
S::size_type rlen
= std::min
<typename
S::size_type
>(str
.size() - pos
, n
);
92 assert(s2
.size() == rlen
);
93 assert(T::compare(s2
.data(), str
.data() + pos
, rlen
) == 0);
94 assert(s2
.get_allocator() == a
);
95 assert(s2
.capacity() >= s2
.size());
96 LIBCPP_ASSERT(is_string_asan_correct(s2
));
98 #ifndef TEST_HAS_NO_EXCEPTIONS
99 else if (!TEST_IS_CONSTANT_EVALUATED
) {
101 S
s2(str
, pos
, n
, a
);
103 } catch (std::out_of_range
&) {
104 assert(pos
> str
.size());
110 void test_lwg2583() {
111 #if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
112 typedef std::basic_string
<char, std::char_traits
<char>, test_allocator
<char> > StringA
;
113 std::vector
<StringA
, std::scoped_allocator_adaptor
<test_allocator
<StringA
> > > vs
;
115 vs
.emplace_back(s
, 2);
118 vs
.emplace_back(s
, 5);
119 } catch (const std::out_of_range
&) {
126 template <class Alloc
>
127 TEST_CONSTEXPR_CXX20
void test_string(const Alloc
& a1
, const Alloc
& a2
) {
128 using S
= std::basic_string
<char, std::char_traits
<char>, Alloc
>;
130 test(S(Alloc(a1
)), 0);
131 test(S(Alloc(a1
)), 1);
132 test(S("1", Alloc(a1
)), 0);
133 test(S("1", Alloc(a1
)), 1);
134 test(S("1", Alloc(a1
)), 2);
135 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 0);
136 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 5);
137 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50);
138 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 500);
140 test(S(Alloc(a1
)), 0, 0);
141 test(S(Alloc(a1
)), 0, 1);
142 test(S(Alloc(a1
)), 1, 0);
143 test(S(Alloc(a1
)), 1, 1);
144 test(S(Alloc(a1
)), 1, 2);
145 test(S("1", Alloc(a1
)), 0, 0);
146 test(S("1", Alloc(a1
)), 0, 1);
147 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 0);
148 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 1);
149 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 10);
150 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 100);
152 test(S(Alloc(a1
)), 0, 0, Alloc(a2
));
153 test(S(Alloc(a1
)), 0, 1, Alloc(a2
));
154 test(S(Alloc(a1
)), 1, 0, Alloc(a2
));
155 test(S(Alloc(a1
)), 1, 1, Alloc(a2
));
156 test(S(Alloc(a1
)), 1, 2, Alloc(a2
));
157 test(S("1", Alloc(a1
)), 0, 0, Alloc(a2
));
158 test(S("1", Alloc(a1
)), 0, 1, Alloc(a2
));
159 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 0, Alloc(a2
));
160 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 1, Alloc(a2
));
161 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 10, Alloc(a2
));
162 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 100, Alloc(a2
));
165 TEST_CONSTEXPR_CXX20
bool test() {
166 test_string(std::allocator
<char>(), std::allocator
<char>());
167 test_string(test_allocator
<char>(), test_allocator
<char>());
168 test_string(test_allocator
<char>(3), test_allocator
<char>(5));
169 #if TEST_STD_VER >= 11
170 test_string(min_allocator
<char>(), min_allocator
<char>());
171 test_string(safe_allocator
<char>(), safe_allocator
<char>());
177 int main(int, char**) {
179 #if TEST_STD_VER > 17
180 static_assert(test());