179 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::elements<N>12// std::views::keys13// std::views::values14 15#include <algorithm>16#include <cassert>17#include <ranges>18#include <tuple>19#include <type_traits>20#include <utility>21 22#include "test_range.h"23 24template <class T>25struct View : std::ranges::view_base {26 T* begin() const;27 T* end() const;28};29 30static_assert(!std::is_invocable_v<decltype((std::views::elements<0>))>);31static_assert(!std::is_invocable_v<decltype((std::views::elements<0>)), View<int>>);32static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::pair<int, int>>>);33static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::tuple<int>>>);34static_assert(!std::is_invocable_v<decltype((std::views::elements<5>)), View<std::tuple<int>>>);35 36static_assert(!std::is_invocable_v<decltype((std::views::keys))>);37static_assert(!std::is_invocable_v<decltype((std::views::keys)), View<int>>);38static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::pair<int, int>>>);39static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::tuple<int>>>);40 41static_assert(!std::is_invocable_v<decltype((std::views::values))>);42static_assert(!std::is_invocable_v<decltype((std::views::values)), View<int>>);43static_assert(std::is_invocable_v<decltype((std::views::values)), View<std::pair<int, int>>>);44static_assert(!std::is_invocable_v<decltype((std::views::values)), View<std::tuple<int>>>);45 46static_assert(!CanBePiped<View<int>, decltype((std::views::elements<0>))>);47static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::elements<0>))>);48static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<0>))>);49static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<5>))>);50 51static_assert(!CanBePiped<View<int>, decltype((std::views::keys))>);52static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::keys))>);53static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::keys))>);54 55static_assert(!CanBePiped<View<int>, decltype((std::views::values))>);56static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::values))>);57static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::values))>);58 59constexpr bool test() {60 std::pair<int, int> buff[] = {{1, 2}, {3, 4}, {5, 6}};61 62 // Test `views::elements<N>(v)`63 {64 using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>;65 std::same_as<Result> decltype(auto) result = std::views::elements<0>(buff);66 auto expected = {1, 3, 5};67 assert(std::ranges::equal(result, expected));68 }69 70 // Test `views::keys(v)`71 {72 using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>;73 std::same_as<Result> decltype(auto) result = std::views::keys(buff);74 auto expected = {1, 3, 5};75 assert(std::ranges::equal(result, expected));76 }77 78 // Test `views::values(v)`79 {80 using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>;81 std::same_as<Result> decltype(auto) result = std::views::values(buff);82 auto expected = {2, 4, 6};83 assert(std::ranges::equal(result, expected));84 }85 86 // Test `v | views::elements<N>`87 {88 using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>;89 std::same_as<Result> decltype(auto) result = buff | std::views::elements<1>;90 auto expected = {2, 4, 6};91 assert(std::ranges::equal(result, expected));92 }93 94 // Test `v | views::keys`95 {96 using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>;97 std::same_as<Result> decltype(auto) result = buff | std::views::keys;98 auto expected = {1, 3, 5};99 assert(std::ranges::equal(result, expected));100 }101 102 // Test `v | views::values`103 {104 using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>;105 std::same_as<Result> decltype(auto) result = buff | std::views::values;106 auto expected = {2, 4, 6};107 assert(std::ranges::equal(result, expected));108 }109 110 // Test views::elements<0> | views::elements<0>111 {112 std::pair<std::tuple<int>, std::tuple<int>> nested[] = {{{1}, {2}}, {{3}, {4}}, {{5}, {6}}};113 using Result = std::ranges::elements_view<114 std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int>>[3]>, 0>,115 0>;116 auto const partial = std::views::elements<0> | std::views::elements<0>;117 std::same_as<Result> decltype(auto) result = nested | partial;118 auto expected = {1, 3, 5};119 assert(std::ranges::equal(result, expected));120 }121 122 // Test views::keys | views::keys123 {124 std::pair<std::tuple<int>, std::tuple<int>> nested[] = {{{1}, {2}}, {{3}, {4}}, {{5}, {6}}};125 using Result = std::ranges::elements_view<126 std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int>>[3]>, 0>,127 0>;128 auto const partial = std::views::keys | std::views::keys;129 std::same_as<Result> decltype(auto) result = nested | partial;130 auto expected = {1, 3, 5};131 assert(std::ranges::equal(result, expected));132 }133 134 // Test views::values | views::values135 {136 std::pair<std::tuple<int>, std::tuple<int, int>> nested[] = {{{1}, {2, 3}}, {{4}, {5, 6}}, {{7}, {8, 9}}};137 using Result = std::ranges::elements_view<138 std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int, int>>[3]>, 1>,139 1>;140 auto const partial = std::views::values | std::views::values;141 std::same_as<Result> decltype(auto) result = nested | partial;142 auto expected = {3, 6, 9};143 assert(std::ranges::equal(result, expected));144 }145 146 // Test views::keys | views::values147 {148 std::pair<std::tuple<int, int>, std::tuple<int>> nested[] = {{{1, 2}, {3}}, {{4, 5}, {6}}, {{7, 8}, {9}}};149 using Result = std::ranges::elements_view<150 std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int, int>, std::tuple<int>>[3]>, 0>,151 1>;152 auto const partial = std::views::keys | std::views::values;153 std::same_as<Result> decltype(auto) result = nested | partial;154 auto expected = {2, 5, 8};155 assert(std::ranges::equal(result, expected));156 }157 158 // Test views::values | views::keys159 {160 std::pair<std::tuple<int>, std::tuple<int, int>> nested[] = {{{1}, {2, 3}}, {{4}, {5, 6}}, {{7}, {8, 9}}};161 using Result = std::ranges::elements_view<162 std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int, int>>[3]>, 1>,163 0>;164 auto const partial = std::views::values | std::views::keys;165 std::same_as<Result> decltype(auto) result = nested | partial;166 auto expected = {2, 5, 8};167 assert(std::ranges::equal(result, expected));168 }169 170 return true;171}172 173int main(int, char**) {174 test();175 static_assert(test());176 177 return 0;178}179