brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 26c9ac0 Raw
176 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::reverse12 13#include <ranges>14 15#include <cassert>16#include <concepts>17#include <iterator>18#include <utility>19 20#include "test_range.h"21#include "types.h"22 23constexpr bool test() {24  int buf[] = {1, 2, 3};25 26  // views::reverse(x) is equivalent to x.base() if x is a reverse_view27  {28    {29      BidirRange view(buf, buf + 3);30      std::ranges::reverse_view<BidirRange> reversed(view);31      std::same_as<BidirRange> auto result = std::views::reverse(reversed);32      assert(result.begin_ == buf);33      assert(result.end_ == buf + 3);34    }35    {36      // Common use case is worth testing37      BidirRange view(buf, buf + 3);38      std::same_as<BidirRange> auto result = std::views::reverse(std::views::reverse(view));39      assert(result.begin_ == buf);40      assert(result.end_ == buf + 3);41    }42  }43 44  // views::reverse(x) is equivalent to subrange{end, begin, size} if x is a45  // sized subrange over reverse iterators46  {47    using It = bidirectional_iterator<int*>;48    using Subrange = std::ranges::subrange<It, It, std::ranges::subrange_kind::sized>;49 50    using ReverseIt = std::reverse_iterator<It>;51    using ReverseSubrange = std::ranges::subrange<ReverseIt, ReverseIt, std::ranges::subrange_kind::sized>;52 53    {54      BidirRange view(buf, buf + 3);55      ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3);56      std::same_as<Subrange> auto result = std::views::reverse(subrange);57      assert(base(result.begin()) == buf);58      assert(base(result.end()) == buf + 3);59    }60    {61      // std::move into views::reverse62      BidirRange view(buf, buf + 3);63      ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3);64      std::same_as<Subrange> auto result = std::views::reverse(std::move(subrange));65      assert(base(result.begin()) == buf);66      assert(base(result.end()) == buf + 3);67    }68    {69      // with a const subrange70      BidirRange view(buf, buf + 3);71      ReverseSubrange const subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3);72      std::same_as<Subrange> auto result = std::views::reverse(subrange);73      assert(base(result.begin()) == buf);74      assert(base(result.end()) == buf + 3);75    }76  }77 78  // views::reverse(x) is equivalent to subrange{end, begin} if x is an79  // unsized subrange over reverse iterators80  {81    using It = bidirectional_iterator<int*>;82    using Subrange = std::ranges::subrange<It, It, std::ranges::subrange_kind::unsized>;83 84    using ReverseIt = std::reverse_iterator<It>;85    using ReverseSubrange = std::ranges::subrange<ReverseIt, ReverseIt, std::ranges::subrange_kind::unsized>;86 87    {88      BidirRange view(buf, buf + 3);89      ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)));90      std::same_as<Subrange> auto result = std::views::reverse(subrange);91      assert(base(result.begin()) == buf);92      assert(base(result.end()) == buf + 3);93    }94    {95      // std::move into views::reverse96      BidirRange view(buf, buf + 3);97      ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)));98      std::same_as<Subrange> auto result = std::views::reverse(std::move(subrange));99      assert(base(result.begin()) == buf);100      assert(base(result.end()) == buf + 3);101    }102    {103      // with a const subrange104      BidirRange view(buf, buf + 3);105      ReverseSubrange const subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)));106      std::same_as<Subrange> auto result = std::views::reverse(subrange);107      assert(base(result.begin()) == buf);108      assert(base(result.end()) == buf + 3);109    }110  }111 112  // Otherwise, views::reverse(x) is equivalent to ranges::reverse_view{x}113  {114    BidirRange view(buf, buf + 3);115    std::same_as<std::ranges::reverse_view<BidirRange>> auto result = std::views::reverse(view);116    assert(base(result.begin().base()) == buf + 3);117    assert(base(result.end().base()) == buf);118  }119 120  // Test that std::views::reverse is a range adaptor121  {122    // Test `v | views::reverse`123    {124      BidirRange view(buf, buf + 3);125      std::same_as<std::ranges::reverse_view<BidirRange>> auto result = view | std::views::reverse;126      assert(base(result.begin().base()) == buf + 3);127      assert(base(result.end().base()) == buf);128    }129 130    // Test `adaptor | views::reverse`131    {132      BidirRange view(buf, buf + 3);133      auto f = [](int i) { return i; };134      auto const partial = std::views::transform(f) | std::views::reverse;135      using Result = std::ranges::reverse_view<std::ranges::transform_view<BidirRange, decltype(f)>>;136      std::same_as<Result> auto result = partial(view);137      assert(base(result.begin().base().base()) == buf + 3);138      assert(base(result.end().base().base()) == buf);139    }140 141    // Test `views::reverse | adaptor`142    {143      BidirRange view(buf, buf + 3);144      auto f = [](int i) { return i; };145      auto const partial = std::views::reverse | std::views::transform(f);146      using Result = std::ranges::transform_view<std::ranges::reverse_view<BidirRange>, decltype(f)>;147      std::same_as<Result> auto result = partial(view);148      assert(base(result.begin().base().base()) == buf + 3);149      assert(base(result.end().base().base()) == buf);150    }151 152    // Check SFINAE friendliness153    {154      struct NotABidirRange { };155      static_assert(!std::is_invocable_v<decltype(std::views::reverse)>);156      static_assert(!std::is_invocable_v<decltype(std::views::reverse), NotABidirRange>);157      static_assert( CanBePiped<BidirRange,     decltype(std::views::reverse)>);158      static_assert( CanBePiped<BidirRange&,    decltype(std::views::reverse)>);159      static_assert(!CanBePiped<NotABidirRange, decltype(std::views::reverse)>);160    }161  }162 163  {164    static_assert(std::same_as<decltype(std::views::reverse), decltype(std::ranges::views::reverse)>);165  }166 167  return true;168}169 170int main(int, char**) {171  test();172  static_assert(test());173 174  return 0;175}176