brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 5f3b5a3 Raw
145 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++17, c++2010 11// constexpr explicit zip_transform_view(F, Views...)12 13#include <algorithm>14#include <ranges>15#include <vector>16 17#include "types.h"18 19struct Fn {20  int operator()(auto&&...) const { return 5; }21};22 23template <class T, class... Args>24concept IsImplicitlyConstructible = requires(T val, Args... args) { val = {std::forward<Args>(args)...}; };25 26// test constructor is explicit27static_assert(std::constructible_from<std::ranges::zip_transform_view<Fn, IntView>, Fn, IntView>);28static_assert(!IsImplicitlyConstructible<std::ranges::zip_transform_view<Fn, IntView>, Fn, IntView>);29 30static_assert(std::constructible_from<std::ranges::zip_transform_view<Fn, IntView, IntView>, Fn, IntView, IntView>);31static_assert(!IsImplicitlyConstructible<std::ranges::zip_transform_view<Fn, IntView, IntView>, Fn, IntView, IntView>);32 33struct MoveAwareView : std::ranges::view_base {34  int moves                 = 0;35  constexpr MoveAwareView() = default;36  constexpr MoveAwareView(MoveAwareView&& other) : moves(other.moves + 1) { other.moves = 1; }37  constexpr MoveAwareView& operator=(MoveAwareView&& other) {38    moves       = other.moves + 1;39    other.moves = 0;40    return *this;41  }42  constexpr const int* begin() const { return &moves; }43  constexpr const int* end() const { return &moves + 1; }44};45 46template <class View1, class View2>47constexpr void constructorTest(auto&& buffer1, auto&& buffer2) {48  std::ranges::zip_transform_view v{MakeTuple{}, View1{buffer1}, View2{buffer2}};49  auto [i, j] = *v.begin();50  assert(i == buffer1[0]);51  assert(j == buffer2[0]);52};53 54constexpr bool test() {55  int buffer[8]  = {1, 2, 3, 4, 5, 6, 7, 8};56  int buffer2[4] = {9, 8, 7, 6};57 58  {59    // one range60    std::ranges::zip_transform_view v(MakeTuple{}, SimpleCommon{buffer2});61    assert(std::ranges::equal(v, std::vector{std::tuple(9), std::tuple(8), std::tuple(7), std::tuple(6)}));62  }63 64  {65    // two ranges66    std::ranges::zip_transform_view v(GetFirst{}, SimpleCommon{buffer}, std::views::iota(0));67    assert(std::ranges::equal(v, std::vector{1, 2, 3, 4, 5, 6, 7, 8}));68  }69 70  {71    // three ranges72    std::ranges::zip_transform_view v(Tie{}, SimpleCommon{buffer}, SimpleCommon{buffer2}, std::ranges::single_view(2.));73    assert(std::ranges::equal(v, std::vector{std::tuple(1, 9, 2.0)}));74  }75 76  {77    // single empty range78    std::ranges::zip_transform_view v(MakeTuple{}, std::ranges::empty_view<int>());79    assert(std::ranges::empty(v));80  }81 82  {83    // empty range at the beginning84    std::ranges::zip_transform_view v(85        MakeTuple{}, std::ranges::empty_view<int>(), SimpleCommon{buffer}, SimpleCommon{buffer});86    assert(std::ranges::empty(v));87  }88 89  {90    // empty range in the middle91    std::ranges::zip_transform_view v(92        MakeTuple{}, SimpleCommon{buffer}, std::ranges::empty_view<int>(), SimpleCommon{buffer});93    assert(std::ranges::empty(v));94  }95 96  {97    // empty range at the end98    std::ranges::zip_transform_view v(99        MakeTuple{}, SimpleCommon{buffer}, SimpleCommon{buffer}, std::ranges::empty_view<int>());100    assert(std::ranges::empty(v));101  }102  {103    // constructor from views104    std::ranges::zip_transform_view v(105        MakeTuple{}, SizedRandomAccessView{buffer}, std::views::iota(0), std::ranges::single_view(2.));106    auto [i, j, k] = *v.begin();107    assert(i == 1);108    assert(j == 0);109    assert(k == 2.0);110  }111 112  {113    // arguments are moved once114    MoveAwareView mv;115    std::ranges::zip_transform_view v{MakeTuple{}, std::move(mv), MoveAwareView{}};116    auto [numMoves1, numMoves2] = *v.begin();117    assert(numMoves1 == 3); // one move from the local variable to parameter, one move from parameter to member118    assert(numMoves2 == 2);119  }120 121  // input and forward122  {123    constructorTest<InputCommonView, ForwardSizedView>(buffer, buffer2);124  }125 126  // bidi and random_access127  {128    constructorTest<BidiCommonView, SizedRandomAccessView>(buffer, buffer2);129  }130 131  // contiguous132  {133    constructorTest<ContiguousCommonView, ContiguousCommonView>(buffer, buffer2);134  }135 136  return true;137}138 139int main(int, char**) {140  test();141  static_assert(test());142 143  return 0;144}145