14be7f489SJoe Loser //===----------------------------------------------------------------------===//
24be7f489SJoe Loser //
34be7f489SJoe Loser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44be7f489SJoe Loser // See https://llvm.org/LICENSE.txt for license information.
54be7f489SJoe Loser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64be7f489SJoe Loser //
74be7f489SJoe Loser //===----------------------------------------------------------------------===//
84be7f489SJoe Loser // UNSUPPORTED: c++03, c++11, c++14, c++17
94be7f489SJoe Loser 
104be7f489SJoe Loser // <string_view>
114be7f489SJoe Loser 
124be7f489SJoe Loser //  template <class It, class End>
134be7f489SJoe Loser //  constexpr basic_string_view(It begin, End end)
144be7f489SJoe Loser 
154be7f489SJoe Loser #include <string_view>
164be7f489SJoe Loser #include <cassert>
17494dad6bSJoe Loser #include <iterator>
184be7f489SJoe Loser 
194be7f489SJoe Loser #include "make_string.h"
204be7f489SJoe Loser #include "test_iterators.h"
214be7f489SJoe Loser 
22*2d653b7eSCasey Carter template<class It, class Sentinel, class CharT>
test_construction(std::basic_string_view<CharT> val)23*2d653b7eSCasey Carter constexpr void test_construction(std::basic_string_view<CharT> val) {
24*2d653b7eSCasey Carter   auto sv = std::basic_string_view<CharT>(It(val.data()), Sentinel(It(val.data() + val.size())));
254be7f489SJoe Loser   assert(sv.data() == val.data());
26*2d653b7eSCasey Carter   assert(sv.size() == val.size());
27*2d653b7eSCasey Carter }
28*2d653b7eSCasey Carter 
29*2d653b7eSCasey Carter template<class CharT>
test_with_char()30*2d653b7eSCasey Carter constexpr void test_with_char() {
31*2d653b7eSCasey Carter   const auto val = MAKE_STRING_VIEW(CharT, "test");
32*2d653b7eSCasey Carter   test_construction<CharT*, CharT*>(val);
33*2d653b7eSCasey Carter   test_construction<CharT*, const CharT*>(val);
34*2d653b7eSCasey Carter   test_construction<const CharT*, CharT*>(val);
35*2d653b7eSCasey Carter   test_construction<const CharT*, sized_sentinel<const CharT*>>(val);
36*2d653b7eSCasey Carter   test_construction<contiguous_iterator<const CharT*>, contiguous_iterator<const CharT*>>(val);
37*2d653b7eSCasey Carter   test_construction<contiguous_iterator<const CharT*>, sized_sentinel<contiguous_iterator<const CharT*>>>(val);
384be7f489SJoe Loser }
394be7f489SJoe Loser 
test()404be7f489SJoe Loser constexpr bool test() {
41*2d653b7eSCasey Carter   test_with_char<char>();
42f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
43*2d653b7eSCasey Carter   test_with_char<wchar_t>();
44f4c1258dSLouis Dionne #endif
45*2d653b7eSCasey Carter   test_with_char<char8_t>();
46*2d653b7eSCasey Carter   test_with_char<char16_t>();
47*2d653b7eSCasey Carter   test_with_char<char32_t>();
48*2d653b7eSCasey Carter 
494be7f489SJoe Loser   return true;
504be7f489SJoe Loser }
514be7f489SJoe Loser 
52494dad6bSJoe Loser #ifndef TEST_HAS_NO_EXCEPTIONS
53494dad6bSJoe Loser template<class CharT>
54494dad6bSJoe Loser struct ThrowingSentinel {
operator ==(const CharT *,ThrowingSentinel)55494dad6bSJoe Loser   friend bool operator==(const CharT*, ThrowingSentinel) noexcept { return true; }
operator -(const CharT *,ThrowingSentinel)56494dad6bSJoe Loser   friend std::iter_difference_t<const CharT*> operator-(const CharT*, ThrowingSentinel) noexcept { return {}; }
operator -(ThrowingSentinel,const CharT *)57494dad6bSJoe Loser   friend std::iter_difference_t<const CharT*> operator-(ThrowingSentinel, const CharT*) { throw 42; }
58494dad6bSJoe Loser };
59494dad6bSJoe Loser 
60494dad6bSJoe Loser template <class CharT>
test_throwing()61494dad6bSJoe Loser void test_throwing() {
62494dad6bSJoe Loser   auto val = MAKE_STRING_VIEW(CharT, "test");
63494dad6bSJoe Loser   try {
64*2d653b7eSCasey Carter     (void)std::basic_string_view<CharT>(val.data(), ThrowingSentinel<CharT>());
65494dad6bSJoe Loser     assert(false);
66494dad6bSJoe Loser   } catch (int i) {
67494dad6bSJoe Loser     assert(i == 42);
68494dad6bSJoe Loser   }
69494dad6bSJoe Loser }
70494dad6bSJoe Loser 
test_throwing()71494dad6bSJoe Loser void test_throwing() {
72494dad6bSJoe Loser   test_throwing<char>();
73494dad6bSJoe Loser #ifndef TEST_HAS_NO_WIDE_CHARACTERS
74494dad6bSJoe Loser   test_throwing<wchar_t>();
75494dad6bSJoe Loser #endif
76494dad6bSJoe Loser   test_throwing<char8_t>();
77494dad6bSJoe Loser   test_throwing<char16_t>();
78494dad6bSJoe Loser   test_throwing<char32_t>();
79494dad6bSJoe Loser }
80494dad6bSJoe Loser #endif
81494dad6bSJoe Loser 
824be7f489SJoe Loser static_assert( std::is_constructible_v<std::string_view, const char*, char*>);
834be7f489SJoe Loser static_assert( std::is_constructible_v<std::string_view, char*, const char*>);
844be7f489SJoe Loser static_assert(!std::is_constructible_v<std::string_view, char*, void*>);               // not a sentinel
854be7f489SJoe Loser static_assert(!std::is_constructible_v<std::string_view, signed char*, signed char*>); // wrong char type
864be7f489SJoe Loser static_assert(!std::is_constructible_v<std::string_view, random_access_iterator<char*>, random_access_iterator<char*>>); // not contiguous
874be7f489SJoe Loser static_assert( std::is_constructible_v<std::string_view, contiguous_iterator<char*>, contiguous_iterator<char*>>);
884be7f489SJoe Loser 
main(int,char **)894be7f489SJoe Loser int main(int, char**) {
904be7f489SJoe Loser   test();
914be7f489SJoe Loser   static_assert(test());
924be7f489SJoe Loser 
93494dad6bSJoe Loser #ifndef TEST_HAS_NO_EXCEPTIONS
94494dad6bSJoe Loser   test_throwing();
95494dad6bSJoe Loser #endif
96494dad6bSJoe Loser 
974be7f489SJoe Loser   return 0;
984be7f489SJoe Loser }
99