brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 29720d9 Raw
173 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 iterator& operator--();12//              requires ref-is-glvalue && bidirectional_range<Base> &&13//                       bidirectional_range<range_reference_t<Base>> &&14//                       common_range<range_reference_t<Base>>;15// constexpr iterator operator--(int);16//              requires ref-is-glvalue && bidirectional_range<Base> &&17//                       bidirectional_range<range_reference_t<Base>> &&18//                       common_range<range_reference_t<Base>>;19 20#include <algorithm>21#include <array>22#include <cassert>23#include <ranges>24#include <type_traits>25#include <vector>26 27#include "../types.h"28 29template <class T>30concept CanPreDecrement = requires(T& t) { --t; };31 32template <class T>33concept CanPostDecrement = requires(T& t) { t--; };34 35constexpr void noDecrementTest(auto&& jv) {36  auto iter = jv.begin();37  static_assert(!CanPreDecrement<decltype(iter)>);38  static_assert(!CanPostDecrement<decltype(iter)>);39}40 41constexpr bool test() {42  int buffer[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};43 44  {45    // outer == ranges::end46    std::ranges::join_view jv(buffer);47    auto iter = std::next(jv.begin(), 16);48    for (int i = 16; i != 0; --i) {49      assert(*--iter == i);50    }51  }52 53  {54    // outer == ranges::end55    std::ranges::join_view jv(buffer);56    auto iter = std::next(jv.begin(), 13);57    for (int i = 13; i != 0; --i) {58      assert(*--iter == i);59    }60  }61 62  {63    // outer != ranges::end64    std::ranges::join_view jv(buffer);65    auto iter = std::next(jv.begin(), 12);66    for (int i = 12; i != 0; --i) {67      assert(*--iter == i);68    }69  }70 71  {72    // outer != ranges::end73    std::ranges::join_view jv(buffer);74    auto iter = std::next(jv.begin());75    for (int i = 1; i != 0; --i) {76      assert(*--iter == i);77    }78  }79 80  {81    int small[2][1] = {{1}, {2}};82    std::ranges::join_view jv(small);83    auto iter = std::next(jv.begin(), 2);84    for (int i = 2; i != 0; --i) {85      assert(*--iter == i);86    }87  }88 89  {90#if defined(__GNUG__) && !defined(__clang__)91    // This seems to be a gcc bug where evaluating the following code92    // at compile time results in wrong array index93    if (!std::is_constant_evaluated()) {94#endif95      // skip empty inner96      BidiCommonInner inners[4] = {buffer[0], {nullptr, 0}, {nullptr, 0}, buffer[1]};97      std::ranges::join_view jv(inners);98      auto iter = jv.end();99      for (int i = 8; i != 0; --i) {100        assert(*--iter == i);101      }102#if defined(__GNUG__) && !defined(__clang__)103    }104#endif105  }106 107  {108    // basic type checking109    std::ranges::join_view jv(buffer);110    auto iter1 = std::ranges::next(jv.begin(), 4);111    using iterator = decltype(iter1);112 113    decltype(auto) iter2 = --iter1;114    static_assert(std::same_as<decltype(iter2), iterator&>);115    assert(&iter1 == &iter2);116 117    std::same_as<iterator> decltype(auto) iter3 = iter1--;118    assert(iter3 == std::next(iter1));119  }120 121  {122    // !ref-is-glvalue123    BidiCommonInner inners[2] = {buffer[0], buffer[1]};124    InnerRValue<BidiCommonOuter<BidiCommonInner>> outer{inners};125    std::ranges::join_view jv(outer);126    noDecrementTest(jv);127  }128 129  {130    // !bidirectional_range<Base>131    BidiCommonInner inners[2] = {buffer[0], buffer[1]};132    SimpleForwardCommonOuter<BidiCommonInner> outer{inners};133    std::ranges::join_view jv(outer);134    noDecrementTest(jv);135  }136 137  {138    // !bidirectional_range<range_reference_t<Base>>139    ForwardCommonInner inners[2] = {buffer[0], buffer[1]};140    std::ranges::join_view jv(inners);141    noDecrementTest(jv);142  }143 144  {145    // LWG3313 `join_view::iterator::operator--` is incorrectly constrained146    // `join_view::iterator` should not have `operator--` if147    // !common_range<range_reference_t<Base>>148    BidiNonCommonInner inners[2] = {buffer[0], buffer[1]};149    std::ranges::join_view jv(inners);150    auto iter = jv.begin();151    static_assert(!CanPreDecrement<decltype(iter)>);152    static_assert(!CanPostDecrement<decltype(iter)>);153  }154 155  {156    // LWG3791: `join_view::iterator::operator--` may be ill-formed157    std::vector<std::vector<int>> vec = {{1, 2}, {3, 4}, {5, 6}};158    auto r = vec | std::views::transform([](auto& x) -> auto&& { return std::move(x); }) | std::views::join;159    auto e = --r.end();160    assert(*e == 6);161    assert(std::ranges::equal(std::views::reverse(r), std::array{6, 5, 4, 3, 2, 1}));162  }163 164  return true;165}166 167int main(int, char**) {168  test();169  static_assert(test());170 171  return 0;172}173