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 // UNSUPPORTED: c++03, c++11, c++14, c++17
9
10 // <string_view>
11
12 // template <class It, class End>
13 // constexpr basic_string_view(It begin, End end)
14
15 #include <string_view>
16 #include <cassert>
17 #include <iterator>
18
19 #include "make_string.h"
20 #include "test_iterators.h"
21
22 template <class It, class Sentinel, class CharT>
test_construction(std::basic_string_view<CharT> val)23 constexpr void test_construction(std::basic_string_view<CharT> val) {
24 auto sv = std::basic_string_view<CharT>(It(val.data()), Sentinel(It(val.data() + val.size())));
25 assert(sv.data() == val.data());
26 assert(sv.size() == val.size());
27 }
28
29 template <class CharT>
test_with_char()30 constexpr void test_with_char() {
31 const auto val = MAKE_STRING_VIEW(CharT, "test");
32 test_construction<CharT*, CharT*>(val);
33 test_construction<CharT*, const CharT*>(val);
34 test_construction<const CharT*, CharT*>(val);
35 test_construction<const CharT*, sized_sentinel<const CharT*>>(val);
36 test_construction<contiguous_iterator<const CharT*>, contiguous_iterator<const CharT*>>(val);
37 test_construction<contiguous_iterator<const CharT*>, sized_sentinel<contiguous_iterator<const CharT*>>>(val);
38 }
39
test()40 constexpr bool test() {
41 test_with_char<char>();
42 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
43 test_with_char<wchar_t>();
44 #endif
45 test_with_char<char8_t>();
46 test_with_char<char16_t>();
47 test_with_char<char32_t>();
48
49 return true;
50 }
51
52 #ifndef TEST_HAS_NO_EXCEPTIONS
53 template <class CharT>
54 struct ThrowingSentinel {
operator ==(const CharT *,ThrowingSentinel)55 friend bool operator==(const CharT*, ThrowingSentinel) noexcept { return true; }
operator -(const CharT *,ThrowingSentinel)56 friend std::iter_difference_t<const CharT*> operator-(const CharT*, ThrowingSentinel) noexcept { return {}; }
operator -(ThrowingSentinel,const CharT *)57 friend std::iter_difference_t<const CharT*> operator-(ThrowingSentinel, const CharT*) { throw 42; }
58 };
59
60 template <class CharT>
test_throwing()61 void test_throwing() {
62 auto val = MAKE_STRING_VIEW(CharT, "test");
63 try {
64 (void)std::basic_string_view<CharT>(val.data(), ThrowingSentinel<CharT>());
65 assert(false);
66 } catch (int i) {
67 assert(i == 42);
68 }
69 }
70
test_throwing()71 void test_throwing() {
72 test_throwing<char>();
73 # ifndef TEST_HAS_NO_WIDE_CHARACTERS
74 test_throwing<wchar_t>();
75 # endif
76 test_throwing<char8_t>();
77 test_throwing<char16_t>();
78 test_throwing<char32_t>();
79 }
80 #endif
81
82 static_assert(std::is_constructible_v<std::string_view, const char*, char*>);
83 static_assert(std::is_constructible_v<std::string_view, char*, const char*>);
84 static_assert(!std::is_constructible_v<std::string_view, char*, void*>); // not a sentinel
85 static_assert(!std::is_constructible_v<std::string_view, signed char*, signed char*>); // wrong char type
86 static_assert(!std::is_constructible_v<std::string_view,
87 random_access_iterator<char*>,
88 random_access_iterator<char*>>); // not contiguous
89 static_assert(std::is_constructible_v<std::string_view, contiguous_iterator<char*>, contiguous_iterator<char*>>);
90
main(int,char **)91 int main(int, char**) {
92 test();
93 static_assert(test());
94
95 #ifndef TEST_HAS_NO_EXCEPTIONS
96 test_throwing();
97 #endif
98
99 return 0;
100 }
101