brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · 22872c2 Raw
222 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 auto begin();14// constexpr auto begin() const15//   requires forward_range<const V> &&16//            forward_range<const Pattern> &&17//            is_reference_v<range_reference_t<const V>> &&18//            input_range<range_reference_t<const V>>;19 20#include <ranges>21 22#include <algorithm>23#include <array>24#include <string>25#include <vector>26 27#include "../types.h"28#include "test_iterators.h"29 30template <bool Simple>31using MaybeSimpleForwardView = BasicView<std::vector<std::string>, ViewProperties{.simple = Simple}, forward_iterator>;32 33template <bool Simple>34using MaybeSimpleForwardRvalueView =35    BasicView<RvalueVector<std::string>, ViewProperties{.simple = Simple}, forward_iterator>;36 37template <bool Simple>38using MaybeSimplePattern = BasicView<std::string, ViewProperties{.simple = Simple}, forward_iterator>;39 40template <class V, class Pattern>41concept JoinWithViewHasConstBegin = requires(const std::ranges::join_with_view<V, Pattern> jwv) {42  { jwv.begin() } -> std::input_iterator;43};44 45constexpr void test_begin() {46  using Str = std::string;47  using Vec = std::vector<Str>;48 49  { // `V` models simple-view50    // `is_reference_v<InnerRng>` is true51    // `Pattern` models simple-view52    // `V` and `Pattern` contain some elements53    using V       = MaybeSimpleForwardView<true>;54    using Pattern = MaybeSimplePattern<true>;55    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"A", "B", "C"}), Pattern(Str{">>"}));56    auto it = jwv.begin();57    assert(std::ranges::equal(std::views::counted(it, 7), Str{"A>>B>>C"}));58  }59 60  { // `V` does not model simple-view61    // `is_reference_v<InnerRng>` is true62    // `Pattern` models simple-view63    // `V` and `Pattern` are empty64    using V       = MaybeSimpleForwardView<false>;65    using Pattern = MaybeSimplePattern<true>;66    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{}), Pattern(Str{}));67    auto it = jwv.begin();68    assert(it == jwv.end());69  }70 71  { // `V` models simple-view72    // `is_reference_v<InnerRng>` is false73    // `Pattern` models simple-view74    // `V` contains two elements, `Pattern` is empty75    using V       = MaybeSimpleForwardRvalueView<true>;76    using Pattern = MaybeSimplePattern<true>;77    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"1", "2"}), Pattern(Str{""}));78    auto it = jwv.begin();79    assert(*it == '1');80    assert(*++it == '2');81  }82 83  { // `V` models simple-view84    // `is_reference_v<InnerRng>` is true85    // `Pattern` does not model simple-view86    // `V` contains one element, `Pattern` is empty87    using V       = MaybeSimpleForwardView<true>;88    using Pattern = MaybeSimplePattern<false>;89    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"07"}), Pattern(Str{}));90    auto it = jwv.begin();91    assert(*it++ == '0');92    assert(*it == '7');93  }94 95  { // `V` does not model simple-view96    // `is_reference_v<InnerRng>` is false97    // `Pattern` models simple-view98    // `V` contains three elements (2nd is empty), `Pattern` is not empty99    using V       = MaybeSimpleForwardRvalueView<false>;100    using Pattern = MaybeSimplePattern<true>;101    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"A", "", "C"}), Pattern(Str{"--"}));102    auto it = jwv.begin();103    assert(std::ranges::equal(std::views::counted(it, 6), Str("A----C")));104  }105 106  { // `V` does not model simple-view107    // `is_reference_v<InnerRng>` is true108    // `Pattern` does not model simple-view109    // `V` contains some empty elements, `Pattern` is not empty110    using V       = MaybeSimpleForwardView<false>;111    using Pattern = MaybeSimplePattern<false>;112    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"", "", ""}), Pattern(Str{"-"}));113    auto it = jwv.begin();114    assert(*it++ == '-');115    assert(*it == '-');116  }117 118  { // `V` models simple-view119    // `is_reference_v<InnerRng>` is false120    // `Pattern` does not model simple-view121    // `V` contains two elements, `Pattern` is not empty122    using V       = MaybeSimpleForwardRvalueView<true>;123    using Pattern = MaybeSimplePattern<false>;124    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"X", "Z"}), Pattern(Str{"Y"}));125    auto it = jwv.begin();126    assert(*it == 'X');127    assert(*++it == 'Y');128    assert(*++it == 'Z');129  }130 131  { // `V` does not model simple-view132    // `is_reference_v<InnerRng>` is false133    // `Pattern` does not model simple-view134    // `V` contains two empty elements, `Pattern` is not empty135    using V       = MaybeSimpleForwardRvalueView<false>;136    using Pattern = MaybeSimplePattern<false>;137    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"", ""}), Pattern(Str{"?"}));138    auto it = jwv.begin();139    assert(*it == '?');140    assert(++it == jwv.end());141  }142 143  { // `V` does not model forward range144    // `V` contains some empty elements, `Pattern` is empty145    using V       = BasicView<Vec, ViewProperties{.common = false}, cpp20_input_iterator>;146    using Pattern = MaybeSimplePattern<false>;147    std::ranges::join_with_view<V, Pattern> jwv(V(Vec{"", "", ""}), Pattern(Str{""}));148    auto it = jwv.begin();149    assert(it == jwv.end());150  }151}152 153constexpr void test_const_begin() {154  using Vec = std::vector<std::array<int, 2>>;155  using Pat = std::array<int, 2>;156 157  { // `const V` models forward range158    // `const Pattern` models forward range159    // `is_reference_v<range_reference_t<const V>>` is true160    // `range_reference_t<const V>` models input range161    using V       = BasicView<Vec, ViewProperties{}, forward_iterator>;162    using Pattern = BasicView<Pat, ViewProperties{}, forward_iterator>;163 164    const std::ranges::join_with_view<V, Pattern> jwv{V{Vec{std::array{1, 2}, std::array{3, 4}}}, Pattern{Pat{0, 0}}};165    auto it = jwv.begin();166    assert(std::ranges::equal(std::views::counted(it, 6), std::array{1, 2, 0, 0, 3, 4}));167  }168 169  // `const V` does not model forward range170  // `const Pattern` models forward range171  // `is_reference_v<range_reference_t<const V>>` is true172  // `range_reference_t<const V>` models input range173  static_assert(!JoinWithViewHasConstBegin<BasicView<Vec, ViewProperties{.common = false}, cpp20_input_iterator>,174                                           BasicView<Pat, ViewProperties{}, forward_iterator>>);175 176  // `const V` models forward range177  // `const Pattern` does not model forward range178  // `is_reference_v<range_reference_t<const V>>` is true179  // `range_reference_t<const V>` models input range180  static_assert(!JoinWithViewHasConstBegin<BasicView<Vec, ViewProperties{}, forward_iterator>,181                                           BasicView<Pat, ViewProperties{.common = false}, cpp20_input_iterator>>);182 183  // `const V` models forward range184  // `const Pattern` models forward range185  // `is_reference_v<range_reference_t<const V>>` is false186  // `range_reference_t<const V>` models input range187  static_assert(188      !JoinWithViewHasConstBegin<BasicView<RvalueVector<std::vector<int>>, ViewProperties{}, forward_iterator>,189                                 BasicView<Pat, ViewProperties{}, forward_iterator>>);190 191  // `const V` models forward range192  // `const Pattern` models forward range193  // `is_reference_v<range_reference_t<const V>>` is true194  // `range_reference_t<const V>` does not model input range195  static_assert(!JoinWithViewHasConstBegin<196                BasicView<std::vector<InputRangeButOutputWhenConst<int>>, ViewProperties{}, forward_iterator>,197                BasicView<Pat, ViewProperties{}, forward_iterator>>);198 199  // `concatable<range_reference_t<const V>, const Pattern>` is not satisfied200  // See also LWG-4074: compatible-joinable-ranges is underconstrained201  static_assert(!JoinWithViewHasConstBegin<BasicVectorView<int, ViewProperties{}, forward_iterator>,202                                           lwg4074::PatternWithProxyConstAccess>);203 204  // Check situation when iterators returned by `begin()` and `begin() const` are the same205  using JWV = std::ranges::join_with_view<MaybeSimpleForwardView<true>, MaybeSimplePattern<true>>;206  static_assert(std::same_as<std::ranges::iterator_t<JWV&>, std::ranges::iterator_t<const JWV&>>);207}208 209constexpr bool test() {210  test_begin();211  test_const_begin();212 213  return true;214}215 216int main(int, char**) {217  test();218  static_assert(test());219 220  return 0;221}222