brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · d31373f Raw
205 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// std::views::all;12 13#include <ranges>14 15#include <cassert>16#include <concepts>17#include <type_traits>18#include <utility>19 20#include "test_iterators.h"21#include "test_macros.h"22#include "test_range.h"23 24int globalBuff[8];25 26template<bool IsNoexcept>27struct View : std::ranges::view_base {28  int start_ = 0;29  explicit View() noexcept(IsNoexcept) = default;30  constexpr explicit View(int start) : start_(start) {}31  View(View&&) noexcept(IsNoexcept) = default;32  View& operator=(View&&) noexcept(IsNoexcept) = default;33  constexpr int* begin() const { return globalBuff + start_; }34  constexpr int* end() const { return globalBuff + 8; }35};36static_assert(std::ranges::view<View<true>>);37static_assert(std::ranges::view<View<false>>);38 39template<bool IsNoexcept>40struct CopyableView : std::ranges::view_base {41  int start_ = 0;42  explicit CopyableView() noexcept(IsNoexcept) = default;43  CopyableView(CopyableView const&) noexcept(IsNoexcept) = default;44  CopyableView& operator=(CopyableView const&) noexcept(IsNoexcept) = default;45  constexpr explicit CopyableView(int start) noexcept : start_(start) {}46  constexpr int* begin() const { return globalBuff + start_; }47  constexpr int* end() const { return globalBuff + 8; }48};49static_assert(std::ranges::view<CopyableView<true>>);50static_assert(std::ranges::view<CopyableView<false>>);51 52struct MoveOnlyView : std::ranges::view_base{53  MoveOnlyView() = default;54  MoveOnlyView(const MoveOnlyView&) = delete;55  MoveOnlyView& operator=(const MoveOnlyView&) = delete;56  MoveOnlyView(MoveOnlyView&&) = default;57  MoveOnlyView& operator=(MoveOnlyView&&) = default;58 59  int* begin() const;60  int* end() const;61};62 63struct Range {64  int start_;65  constexpr explicit Range(int start) noexcept : start_(start) {}66  constexpr int* begin() const { return globalBuff + start_; }67  constexpr int* end() const { return globalBuff + 8; }68};69 70struct BorrowableRange {71  int start_;72  constexpr explicit BorrowableRange(int start) noexcept : start_(start) {}73  constexpr int* begin() const { return globalBuff + start_; }74  constexpr int* end() const { return globalBuff + 8; }75};76template<>77inline constexpr bool std::ranges::enable_borrowed_range<BorrowableRange> = true;78 79struct RandomAccessRange {80  constexpr auto begin() { return random_access_iterator<int*>(globalBuff); }81  constexpr auto end() { return sized_sentinel(random_access_iterator<int*>(globalBuff + 8)); }82};83template<>84inline constexpr bool std::ranges::enable_borrowed_range<RandomAccessRange> = true;85 86constexpr bool test() {87  {88    ASSERT_SAME_TYPE(decltype(std::views::all(View<true>())), View<true>);89    static_assert(noexcept(std::views::all(View<true>())));90    static_assert(!noexcept(std::views::all(View<false>())));91 92    auto viewCopy = std::views::all(View<true>(2));93    ASSERT_SAME_TYPE(decltype(viewCopy), View<true>);94    assert(std::ranges::begin(viewCopy) == globalBuff + 2);95    assert(std::ranges::end(viewCopy) == globalBuff + 8);96  }97 98  {99    ASSERT_SAME_TYPE(decltype(std::views::all(std::declval<const CopyableView<true>&>())), CopyableView<true>);100    static_assert(noexcept(std::views::all(CopyableView<true>())));101    static_assert(!noexcept(std::views::all(CopyableView<false>())));102 103    CopyableView<true> view(2);104    auto viewCopy = std::views::all(view);105    ASSERT_SAME_TYPE(decltype(viewCopy), CopyableView<true>);106    assert(std::ranges::begin(viewCopy) == globalBuff + 2);107    assert(std::ranges::end(viewCopy) == globalBuff + 8);108  }109 110  {111    Range range(2);112    auto ref = std::views::all(range);113    ASSERT_SAME_TYPE(decltype(ref), std::ranges::ref_view<Range>);114    assert(std::ranges::begin(ref) == globalBuff + 2);115    assert(std::ranges::end(ref) == globalBuff + 8);116 117    auto own = std::views::all(std::move(range));118    ASSERT_SAME_TYPE(decltype(own), std::ranges::owning_view<Range>);119    assert(std::ranges::begin(own) == globalBuff + 2);120    assert(std::ranges::end(own) == globalBuff + 8);121 122    auto cref = std::views::all(std::as_const(range));123    ASSERT_SAME_TYPE(decltype(cref), std::ranges::ref_view<const Range>);124    assert(std::ranges::begin(cref) == globalBuff + 2);125    assert(std::ranges::end(cref) == globalBuff + 8);126 127    static_assert(!std::is_invocable_v<decltype(std::views::all), const Range&&>);128  }129 130  {131    auto own = std::views::all(BorrowableRange(2));132    ASSERT_SAME_TYPE(decltype(own), std::ranges::owning_view<BorrowableRange>);133    assert(std::ranges::begin(own) == globalBuff + 2);134    assert(std::ranges::end(own) == globalBuff + 8);135  }136 137  {138    auto own = std::views::all(RandomAccessRange());139    ASSERT_SAME_TYPE(decltype(own), std::ranges::owning_view<RandomAccessRange>);140    assert(base(std::ranges::begin(own)) == globalBuff);141    assert(base(base(std::ranges::end(own))) == globalBuff + 8);142  }143 144  // Check SFINAE friendliness of the call operator145  {146    static_assert(!std::is_invocable_v<decltype(std::views::all)>);147    static_assert(!std::is_invocable_v<decltype(std::views::all), RandomAccessRange, RandomAccessRange>);148 149    // `views::all(v)` is expression equivalent to `decay-copy(v)` if the decayed type150    // of `v` models `view`. If `v` is an lvalue-reference to a move-only view, the151    // expression should be ill-formed because `v` is not copyable152    static_assert(!std::is_invocable_v<decltype(std::views::all), MoveOnlyView&>);153  }154 155  // Test that std::views::all is a range adaptor156  {157    // Test `v | views::all`158    {159      Range range(0);160      auto result = range | std::views::all;161      ASSERT_SAME_TYPE(decltype(result), std::ranges::ref_view<Range>);162      assert(&result.base() == &range);163    }164 165    // Test `adaptor | views::all`166    {167      Range range(0);168      auto f = [](int i) { return i; };169      auto const partial = std::views::transform(f) | std::views::all;170      using Result = std::ranges::transform_view<std::ranges::ref_view<Range>, decltype(f)>;171      std::same_as<Result> auto result = partial(range);172      assert(&result.base().base() == &range);173    }174 175    // Test `views::all | adaptor`176    {177      Range range(0);178      auto f = [](int i) { return i; };179      auto const partial = std::views::all | std::views::transform(f);180      using Result = std::ranges::transform_view<std::ranges::ref_view<Range>, decltype(f)>;181      std::same_as<Result> auto result = partial(range);182      assert(&result.base().base() == &range);183    }184 185    {186      struct NotAView { };187      static_assert( CanBePiped<Range&,    decltype(std::views::all)>);188      static_assert(!CanBePiped<NotAView,  decltype(std::views::all)>);189    }190  }191 192  {193    static_assert(std::same_as<decltype(std::views::all), decltype(std::ranges::views::all)>);194  }195 196  return true;197}198 199int main(int, char**) {200  test();201  static_assert(test());202 203  return 0;204}205