brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · 207d60a Raw
284 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++2310 11// <ranges>12 13// constexpr iterator& operator--()14//   requires ref-is-glvalue && bidirectional_range<Base> &&15//            bidirectional-common<InnerBase> && bidirectional-common<PatternBase>;16// constexpr iterator operator--(int)17//   requires ref-is-glvalue && bidirectional_range<Base> &&18//            bidirectional-common<InnerBase> && bidirectional-common<PatternBase>;19 20#include <ranges>21 22#include <algorithm>23#include <array>24#include <cassert>25#include <forward_list>26#include <string>27#include <string_view>28#include <vector>29 30#include "../types.h"31 32template <class I>33concept CanPreDecrement = requires(I& i) {34  { --i } -> std::same_as<I&>;35};36 37template <class I>38concept CanPostDecrement = requires(I& i) {39  { i-- } -> std::same_as<I>;40};41 42template <class I>43concept CanDecrement = CanPreDecrement<I> && CanPostDecrement<I>;44 45constexpr bool test() {46  { // `V` and `Pattern` are not empty. Test return type too.47    using V       = std::ranges::owning_view<std::vector<std::string>>;48    using Pattern = std::ranges::single_view<char>;49    using JWV     = std::ranges::join_with_view<V, Pattern>;50 51    using Iter  = std::ranges::iterator_t<JWV>;52    using CIter = std::ranges::iterator_t<const JWV>;53    static_assert(CanDecrement<Iter>);54    static_assert(CanDecrement<CIter>);55 56    JWV jwv(V{{"01", "23", "45"}}, Pattern{'_'});57 58    {59      auto it                                   = jwv.end();60      std::same_as<Iter&> decltype(auto) it_ref = --it;61      assert(it_ref == it);62      assert(*it == '5');63      std::same_as<Iter> decltype(auto) it_copy = it--;64      assert(--it_copy == it);65      --it;66      assert(*it == '_');67      it--;68      assert(*it == '3');69      --it;70      it--;71      assert(*it == '_');72    }73 74    {75      auto cit                                    = std::as_const(jwv).end();76      std::same_as<CIter&> decltype(auto) cit_ref = --cit;77      assert(cit_ref == cit);78      assert(*cit == '5');79      std::same_as<CIter> decltype(auto) cit_copy = cit--;80      assert(--cit_copy == cit);81      --cit;82      assert(*cit == '_');83      cit--;84      assert(*cit == '3');85      --cit;86      cit--;87      assert(*cit == '_');88    }89 90    assert(std::ranges::equal(std::views::reverse(std::move(jwv)), std::string_view{"54_32_10"}));91  }92 93  { // `Pattern` is empty, `V` is not.94    using Inner   = std::array<int, 1>;95    using V       = std::ranges::owning_view<std::array<Inner, 3>>;96    using Pattern = std::ranges::owning_view<std::array<int, 0>>;97    using JWV     = std::ranges::join_with_view<V, Pattern>;98 99    JWV jwv(V{{Inner{-9}, Inner{-99}, Inner{-999}}}, Pattern{});100 101    {102      auto it = jwv.end();103      --it;104      assert(*it == -999);105      it--;106      assert(*it == -99);107      --it;108      assert(*it == -9);109      assert(it == jwv.begin());110    }111 112    {113      auto cit = std::as_const(jwv).end();114      --cit;115      assert(*cit == -999);116      cit--;117      assert(*cit == -99);118      --cit;119      assert(*cit == -9);120      assert(cit == std::as_const(jwv).begin());121    }122  }123 124#if !defined(TEST_COMPILER_GCC) // GCC c++/101777125  { // `V` has empty subrange in the middle, `Pattern` is not empty. Try to go back and forth.126    using V       = std::array<std::vector<int>, 3>;127    using Pattern = std::ranges::single_view<int>;128    using JWV     = std::ranges::join_with_view<std::ranges::owning_view<V>, Pattern>;129 130    JWV jwv(V{{{5}, {}, {125}}}, Pattern{1});131 132    {133      auto it = jwv.end();134      --it;135      assert(*it == 125);136      it--;137      assert(*it == 1);138      --it;139      assert(*it == 1);140      it--;141      assert(*it == 5);142      ++it;143      assert(*it == 1);144      --it;145      assert(*it == 5);146      std::ranges::advance(it, 4);147      it--;148      assert(*it == 125);149    }150 151    {152      auto cit = std::as_const(jwv).end();153      --cit;154      assert(*cit == 125);155      cit--;156      assert(*cit == 1);157      --cit;158      assert(*cit == 1);159      cit--;160      assert(*cit == 5);161      ++cit;162      assert(*cit == 1);163      --cit;164      assert(*cit == 5);165      std::ranges::advance(cit, 4);166      cit--;167      assert(*cit == 125);168    }169  }170 171  { // Only first element of `V` is not empty. `Pattern` is empty. Try to go back and forth.172    using Inner   = std::vector<int>;173    using V       = std::ranges::owning_view<std::array<Inner, 3>>;174    using Pattern = std::ranges::empty_view<int>;175    using JWV     = std::ranges::join_with_view<V, Pattern>;176 177    JWV jwv(V{{Inner{999}, {}, {}}}, Pattern{});178 179    {180      auto it = jwv.end();181      --it;182      assert(*it == 999);183      ++it;184      assert(it == jwv.end());185      it--;186      assert(*it == 999);187    }188 189    {190      auto cit = std::as_const(jwv).end();191      --cit;192      assert(*cit == 999);193      ++cit;194      assert(cit == std::as_const(jwv).end());195      cit--;196      assert(*cit == 999);197    }198  }199#endif // !defined(TEST_COMPILER_GCC)200 201  { // `ref-is-glvalue` is false202    using V       = RvalueVector<std::vector<int>>;203    using Pattern = std::ranges::empty_view<int>;204    using JWV     = std::ranges::join_with_view<std::ranges::owning_view<V>, std::ranges::owning_view<Pattern>>;205    using Iter    = std::ranges::iterator_t<JWV>;206    static_assert(!CanPreDecrement<Iter>);207    static_assert(!CanPostDecrement<Iter>);208  }209 210  { // `Base` does not model bidirectional range211    using V       = std::ranges::owning_view<std::forward_list<std::vector<int>>>;212    using Pattern = std::ranges::single_view<int>;213    using JWV     = std::ranges::join_with_view<V, Pattern>;214    using Iter    = std::ranges::iterator_t<JWV>;215    using CIter   = std::ranges::iterator_t<const JWV>;216    static_assert(!CanPreDecrement<Iter>);217    static_assert(!CanPostDecrement<Iter>);218    static_assert(!CanPreDecrement<CIter>);219    static_assert(!CanPostDecrement<CIter>);220  }221 222  {   // InnerBase does not model bidirectional-common223    { // InnerBase does not model bidirectional range224      using V       = std::ranges::owning_view<std::vector<std::forward_list<int>>>;225      using Pattern = std::ranges::single_view<int>;226      using JWV     = std::ranges::join_with_view<V, Pattern>;227      using Iter    = std::ranges::iterator_t<JWV>;228      using CIter   = std::ranges::iterator_t<const JWV>;229      static_assert(!CanPreDecrement<Iter>);230      static_assert(!CanPostDecrement<Iter>);231      static_assert(!CanPreDecrement<CIter>);232      static_assert(!CanPostDecrement<CIter>);233    }234 235    { // InnerBase does not model common range236      using InnerBase = BasicVectorView<int, ViewProperties{.common = false}, bidirectional_iterator>;237      using V         = std::ranges::owning_view<std::vector<InnerBase>>;238      using Pattern   = std::ranges::single_view<int>;239      using JWV       = std::ranges::join_with_view<V, Pattern>;240      using Iter      = std::ranges::iterator_t<JWV>;241      using CIter     = std::ranges::iterator_t<const JWV>;242      static_assert(!CanPreDecrement<Iter>);243      static_assert(!CanPostDecrement<Iter>);244      static_assert(!CanPreDecrement<CIter>);245      static_assert(!CanPostDecrement<CIter>);246    }247  }248 249  {   // PatternBase does not model bidirectional-common250    { // PatternBase does not model bidirectional range251      using V       = std::ranges::owning_view<std::vector<std::vector<int>>>;252      using Pattern = std::ranges::owning_view<std::forward_list<int>>;253      using JWV     = std::ranges::join_with_view<V, Pattern>;254      using Iter    = std::ranges::iterator_t<JWV>;255      using CIter   = std::ranges::iterator_t<const JWV>;256      static_assert(!CanPreDecrement<Iter>);257      static_assert(!CanPostDecrement<Iter>);258      static_assert(!CanPreDecrement<CIter>);259      static_assert(!CanPostDecrement<CIter>);260    }261 262    { // PatternBase does not model common range263      using V       = std::ranges::owning_view<std::vector<std::vector<int>>>;264      using Pattern = BasicVectorView<int, ViewProperties{.common = false}, bidirectional_iterator>;265      using JWV     = std::ranges::join_with_view<V, Pattern>;266      using Iter    = std::ranges::iterator_t<JWV>;267      using CIter   = std::ranges::iterator_t<const JWV>;268      static_assert(!CanPreDecrement<Iter>);269      static_assert(!CanPostDecrement<Iter>);270      static_assert(!CanPreDecrement<CIter>);271      static_assert(!CanPostDecrement<CIter>);272    }273  }274 275  return true;276}277 278int main(int, char**) {279  test();280  static_assert(test());281 282  return 0;283}284