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