1c16b13ebSJoe Loser //===----------------------------------------------------------------------===//
2c16b13ebSJoe Loser //
3c16b13ebSJoe Loser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c16b13ebSJoe Loser // See https://llvm.org/LICENSE.txt for license information.
5c16b13ebSJoe Loser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c16b13ebSJoe Loser //
7c16b13ebSJoe Loser //===----------------------------------------------------------------------===//
8c16b13ebSJoe Loser // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9c16b13ebSJoe Loser // UNSUPPORTED: libcpp-has-no-incomplete-ranges
10c16b13ebSJoe Loser
11c16b13ebSJoe Loser // <string_view>
12c16b13ebSJoe Loser
13c16b13ebSJoe Loser // template <class Range>
14c16b13ebSJoe Loser // constexpr basic_string_view(Range&& range);
15c16b13ebSJoe Loser
16c16b13ebSJoe Loser #include <string_view>
17c16b13ebSJoe Loser #include <array>
18c16b13ebSJoe Loser #include <cassert>
19c16b13ebSJoe Loser #include <iterator>
20c16b13ebSJoe Loser #include <ranges>
21c16b13ebSJoe Loser #include <type_traits>
22c16b13ebSJoe Loser #include <vector>
23c16b13ebSJoe Loser
24c16b13ebSJoe Loser #include "constexpr_char_traits.h"
25c16b13ebSJoe Loser #include "make_string.h"
26c16b13ebSJoe Loser #include "test_iterators.h"
27c16b13ebSJoe Loser #include "test_range.h"
28c16b13ebSJoe Loser
29c16b13ebSJoe Loser template<class CharT>
test()30c16b13ebSJoe Loser constexpr void test() {
31c16b13ebSJoe Loser auto data = MAKE_STRING_VIEW(CharT, "test");
32c16b13ebSJoe Loser std::array<CharT, 4> arr;
33c16b13ebSJoe Loser for(int i = 0; i < 4; ++i) {
34c16b13ebSJoe Loser arr[i] = data[i];
35c16b13ebSJoe Loser }
36c16b13ebSJoe Loser auto sv = std::basic_string_view<CharT>(arr);
37c16b13ebSJoe Loser
38c16b13ebSJoe Loser ASSERT_SAME_TYPE(decltype(sv), std::basic_string_view<CharT>);
39c16b13ebSJoe Loser assert(sv.size() == arr.size());
40c16b13ebSJoe Loser assert(sv.data() == arr.data());
41c16b13ebSJoe Loser }
42c16b13ebSJoe Loser
test()43c16b13ebSJoe Loser constexpr bool test() {
44c16b13ebSJoe Loser test<char>();
45c16b13ebSJoe Loser #ifndef TEST_HAS_NO_WIDE_CHARACTERS
46c16b13ebSJoe Loser test<wchar_t>();
47c16b13ebSJoe Loser #endif
48c16b13ebSJoe Loser test<char8_t>();
49c16b13ebSJoe Loser test<char16_t>();
50c16b13ebSJoe Loser test<char32_t>();
51c16b13ebSJoe Loser
52c16b13ebSJoe Loser {
53c16b13ebSJoe Loser struct NonConstConversionOperator {
54c16b13ebSJoe Loser const char* data_ = "test";
55c16b13ebSJoe Loser constexpr const char* begin() const { return data_; }
56c16b13ebSJoe Loser constexpr const char* end() const { return data_ + 4; }
57c16b13ebSJoe Loser constexpr operator std::basic_string_view<char>() { return "NonConstConversionOp"; }
58c16b13ebSJoe Loser };
59c16b13ebSJoe Loser
60c16b13ebSJoe Loser NonConstConversionOperator nc;
61c16b13ebSJoe Loser std::string_view sv = nc;
62c16b13ebSJoe Loser assert(sv == "NonConstConversionOp");
63c16b13ebSJoe Loser static_assert(!std::is_constructible_v<std::string_view,
64c16b13ebSJoe Loser const NonConstConversionOperator&>); // conversion operator is non-const
65c16b13ebSJoe Loser }
66c16b13ebSJoe Loser
67c16b13ebSJoe Loser {
68c16b13ebSJoe Loser struct ConstConversionOperator {
69c16b13ebSJoe Loser const char* data_ = "test";
70c16b13ebSJoe Loser constexpr const char* begin() const { return data_; }
71c16b13ebSJoe Loser constexpr const char* end() const { return data_ + 4; }
72c16b13ebSJoe Loser constexpr operator std::basic_string_view<char>() const { return "ConstConversionOp"; }
73c16b13ebSJoe Loser };
74c16b13ebSJoe Loser ConstConversionOperator cv;
75c16b13ebSJoe Loser std::basic_string_view<char> sv = cv;
76c16b13ebSJoe Loser assert(sv == "ConstConversionOp");
77c16b13ebSJoe Loser }
78c16b13ebSJoe Loser
79c16b13ebSJoe Loser struct DeletedConversionOperator {
80c16b13ebSJoe Loser const char* data_ = "test";
81c16b13ebSJoe Loser constexpr const char* begin() const { return data_; }
82c16b13ebSJoe Loser constexpr const char* end() const { return data_ + 4; }
83c16b13ebSJoe Loser operator std::basic_string_view<char>() = delete;
84c16b13ebSJoe Loser };
85c16b13ebSJoe Loser
86c16b13ebSJoe Loser struct DeletedConstConversionOperator {
87c16b13ebSJoe Loser const char* data_ = "test";
88c16b13ebSJoe Loser constexpr const char* begin() const { return data_; }
89c16b13ebSJoe Loser constexpr const char* end() const { return data_ + 4; }
90c16b13ebSJoe Loser operator std::basic_string_view<char>() const = delete;
91c16b13ebSJoe Loser };
92c16b13ebSJoe Loser
93c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, DeletedConversionOperator>);
94c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, const DeletedConversionOperator>);
95c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, DeletedConstConversionOperator>);
96c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, const DeletedConstConversionOperator>);
97c16b13ebSJoe Loser
98c16b13ebSJoe Loser // Test that we're not trying to use the type's conversion operator to string_view in the constructor.
99c16b13ebSJoe Loser {
100c16b13ebSJoe Loser const DeletedConversionOperator d;
101c16b13ebSJoe Loser std::basic_string_view<char> csv = d;
102c16b13ebSJoe Loser assert(csv == "test");
103c16b13ebSJoe Loser }
104c16b13ebSJoe Loser
105c16b13ebSJoe Loser {
106c16b13ebSJoe Loser DeletedConstConversionOperator dc;
107c16b13ebSJoe Loser std::basic_string_view<char> sv = dc;
108c16b13ebSJoe Loser assert(sv == "test");
109c16b13ebSJoe Loser }
110c16b13ebSJoe Loser
111c16b13ebSJoe Loser return true;
112c16b13ebSJoe Loser }
113c16b13ebSJoe Loser
114c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, std::vector<char>&>);
115c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, const std::vector<char>&>);
116c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, std::vector<char>&&>);
117c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, const std::vector<char>&&>);
118c16b13ebSJoe Loser
119c16b13ebSJoe Loser using SizedButNotContiguousRange = std::ranges::subrange<random_access_iterator<char*>>;
120c16b13ebSJoe Loser static_assert(!std::ranges::contiguous_range<SizedButNotContiguousRange>);
121c16b13ebSJoe Loser static_assert(std::ranges::sized_range<SizedButNotContiguousRange>);
122c16b13ebSJoe Loser static_assert(!std::is_constructible_v<std::string_view, SizedButNotContiguousRange>);
123c16b13ebSJoe Loser
124*2a04deccSArthur O'Dwyer using ContiguousButNotSizedRange = std::ranges::subrange<contiguous_iterator<char*>, sentinel_wrapper<contiguous_iterator<char*>>, std::ranges::subrange_kind::unsized>;
125c16b13ebSJoe Loser static_assert(std::ranges::contiguous_range<ContiguousButNotSizedRange>);
126c16b13ebSJoe Loser static_assert(!std::ranges::sized_range<ContiguousButNotSizedRange>);
127c16b13ebSJoe Loser static_assert(!std::is_constructible_v<std::string_view, ContiguousButNotSizedRange>);
128c16b13ebSJoe Loser
129c16b13ebSJoe Loser static_assert(!std::is_constructible_v<std::string_view, std::vector<char16_t>>); // different CharT
130c16b13ebSJoe Loser
131c16b13ebSJoe Loser struct WithStringViewConversionOperator {
132c16b13ebSJoe Loser char* begin() const;
133c16b13ebSJoe Loser char* end() const;
operator std::string_viewWithStringViewConversionOperator134c16b13ebSJoe Loser operator std::string_view() const { return {}; }
135c16b13ebSJoe Loser };
136c16b13ebSJoe Loser
137c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, WithStringViewConversionOperator>); // lvalue
138c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, const WithStringViewConversionOperator&>); // const lvalue
139c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, WithStringViewConversionOperator&&>); // rvalue
140c16b13ebSJoe Loser
141c16b13ebSJoe Loser template <class CharTraits>
142c16b13ebSJoe Loser struct WithTraitsType {
143c16b13ebSJoe Loser typename CharTraits::char_type* begin() const;
144c16b13ebSJoe Loser typename CharTraits::char_type* end() const;
145c16b13ebSJoe Loser using traits_type = CharTraits;
146c16b13ebSJoe Loser };
147c16b13ebSJoe Loser
148c16b13ebSJoe Loser using CCT = constexpr_char_traits<char>;
149c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::string_view, WithTraitsType<std::char_traits<char>>>);
150c16b13ebSJoe Loser #ifndef TEST_HAS_NO_WIDE_CHARACTERS
151c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::wstring_view, WithTraitsType<std::char_traits<wchar_t>>>);
152c16b13ebSJoe Loser #endif
153c16b13ebSJoe Loser static_assert(std::is_constructible_v<std::basic_string_view<char, CCT>, WithTraitsType<CCT>>);
154c16b13ebSJoe Loser static_assert(!std::is_constructible_v<std::string_view, WithTraitsType<CCT>>); // wrong traits type
155c16b13ebSJoe Loser #ifndef TEST_HAS_NO_WIDE_CHARACTERS
156c16b13ebSJoe Loser static_assert(!std::is_constructible_v<std::wstring_view, WithTraitsType<std::char_traits<char>>>); // wrong traits type
157c16b13ebSJoe Loser #endif
158c16b13ebSJoe Loser
159c16b13ebSJoe Loser #ifndef TEST_HAS_NO_EXCEPTIONS
test_throwing()160c16b13ebSJoe Loser void test_throwing() {
161c16b13ebSJoe Loser struct ThrowingData {
162c16b13ebSJoe Loser char* begin() const { return nullptr; }
163c16b13ebSJoe Loser char* end() const { return nullptr; }
164c16b13ebSJoe Loser char* data() const { throw 42; return nullptr; }
165c16b13ebSJoe Loser };
166c16b13ebSJoe Loser try {
167c16b13ebSJoe Loser ThrowingData x;
168c16b13ebSJoe Loser (void) std::string_view(x);
169c16b13ebSJoe Loser assert(false);
170c16b13ebSJoe Loser } catch (int i) {
171c16b13ebSJoe Loser assert(i == 42);
172c16b13ebSJoe Loser }
173c16b13ebSJoe Loser
174c16b13ebSJoe Loser struct ThrowingSize {
175c16b13ebSJoe Loser char* begin() const { return nullptr; }
176c16b13ebSJoe Loser char* end() const { return nullptr; }
177c16b13ebSJoe Loser size_t size() const { throw 42; return 0; }
178c16b13ebSJoe Loser };
179c16b13ebSJoe Loser try {
180c16b13ebSJoe Loser ThrowingSize x;
181c16b13ebSJoe Loser (void) std::string_view(x);
182c16b13ebSJoe Loser assert(false);
183c16b13ebSJoe Loser } catch (int i) {
184c16b13ebSJoe Loser assert(i == 42);
185c16b13ebSJoe Loser }
186c16b13ebSJoe Loser }
187c16b13ebSJoe Loser #endif
188c16b13ebSJoe Loser
main(int,char **)189c16b13ebSJoe Loser int main(int, char**) {
190c16b13ebSJoe Loser test();
191c16b13ebSJoe Loser static_assert(test());
192c16b13ebSJoe Loser #ifndef TEST_HAS_NO_EXCEPTIONS
193c16b13ebSJoe Loser test_throwing();
194c16b13ebSJoe Loser #endif
195c16b13ebSJoe Loser
196c16b13ebSJoe Loser return 0;
197c16b13ebSJoe Loser }
198c16b13ebSJoe Loser
199