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 //===----------------------------------------------------------------------===//
8 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
12 // template <class Range>
13 // constexpr basic_string_view(Range&& range);
15 #include <string_view>
20 #include <type_traits>
23 #include "make_string.h"
24 #include "test_iterators.h"
25 #include "test_range.h"
27 template <class CharT
>
28 constexpr void test() {
29 auto data
= MAKE_STRING_VIEW(CharT
, "test");
30 std::array
<CharT
, 4> arr
;
31 for (int i
= 0; i
< 4; ++i
) {
34 auto sv
= std::basic_string_view
<CharT
>(arr
);
36 ASSERT_SAME_TYPE(decltype(sv
), std::basic_string_view
<CharT
>);
37 assert(sv
.size() == arr
.size());
38 assert(sv
.data() == arr
.data());
41 constexpr bool test() {
43 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
51 struct NonConstConversionOperator
{
52 const char* data_
= "test";
53 constexpr const char* begin() const { return data_
; }
54 constexpr const char* end() const { return data_
+ 4; }
55 constexpr operator std::basic_string_view
<char>() { return "NonConstConversionOp"; }
58 NonConstConversionOperator nc
;
59 std::string_view sv
= nc
;
60 assert(sv
== "NonConstConversionOp");
61 static_assert(!std::is_constructible_v
<std::string_view
,
62 const NonConstConversionOperator
&>); // conversion operator is non-const
66 struct ConstConversionOperator
{
67 const char* data_
= "test";
68 constexpr const char* begin() const { return data_
; }
69 constexpr const char* end() const { return data_
+ 4; }
70 constexpr operator std::basic_string_view
<char>() const { return "ConstConversionOp"; }
72 ConstConversionOperator cv
;
73 std::basic_string_view
<char> sv
= cv
;
74 assert(sv
== "ConstConversionOp");
77 struct DeletedConversionOperator
{
78 const char* data_
= "test";
79 constexpr const char* begin() const { return data_
; }
80 constexpr const char* end() const { return data_
+ 4; }
81 operator std::basic_string_view
<char>() = delete;
84 struct DeletedConstConversionOperator
{
85 const char* data_
= "test";
86 constexpr const char* begin() const { return data_
; }
87 constexpr const char* end() const { return data_
+ 4; }
88 operator std::basic_string_view
<char>() const = delete;
91 static_assert(std::is_constructible_v
<std::string_view
, DeletedConversionOperator
>);
92 static_assert(std::is_constructible_v
<std::string_view
, const DeletedConversionOperator
>);
93 static_assert(std::is_constructible_v
<std::string_view
, DeletedConstConversionOperator
>);
94 static_assert(std::is_constructible_v
<std::string_view
, const DeletedConstConversionOperator
>);
96 // Test that we're not trying to use the type's conversion operator to string_view in the constructor.
98 const DeletedConversionOperator d
;
99 std::basic_string_view
<char> csv
= std::basic_string_view
<char>(d
);
100 assert(csv
== "test");
104 DeletedConstConversionOperator dc
;
105 std::basic_string_view
<char> sv
= std::basic_string_view
<char>(dc
);
106 assert(sv
== "test");
109 // Different trait types
111 struct OtherTraits
: std::char_traits
<char> {};
112 std::basic_string_view
<char> sv1
{"hello"};
113 std::basic_string_view
<char, OtherTraits
> sv2(sv1
);
114 assert(sv1
.size() == sv2
.size());
115 assert(sv1
.data() == sv2
.data());
121 static_assert(std::is_constructible_v
<std::string_view
, std::vector
<char>&>);
122 static_assert(std::is_constructible_v
<std::string_view
, const std::vector
<char>&>);
123 static_assert(std::is_constructible_v
<std::string_view
, std::vector
<char>&&>);
124 static_assert(std::is_constructible_v
<std::string_view
, const std::vector
<char>&&>);
126 using SizedButNotContiguousRange
= std::ranges::subrange
<random_access_iterator
<char*>>;
127 static_assert(!std::ranges::contiguous_range
<SizedButNotContiguousRange
>);
128 static_assert(std::ranges::sized_range
<SizedButNotContiguousRange
>);
129 static_assert(!std::is_constructible_v
<std::string_view
, SizedButNotContiguousRange
>);
131 using ContiguousButNotSizedRange
=
132 std::ranges::subrange
<contiguous_iterator
<char*>,
133 sentinel_wrapper
<contiguous_iterator
<char*>>,
134 std::ranges::subrange_kind::unsized
>;
135 static_assert(std::ranges::contiguous_range
<ContiguousButNotSizedRange
>);
136 static_assert(!std::ranges::sized_range
<ContiguousButNotSizedRange
>);
137 static_assert(!std::is_constructible_v
<std::string_view
, ContiguousButNotSizedRange
>);
139 static_assert(!std::is_constructible_v
<std::string_view
, std::vector
<char16_t
>>); // different CharT
141 struct WithStringViewConversionOperator
{
144 operator std::string_view() const { return {}; }
147 static_assert(std::is_constructible_v
<std::string_view
, WithStringViewConversionOperator
>); // lvalue
148 static_assert(std::is_constructible_v
<std::string_view
, const WithStringViewConversionOperator
&>); // const lvalue
149 static_assert(std::is_constructible_v
<std::string_view
, WithStringViewConversionOperator
&&>); // rvalue
151 #ifndef TEST_HAS_NO_EXCEPTIONS
152 void test_throwing() {
153 struct ThrowingData
{
154 char* begin() const { return nullptr; }
155 char* end() const { return nullptr; }
163 (void)std::string_view(x
);
169 struct ThrowingSize
{
170 char* begin() const { return nullptr; }
171 char* end() const { return nullptr; }
172 std::size_t size() const {
179 (void)std::string_view(x
);
187 static_assert(!std::is_convertible_v
<std::vector
<char>, std::string_view
>);
189 int main(int, char**) {
191 static_assert(test());
192 #ifndef TEST_HAS_NO_EXCEPTIONS