brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 4a0bf7b Raw
160 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// std::views::zip_transform12 13#include <ranges>14 15#include <algorithm>16#include <array>17#include <cassert>18#include <functional>19#include <type_traits>20#include <vector>21 22#include "types.h"23 24struct NotMoveConstructible {25  NotMoveConstructible()                       = default;26  NotMoveConstructible(NotMoveConstructible&&) = delete;27  int operator()() const { return 5; }28};29 30struct NotCopyConstructible {31  NotCopyConstructible()                            = default;32  NotCopyConstructible(NotCopyConstructible&&)      = default;33  NotCopyConstructible(const NotCopyConstructible&) = delete;34  int operator()() const { return 5; }35};36 37struct NotInvocable {};38 39template <class... Args>40struct Invocable {41  int operator()(Args...) const { return 5; }42};43 44struct ReturnNotObject {45  void operator()() const {}46};47 48// LWG3773 views::zip_transform still requires F to be copy_constructible when empty pack49static_assert(std::is_invocable_v<decltype((std::views::zip_transform)), NotCopyConstructible>);50 51static_assert(!std::is_invocable_v<decltype((std::views::zip_transform))>);52static_assert(!std::is_invocable_v<decltype((std::views::zip_transform)), NotMoveConstructible>);53static_assert(!std::is_invocable_v<decltype((std::views::zip_transform)), NotInvocable>);54static_assert(std::is_invocable_v<decltype((std::views::zip_transform)), Invocable<>>);55static_assert(!std::is_invocable_v<decltype((std::views::zip_transform)), ReturnNotObject>);56 57static_assert(std::is_invocable_v<decltype((std::views::zip_transform)), //58                                  Invocable<int>,                        //59                                  std::ranges::iota_view<int, int>>);60static_assert(!std::is_invocable_v<decltype((std::views::zip_transform)), //61                                   Invocable<>,                           //62                                   std::ranges::iota_view<int, int>>);63static_assert(!std::is_invocable_v<decltype((std::views::zip_transform)),64                                   Invocable<int>,65                                   std::ranges::iota_view<int, int>,66                                   std::ranges::iota_view<int, int>>);67static_assert(std::is_invocable_v<decltype((std::views::zip_transform)),68                                  Invocable<int, int>,69                                  std::ranges::iota_view<int, int>,70                                  std::ranges::iota_view<int, int>>);71 72constexpr bool test() {73  {74    // zip_transform function with no ranges75    auto v = std::views::zip_transform(Invocable<>{});76    assert(std::ranges::empty(v));77    static_assert(std::is_same_v<decltype(v), std::ranges::empty_view<int>>);78  }79 80  {81    // zip_transform views82    int buffer1[] = {1, 2, 3, 4, 5, 6, 7, 8};83    int buffer2[] = {9, 10, 11, 12};84    auto view1    = std::views::all(buffer1);85    auto view2    = std::views::all(buffer2);86    std::same_as<std::ranges::zip_transform_view<std::plus<>, decltype(view1), decltype(view2)>> decltype(auto) v =87        std::views::zip_transform(std::plus{}, buffer1, buffer2);88    assert(std::ranges::size(v) == 4);89    auto expected = {10, 12, 14, 16};90    assert(std::ranges::equal(v, expected));91    static_assert(std::is_same_v<std::ranges::range_reference_t<decltype(v)>, int>);92  }93 94  {95    // zip_transform a viewable range96    std::array a{1, 2, 3};97    auto id = [](auto& x) -> decltype(auto) { return (x); };98    std::same_as<99        std::ranges::zip_transform_view<decltype(id), std::ranges::ref_view<std::array<int, 3>>>> decltype(auto) v =100        std::views::zip_transform(id, a);101    assert(&v[0] == &a[0]);102    static_assert(std::is_same_v<std::ranges::range_reference_t<decltype(v)>, int&>);103  }104 105  int buffer[] = {1, 2, 3};106  {107    // one range108    auto v = std::views::zip_transform(MakeTuple{}, SimpleCommon{buffer});109    assert(std::ranges::equal(v, std::vector{std::tuple(1), std::tuple(2), std::tuple(3)}));110  }111 112  {113    // two ranges114    auto v = std::views::zip_transform(GetFirst{}, SimpleCommon{buffer}, std::views::iota(0));115    assert(std::ranges::equal(v, std::vector{1, 2, 3}));116  }117 118  {119    // three ranges120    auto v = std::views::zip_transform(Tie{}, SimpleCommon{buffer}, SimpleCommon{buffer}, std::ranges::single_view(2.));121    assert(std::ranges::equal(v, std::vector{std::tuple(1, 1, 2.0)}));122  }123 124  {125    // single empty range126    auto v = std::views::zip_transform(MakeTuple{}, std::ranges::empty_view<int>());127    assert(std::ranges::empty(v));128  }129 130  {131    // empty range at the beginning132    auto v = std::views::zip_transform(133        MakeTuple{}, std::ranges::empty_view<int>(), SimpleCommon{buffer}, SimpleCommon{buffer});134    assert(std::ranges::empty(v));135  }136 137  {138    // empty range in the middle139    auto v = std::views::zip_transform(140        MakeTuple{}, SimpleCommon{buffer}, std::ranges::empty_view<int>(), SimpleCommon{buffer});141    assert(std::ranges::empty(v));142  }143 144  {145    // empty range at the end146    auto v = std::views::zip_transform(147        MakeTuple{}, SimpleCommon{buffer}, SimpleCommon{buffer}, std::ranges::empty_view<int>());148    assert(std::ranges::empty(v));149  }150 151  return true;152}153 154int main(int, char**) {155  test();156  static_assert(test());157 158  return 0;159}160