xref: /llvm-project/libcxx/test/std/strings/string.view/string.view.cons/from_iterator_sentinel.pass.cpp (revision a40bada91aeda276a772acfbcae6e8de26755a11)
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