233 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// constexpr void operator++(int);13// constexpr iterator operator++(int)14// requires ref-is-glvalue && forward_range<Base> &&15// forward_range<range_reference_t<Base>>;16 17#include <cassert>18#include <ranges>19 20#include "test_macros.h"21#include "../types.h"22 23constexpr bool test() {24 // This way if we read past end we'll catch the error.25 int buffer1[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};26 int dummy = 42;27 (void) dummy;28 int buffer2[2][4] = {{9, 10, 11, 12}, {13, 14, 15, 16}};29 30 // operator++(int);31 {32 std::ranges::join_view jv(buffer1);33 auto iter = jv.begin();34 for (int i = 1; i < 9; ++i) {35 assert(*iter++ == i);36 }37 }38 39 {40 using IntView = ValueView<int>;41 IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])};42 std::ranges::join_view jv(ValueView<IntView>{children});43 auto iter = jv.begin();44 for (int i = 1; i < 17; ++i) {45 assert(*iter == i);46 iter++;47 }48 49 ASSERT_SAME_TYPE(decltype(iter++), void);50 }51 52 {53 std::ranges::join_view jv(buffer1);54 auto iter = std::next(jv.begin(), 7);55 assert(*iter++ == 8);56 assert(iter == jv.end());57 }58 59 {60 int small[2][1] = {{1}, {2}};61 std::ranges::join_view jv(small);62 auto iter = jv.begin();63 for (int i = 1; i < 3; ++i) {64 assert(*iter++ == i);65 }66 }67 68 // Has some empty children.69 {70 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 1), CopyableChild(buffer2[1], 0)};71 auto jv = std::ranges::join_view(ParentView(children));72 auto iter = jv.begin();73 assert(*iter == 1); iter++;74 assert(*iter == 2); iter++;75 assert(*iter == 3); iter++;76 assert(*iter == 4); iter++;77 assert(*iter == 9); iter++;78 assert(iter == jv.end());79 }80 81 // Parent is empty.82 {83 CopyableChild children[4] = {CopyableChild(buffer1[0]), CopyableChild(buffer1[1]), CopyableChild(buffer2[0]), CopyableChild(buffer2[1])};84 std::ranges::join_view jv(ParentView(children, 0));85 assert(jv.begin() == jv.end());86 }87 88 // Parent size is one.89 {90 CopyableChild children[1] = {CopyableChild(buffer1[0])};91 std::ranges::join_view jv(ParentView(children, 1));92 auto iter = jv.begin();93 assert(*iter == 1); iter++;94 assert(*iter == 2); iter++;95 assert(*iter == 3); iter++;96 assert(*iter == 4); iter++;97 assert(iter == jv.end());98 }99 100 // Parent and child size is one.101 {102 CopyableChild children[1] = {CopyableChild(buffer1[0], 1)};103 std::ranges::join_view jv(ParentView(children, 1));104 auto iter = jv.begin();105 assert(*iter == 1); iter++;106 assert(iter == jv.end());107 }108 109 // Parent size is one child is empty110 {111 CopyableChild children[1] = {CopyableChild(buffer1[0], 0)};112 std::ranges::join_view jv(ParentView(children, 1));113 assert(jv.begin() == jv.end());114 }115 116 // Has all empty children.117 {118 CopyableChild children[4] = {CopyableChild(buffer1[0], 0), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};119 auto jv = std::ranges::join_view(ParentView(children));120 assert(jv.begin() == jv.end());121 }122 123 // First child is empty, others are not.124 {125 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};126 auto jv = std::ranges::join_view(ParentView(children));127 auto iter = jv.begin();128 assert(*iter == 1); iter++;129 assert(*iter == 2); iter++;130 assert(*iter == 3); iter++;131 assert(*iter == 4); iter++;132 assert(iter == jv.end());133 }134 135 // Last child is empty, others are not.136 {137 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 4), CopyableChild(buffer2[0], 4), CopyableChild(buffer2[1], 0)};138 auto jv = std::ranges::join_view(ParentView(children));139 auto iter = jv.begin();140 for (int i = 1; i < 13; ++i) {141 assert(*iter == i);142 iter++;143 }144 }145 146 // operator++();147 {148 std::ranges::join_view jv(buffer1);149 auto iter = jv.begin();150 for (int i = 2; i < 9; ++i) {151 assert(*++iter == i);152 }153 }154 155 {156 using IntView = ValueView<int>;157 IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])};158 std::ranges::join_view jv(ValueView<IntView>{children});159 auto iter = jv.begin();160 for (int i = 2; i < 17; ++i) {161 assert(*++iter == i);162 }163 164 ASSERT_SAME_TYPE(decltype(++iter), decltype(iter)&);165 }166 167 {168 // check return value169 std::ranges::join_view jv(buffer1);170 auto iter = jv.begin();171 using iterator = decltype(iter);172 173 decltype(auto) iter2 = ++iter;174 static_assert(std::is_same_v<decltype(iter2), iterator&>);175 assert(&iter2 == &iter);176 177 std::same_as<iterator> decltype(auto) iter3 = iter++;178 assert(std::next(iter3) == iter);179 }180 181 {182 // !ref-is-glvalue183 BidiCommonInner inners[2] = {buffer1[0], buffer1[1]};184 InnerRValue<BidiCommonOuter<BidiCommonInner>> outer{inners};185 std::ranges::join_view jv(outer);186 auto iter = jv.begin();187 static_assert(std::is_void_v<decltype(iter++)>);188 }189 190 {191 // !forward_range<Base>192 BufferView<int*> inners[2] = {buffer1[0], buffer1[1]};193 using Outer = SimpleInputCommonOuter<BufferView<int*>>;194 std::ranges::join_view jv{Outer(inners)};195 auto iter = jv.begin();196 static_assert(std::is_void_v<decltype(iter++)>);197 }198 199 {200 // !forward_range<range_reference_t<Base>>201 InputCommonInner inners[1] = {buffer1[0]};202 std::ranges::join_view jv{inners};203 auto iter = jv.begin();204 static_assert(std::is_void_v<decltype(iter++)>);205 }206 207 {208 // Check stashing iterators (LWG3698: regex_iterator and join_view don't work together very well)209 std::ranges::join_view<StashingRange> jv;210 auto it = jv.begin();211 assert(*it == 'a');212 ++it;213 assert(*it == 'a');214 ++it;215 assert(*it == 'b');216 it++;217 assert(*it == 'a');218 it++;219 assert(*it == 'b');220 ++it;221 assert(*it == 'c');222 }223 224 return true;225}226 227int main(int, char**) {228 test();229 static_assert(test());230 231 return 0;232}233