brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 91d6f2e Raw
146 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// std::views::transform12 13#include <ranges>14 15#include <cassert>16#include <concepts>17#include <type_traits>18#include <utility>19 20#include "test_macros.h"21#include "test_range.h"22#include "types.h"23 24struct NonCopyableFunction {25  NonCopyableFunction(NonCopyableFunction const&) = delete;26  template <class T>27  constexpr T operator()(T x) const { return x; }28};29 30constexpr bool test() {31  int buff[8] = {0, 1, 2, 3, 4, 5, 6, 7};32 33  // Test `views::transform(f)(v)`34  {35    {36      using Result = std::ranges::transform_view<MoveOnlyView, PlusOne>;37      std::same_as<Result> auto result = std::views::transform(PlusOne{})(MoveOnlyView{buff});38      assert(result.begin().base() == buff);39      assert(result[0] == 1);40      assert(result[1] == 2);41      assert(result[2] == 3);42    }43    {44      auto const partial = std::views::transform(PlusOne{});45      using Result = std::ranges::transform_view<MoveOnlyView, PlusOne>;46      std::same_as<Result> auto result = partial(MoveOnlyView{buff});47      assert(result.begin().base() == buff);48      assert(result[0] == 1);49      assert(result[1] == 2);50      assert(result[2] == 3);51    }52  }53 54  // Test `v | views::transform(f)`55  {56    {57      using Result = std::ranges::transform_view<MoveOnlyView, PlusOne>;58      std::same_as<Result> auto result = MoveOnlyView{buff} | std::views::transform(PlusOne{});59      assert(result.begin().base() == buff);60      assert(result[0] == 1);61      assert(result[1] == 2);62      assert(result[2] == 3);63    }64    {65      auto const partial = std::views::transform(PlusOne{});66      using Result = std::ranges::transform_view<MoveOnlyView, PlusOne>;67      std::same_as<Result> auto result = MoveOnlyView{buff} | partial;68      assert(result.begin().base() == buff);69      assert(result[0] == 1);70      assert(result[1] == 2);71      assert(result[2] == 3);72    }73  }74 75  // Test `views::transform(v, f)`76  {77    using Result = std::ranges::transform_view<MoveOnlyView, PlusOne>;78    std::same_as<Result> auto result = std::views::transform(MoveOnlyView{buff}, PlusOne{});79    assert(result.begin().base() == buff);80    assert(result[0] == 1);81    assert(result[1] == 2);82    assert(result[2] == 3);83  }84 85  // Test that one can call std::views::transform with arbitrary stuff, as long as we86  // don't try to actually complete the call by passing it a range.87  //88  // That makes no sense and we can't do anything with the result, but it's valid.89  {90    struct X { };91    auto partial = std::views::transform(X{});92    (void)partial;93  }94 95  // Test `adaptor | views::transform(f)`96  {97    {98      using Result = std::ranges::transform_view<std::ranges::transform_view<MoveOnlyView, PlusOne>, TimesTwo>;99      std::same_as<Result> auto result = MoveOnlyView{buff} | std::views::transform(PlusOne{}) | std::views::transform(TimesTwo{});100      assert(result.begin().base().base() == buff);101      assert(result[0] == 2);102      assert(result[1] == 4);103      assert(result[2] == 6);104    }105    {106      auto const partial = std::views::transform(PlusOne{}) | std::views::transform(TimesTwo{});107      using Result = std::ranges::transform_view<std::ranges::transform_view<MoveOnlyView, PlusOne>, TimesTwo>;108      std::same_as<Result> auto result = MoveOnlyView{buff} | partial;109      assert(result.begin().base().base() == buff);110      assert(result[0] == 2);111      assert(result[1] == 4);112      assert(result[2] == 6);113    }114  }115 116  // Test SFINAE friendliness117  {118    struct NotAView { };119    struct NotInvocable { };120 121    static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::transform)>);122    static_assert( CanBePiped<MoveOnlyView, decltype(std::views::transform(PlusOne{}))>);123    static_assert(!CanBePiped<NotAView,       decltype(std::views::transform(PlusOne{}))>);124    static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::transform(NotInvocable{}))>);125 126    static_assert(!std::is_invocable_v<decltype(std::views::transform)>);127    static_assert(!std::is_invocable_v<decltype(std::views::transform), PlusOne, MoveOnlyView>);128    static_assert( std::is_invocable_v<decltype(std::views::transform), MoveOnlyView, PlusOne>);129    static_assert(!std::is_invocable_v<decltype(std::views::transform), MoveOnlyView, PlusOne, PlusOne>);130    static_assert(!std::is_invocable_v<decltype(std::views::transform), NonCopyableFunction>);131  }132 133  {134    static_assert(std::is_same_v<decltype(std::ranges::views::transform), decltype(std::views::transform)>);135  }136 137  return true;138}139 140int main(int, char**) {141  test();142  static_assert(test());143 144  return 0;145}146