brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · 742d40d Raw
198 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// UNSUPPORTED: c++03, c++11, c++14, c++17, c++209 10// <string_view>11 12//  template <class Range>13//  constexpr basic_string_view(Range&& range);14 15#include <string_view>16#include <array>17#include <cassert>18#include <iterator>19#include <ranges>20#include <type_traits>21#include <vector>22 23#include "make_string.h"24#include "test_iterators.h"25#include "test_range.h"26 27template <class CharT>28constexpr void test() {29  auto data = MAKE_STRING_VIEW(CharT, "test");30  std::array<CharT, 4> arr;31  for (int i = 0; i < 4; ++i) {32    arr[i] = data[i];33  }34  auto sv = std::basic_string_view<CharT>(arr);35 36  ASSERT_SAME_TYPE(decltype(sv), std::basic_string_view<CharT>);37  assert(sv.size() == arr.size());38  assert(sv.data() == arr.data());39}40 41constexpr bool test() {42  test<char>();43#ifndef TEST_HAS_NO_WIDE_CHARACTERS44  test<wchar_t>();45#endif46  test<char8_t>();47  test<char16_t>();48  test<char32_t>();49 50  {51    struct NonConstConversionOperator {52      const char* data_ = "test";53      constexpr const char* begin() const { return data_; }54      constexpr const char* end() const { return data_ + 4; }55      constexpr operator std::basic_string_view<char>() { return "NonConstConversionOp"; }56    };57 58    NonConstConversionOperator nc;59    std::string_view sv = nc;60    assert(sv == "NonConstConversionOp");61    static_assert(!std::is_constructible_v<std::string_view,62                                           const NonConstConversionOperator&>); // conversion operator is non-const63  }64 65  {66    struct ConstConversionOperator {67      const char* data_ = "test";68      constexpr const char* begin() const { return data_; }69      constexpr const char* end() const { return data_ + 4; }70      constexpr operator std::basic_string_view<char>() const { return "ConstConversionOp"; }71    };72    ConstConversionOperator cv;73    std::basic_string_view<char> sv = cv;74    assert(sv == "ConstConversionOp");75  }76 77  struct DeletedConversionOperator {78    const char* data_ = "test";79    constexpr const char* begin() const { return data_; }80    constexpr const char* end() const { return data_ + 4; }81    operator std::basic_string_view<char>() = delete;82  };83 84  struct DeletedConstConversionOperator {85    const char* data_ = "test";86    constexpr const char* begin() const { return data_; }87    constexpr const char* end() const { return data_ + 4; }88    operator std::basic_string_view<char>() const = delete;89  };90 91  static_assert(std::is_constructible_v<std::string_view, DeletedConversionOperator>);92  static_assert(std::is_constructible_v<std::string_view, const DeletedConversionOperator>);93  static_assert(std::is_constructible_v<std::string_view, DeletedConstConversionOperator>);94  static_assert(std::is_constructible_v<std::string_view, const DeletedConstConversionOperator>);95 96  // Test that we're not trying to use the type's conversion operator to string_view in the constructor.97  {98    const DeletedConversionOperator d;99    std::basic_string_view<char> csv = std::basic_string_view<char>(d);100    assert(csv == "test");101  }102 103  {104    DeletedConstConversionOperator dc;105    std::basic_string_view<char> sv = std::basic_string_view<char>(dc);106    assert(sv == "test");107  }108 109  // Different trait types110  {111    struct OtherTraits : std::char_traits<char> {};112    std::basic_string_view<char> sv1{"hello"};113    std::basic_string_view<char, OtherTraits> sv2(sv1);114    assert(sv1.size() == sv2.size());115    assert(sv1.data() == sv2.data());116  }117 118  return true;119}120 121static_assert(std::is_constructible_v<std::string_view, std::vector<char>&>);122static_assert(std::is_constructible_v<std::string_view, const std::vector<char>&>);123static_assert(std::is_constructible_v<std::string_view, std::vector<char>&&>);124static_assert(std::is_constructible_v<std::string_view, const std::vector<char>&&>);125 126using SizedButNotContiguousRange = std::ranges::subrange<random_access_iterator<char*>>;127static_assert(!std::ranges::contiguous_range<SizedButNotContiguousRange>);128static_assert(std::ranges::sized_range<SizedButNotContiguousRange>);129static_assert(!std::is_constructible_v<std::string_view, SizedButNotContiguousRange>);130 131using ContiguousButNotSizedRange =132    std::ranges::subrange<contiguous_iterator<char*>,133                          sentinel_wrapper<contiguous_iterator<char*>>,134                          std::ranges::subrange_kind::unsized>;135static_assert(std::ranges::contiguous_range<ContiguousButNotSizedRange>);136static_assert(!std::ranges::sized_range<ContiguousButNotSizedRange>);137static_assert(!std::is_constructible_v<std::string_view, ContiguousButNotSizedRange>);138 139static_assert(!std::is_constructible_v<std::string_view, std::vector<char16_t>>); // different CharT140 141struct WithStringViewConversionOperator {142  char* begin() const;143  char* end() const;144  operator std::string_view() const { return {}; }145};146 147static_assert(std::is_constructible_v<std::string_view, WithStringViewConversionOperator>);        // lvalue148static_assert(std::is_constructible_v<std::string_view, const WithStringViewConversionOperator&>); // const lvalue149static_assert(std::is_constructible_v<std::string_view, WithStringViewConversionOperator&&>);      // rvalue150 151#ifndef TEST_HAS_NO_EXCEPTIONS152void test_throwing() {153  struct ThrowingData {154    char* begin() const { return nullptr; }155    char* end() const { return nullptr; }156    char* data() const {157      throw 42;158      return nullptr;159    }160  };161  try {162    ThrowingData x;163    (void)std::string_view(x);164    assert(false);165  } catch (int i) {166    assert(i == 42);167  }168 169  struct ThrowingSize {170    char* begin() const { return nullptr; }171    char* end() const { return nullptr; }172    std::size_t size() const {173      throw 42;174      return 0;175    }176  };177  try {178    ThrowingSize x;179    (void)std::string_view(x);180    assert(false);181  } catch (int i) {182    assert(i == 42);183  }184}185#endif186 187static_assert(!std::is_convertible_v<std::vector<char>, std::string_view>);188 189int main(int, char**) {190  test();191  static_assert(test());192#ifndef TEST_HAS_NO_EXCEPTIONS193  test_throwing();194#endif195 196  return 0;197}198