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"
31 TEST_CONSTEXPR_CXX20
void test(S str
, unsigned pos
) {
32 typedef typename
S::traits_type T
;
33 typedef typename
S::allocator_type A
;
35 if (pos
<= str
.size()) {
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());
44 #ifndef TEST_HAS_NO_EXCEPTIONS
45 else if (!TEST_IS_CONSTANT_EVALUATED
) {
49 } catch (std::out_of_range
&) {
50 assert(pos
> str
.size());
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()) {
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());
69 #ifndef TEST_HAS_NO_EXCEPTIONS
70 else if (!TEST_IS_CONSTANT_EVALUATED
) {
74 } catch (std::out_of_range
&) {
75 assert(pos
> str
.size());
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
;
85 if (pos
<= str
.size()) {
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());
94 #ifndef TEST_HAS_NO_EXCEPTIONS
95 else if (!TEST_IS_CONSTANT_EVALUATED
) {
99 } catch (std::out_of_range
&) {
100 assert(pos
> str
.size());
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
;
111 vs
.emplace_back(s
, 2);
114 vs
.emplace_back(s
, 5);
115 } catch (const std::out_of_range
&) {
122 template <class Alloc
>
123 TEST_CONSTEXPR_CXX20
void test_string(const Alloc
& a1
, const Alloc
& a2
) {
124 using S
= std::basic_string
<char, std::char_traits
<char>, Alloc
>;
126 test(S(Alloc(a1
)), 0);
127 test(S(Alloc(a1
)), 1);
128 test(S("1", Alloc(a1
)), 0);
129 test(S("1", Alloc(a1
)), 1);
130 test(S("1", Alloc(a1
)), 2);
131 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 0);
132 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 5);
133 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50);
134 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 500);
136 test(S(Alloc(a1
)), 0, 0);
137 test(S(Alloc(a1
)), 0, 1);
138 test(S(Alloc(a1
)), 1, 0);
139 test(S(Alloc(a1
)), 1, 1);
140 test(S(Alloc(a1
)), 1, 2);
141 test(S("1", Alloc(a1
)), 0, 0);
142 test(S("1", Alloc(a1
)), 0, 1);
143 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 0);
144 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 1);
145 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 10);
146 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 100);
148 test(S(Alloc(a1
)), 0, 0, Alloc(a2
));
149 test(S(Alloc(a1
)), 0, 1, Alloc(a2
));
150 test(S(Alloc(a1
)), 1, 0, Alloc(a2
));
151 test(S(Alloc(a1
)), 1, 1, Alloc(a2
));
152 test(S(Alloc(a1
)), 1, 2, Alloc(a2
));
153 test(S("1", Alloc(a1
)), 0, 0, Alloc(a2
));
154 test(S("1", Alloc(a1
)), 0, 1, Alloc(a2
));
155 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 0, Alloc(a2
));
156 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 1, Alloc(a2
));
157 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 10, Alloc(a2
));
158 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1
)), 50, 100, Alloc(a2
));
161 TEST_CONSTEXPR_CXX20
bool test() {
162 test_string(std::allocator
<char>(), std::allocator
<char>());
163 test_string(test_allocator
<char>(), test_allocator
<char>());
164 test_string(test_allocator
<char>(3), test_allocator
<char>(5));
165 #if TEST_STD_VER >= 11
166 test_string(min_allocator
<char>(), min_allocator
<char>());
172 int main(int, char**) {
174 #if TEST_STD_VER > 17
175 static_assert(test());