brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · c08e996 Raw
126 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// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// constexpr View base() const& requires copy_constructible<_View>;12// constexpr View base() &&;13 14#include <ranges>15 16#include <cassert>17#include <string_view>18#include <utility>19#include "types.h"20 21struct MoveOnlyView : std::ranges::view_base {22  std::string_view view_;23  constexpr MoveOnlyView() = default;24  constexpr MoveOnlyView(const char* ptr) : view_(ptr) {}25  constexpr MoveOnlyView(std::string_view v) : view_(v) {}26  constexpr MoveOnlyView(MoveOnlyView&&) = default;27  constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default;28  constexpr std::string_view::const_iterator begin() const { return view_.begin(); }29  constexpr std::string_view::const_iterator end() const { return view_.end(); }30  constexpr bool operator==(MoveOnlyView rhs) const { return view_ == rhs.view_; }31};32static_assert( std::ranges::view<MoveOnlyView>);33static_assert( std::ranges::contiguous_range<MoveOnlyView>);34static_assert(!std::copyable<MoveOnlyView>);35 36struct ViewWithInitTracking : std::ranges::view_base {37  enum class InitializedBy {38    Copy,39    Move,40    Invalid41  };42 43  std::string_view v_;44  InitializedBy initialized_by = InitializedBy::Invalid;45  constexpr ViewWithInitTracking(std::string_view v) : v_(v) {}46 47  constexpr auto begin() const { return v_.begin(); }48  constexpr auto end() const { return v_.end(); }49 50  constexpr ViewWithInitTracking(const ViewWithInitTracking& rhs) : v_(rhs.v_) { initialized_by = InitializedBy::Copy; }51  constexpr ViewWithInitTracking(ViewWithInitTracking&& rhs) : v_(rhs.v_) { initialized_by = InitializedBy::Move; }52  constexpr ViewWithInitTracking& operator=(const ViewWithInitTracking& rhs) = default;53  constexpr ViewWithInitTracking& operator=(ViewWithInitTracking&& rhs) = default;54  constexpr bool operator==(const ViewWithInitTracking& rhs) const { return v_ == rhs.v_; }55};56 57template <class View>58concept CanCallBase = requires(View v) { std::forward<View>(v).base(); };59 60static_assert( CanCallBase<std::ranges::lazy_split_view<MoveOnlyView, ForwardView>&&>);61static_assert(!CanCallBase<std::ranges::lazy_split_view<MoveOnlyView, ForwardView>&>);62static_assert(!CanCallBase<std::ranges::lazy_split_view<MoveOnlyView, ForwardView> const &>);63static_assert(!CanCallBase<std::ranges::lazy_split_view<MoveOnlyView, ForwardView> const &&>);64 65constexpr bool test() {66  using View = ViewWithInitTracking;67 68  // Copyable input -- both lvalue and rvalue overloads of `base` are available.69  {70    // Non-const lvalue.71    {72      View str{"abc def"};73      std::ranges::lazy_split_view<View, std::string_view> v(str, " ");74 75      std::same_as<View> decltype(auto) result = v.base();76      assert(result == str);77      assert(result.initialized_by == View::InitializedBy::Copy);78    }79 80    // Const lvalue.81    {82      View str{"abc def"};83      const std::ranges::lazy_split_view<View, std::string_view> v(str, " ");84 85      std::same_as<View> decltype(auto) result = v.base();86      assert(result == str);87      assert(result.initialized_by == View::InitializedBy::Copy);88    }89 90    // Non-const rvalue.91    {92      View str{"abc def"};93      std::ranges::lazy_split_view<View, std::string_view> v(str, " ");94 95      std::same_as<View> decltype(auto) result = std::move(v).base();96      assert(result == str);97      assert(result.initialized_by == View::InitializedBy::Move);98    }99 100    // Const rvalue.101    {102      View str{"abc def"};103      const std::ranges::lazy_split_view<View, std::string_view> v(str, " ");104 105      std::same_as<View> decltype(auto) result = std::move(v).base();106      assert(result == str);107      assert(result.initialized_by == View::InitializedBy::Copy);108    }109  }110 111  // Move-only input -- only the rvalue overload of `base` is available.112  {113    std::ranges::lazy_split_view<MoveOnlyView, ForwardView> v;114    assert(std::move(v).base() == MoveOnlyView());115  }116 117  return true;118}119 120int main(int, char**) {121  test();122  static_assert(test());123 124  return 0;125}126