124 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: std-at-least-c++2610 11// <string>12 13// constexpr basic_string_view<charT, traits> subview(size_type pos = 0,14// size_type n = npos) const;15 16#include <cassert>17#include <concepts>18#include <string>19#include <string_view>20#include <utility>21 22#include "constexpr_char_traits.h"23#include "make_string.h"24#include "min_allocator.h"25#include "test_allocator.h"26#include "test_macros.h"27#include "type_algorithms.h"28 29#define CS(S) MAKE_CSTRING(CharT, S)30 31template <typename CharT, typename TraitsT, typename AllocT>32constexpr void test() {33 std::basic_string<CharT, TraitsT, AllocT> s{CS("Hello cruel world!"), AllocT{}};34 35 { // With a default position and a character length.36 37 // Also check if subview() is a const-qualified.38 assert(std::as_const(s).subview() == CS("Hello cruel world!"));39 40 // Check it the return type of subview() is correct.41 std::same_as<std::basic_string_view<CharT, TraitsT>> decltype(auto) sv = s.subview();42 assert(sv == CS("Hello cruel world!"));43 }44 45 { // Check with different position and length.46 47 // With a explict position and a character length.48 assert(s.subview(6, 5) == CS("cruel"));49 50 // From the beginning of the string with a explicit character length.51 assert(s.subview(0, 5) == CS("Hello"));52 53 // To the end of string with the default character length.54 assert(s.subview(12) == CS("world!"));55 56 // From the beginning to the end of the string with explicit values.57 assert(s.subview(0, s.size()) == CS("Hello cruel world!"));58 }59 60 // Test if exceptions are thrown correctly.61#ifndef TEST_HAS_NO_EXCEPTIONS62 if (!std::is_constant_evaluated()) {63 { // With a position that is out of range.64 try {65 std::ignore = s.subview(s.size() + 1);66 assert(false);67 } catch ([[maybe_unused]] const std::out_of_range& ex) {68 LIBCPP_ASSERT(std::string(ex.what()) == "string_view::substr");69 } catch (...) {70 assert(false);71 }72 }73 74 { // With a position that is out of range and a 0 character length.75 try {76 std::ignore = s.subview(s.size() + 1, 0);77 assert(false);78 } catch ([[maybe_unused]] const std::out_of_range& ex) {79 LIBCPP_ASSERT(std::string(ex.what()) == "string_view::substr");80 } catch (...) {81 assert(false);82 }83 }84 85 { // With a position that is out of range and a some character length.86 try {87 std::ignore = s.subview(s.size() + 1, 1);88 assert(false);89 } catch ([[maybe_unused]] const std::out_of_range& ex) {90 LIBCPP_ASSERT(std::string(ex.what()) == "string_view::substr");91 } catch (...) {92 assert(false);93 }94 }95 }96#endif97}98 99template <typename CharT>100constexpr void test() {101 test<CharT, std::char_traits<CharT>, std::allocator<CharT>>();102 test<CharT, std::char_traits<CharT>, min_allocator<CharT>>();103 test<CharT, std::char_traits<CharT>, safe_allocator<CharT>>();104 test<CharT, std::char_traits<CharT>, test_allocator<CharT>>();105 106 test<CharT, constexpr_char_traits<CharT>, std::allocator<CharT>>();107 test<CharT, constexpr_char_traits<CharT>, min_allocator<CharT>>();108 test<CharT, constexpr_char_traits<CharT>, safe_allocator<CharT>>();109 test<CharT, constexpr_char_traits<CharT>, test_allocator<CharT>>();110}111 112constexpr bool test() {113 types::for_each(types::character_types(), []<typename CharT> { test<CharT>(); });114 115 return true;116}117 118int main(int, char**) {119 test();120 static_assert(test());121 122 return 0;123}124