194461822SHui Xie //===----------------------------------------------------------------------===//
294461822SHui Xie //
394461822SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
494461822SHui Xie // See https://llvm.org/LICENSE.txt for license information.
594461822SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
694461822SHui Xie //
794461822SHui Xie //===----------------------------------------------------------------------===//
894461822SHui Xie
994461822SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17
1094461822SHui Xie
1194461822SHui Xie // std::views::elements<N>
1294461822SHui Xie // std::views::keys
1394461822SHui Xie // std::views::values
1494461822SHui Xie
1594461822SHui Xie #include <algorithm>
1694461822SHui Xie #include <cassert>
1794461822SHui Xie #include <ranges>
1894461822SHui Xie #include <tuple>
1994461822SHui Xie #include <type_traits>
2094461822SHui Xie #include <utility>
2194461822SHui Xie
22*ba2236d3SWill Hawkins #include "test_range.h"
23*ba2236d3SWill Hawkins
2494461822SHui Xie template <class T>
2594461822SHui Xie struct View : std::ranges::view_base {
2694461822SHui Xie T* begin() const;
2794461822SHui Xie T* end() const;
2894461822SHui Xie };
2994461822SHui Xie
3094461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::elements<0>))>);
3194461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::elements<0>)), View<int>>);
3294461822SHui Xie static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::pair<int, int>>>);
3394461822SHui Xie static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::tuple<int>>>);
3494461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::elements<5>)), View<std::tuple<int>>>);
3594461822SHui Xie
3694461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::keys))>);
3794461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::keys)), View<int>>);
3894461822SHui Xie static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::pair<int, int>>>);
3994461822SHui Xie static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::tuple<int>>>);
4094461822SHui Xie
4194461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::values))>);
4294461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::values)), View<int>>);
4394461822SHui Xie static_assert(std::is_invocable_v<decltype((std::views::values)), View<std::pair<int, int>>>);
4494461822SHui Xie static_assert(!std::is_invocable_v<decltype((std::views::values)), View<std::tuple<int>>>);
4594461822SHui Xie
4694461822SHui Xie static_assert(!CanBePiped<View<int>, decltype((std::views::elements<0>))>);
4794461822SHui Xie static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::elements<0>))>);
4894461822SHui Xie static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<0>))>);
4994461822SHui Xie static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<5>))>);
5094461822SHui Xie
5194461822SHui Xie static_assert(!CanBePiped<View<int>, decltype((std::views::keys))>);
5294461822SHui Xie static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::keys))>);
5394461822SHui Xie static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::keys))>);
5494461822SHui Xie
5594461822SHui Xie static_assert(!CanBePiped<View<int>, decltype((std::views::values))>);
5694461822SHui Xie static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::values))>);
5794461822SHui Xie static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::values))>);
5894461822SHui Xie
test()5994461822SHui Xie constexpr bool test() {
6094461822SHui Xie std::pair<int, int> buff[] = {{1, 2}, {3, 4}, {5, 6}};
6194461822SHui Xie
6294461822SHui Xie // Test `views::elements<N>(v)`
6394461822SHui Xie {
6494461822SHui Xie using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>;
6594461822SHui Xie std::same_as<Result> decltype(auto) result = std::views::elements<0>(buff);
6694461822SHui Xie auto expected = {1, 3, 5};
6794461822SHui Xie assert(std::ranges::equal(result, expected));
6894461822SHui Xie }
6994461822SHui Xie
7094461822SHui Xie // Test `views::keys(v)`
7194461822SHui Xie {
7294461822SHui Xie using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>;
7394461822SHui Xie std::same_as<Result> decltype(auto) result = std::views::keys(buff);
7494461822SHui Xie auto expected = {1, 3, 5};
7594461822SHui Xie assert(std::ranges::equal(result, expected));
7694461822SHui Xie }
7794461822SHui Xie
7894461822SHui Xie // Test `views::values(v)`
7994461822SHui Xie {
8094461822SHui Xie using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>;
8194461822SHui Xie std::same_as<Result> decltype(auto) result = std::views::values(buff);
8294461822SHui Xie auto expected = {2, 4, 6};
8394461822SHui Xie assert(std::ranges::equal(result, expected));
8494461822SHui Xie }
8594461822SHui Xie
8694461822SHui Xie // Test `v | views::elements<N>`
8794461822SHui Xie {
8894461822SHui Xie using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>;
8994461822SHui Xie std::same_as<Result> decltype(auto) result = buff | std::views::elements<1>;
9094461822SHui Xie auto expected = {2, 4, 6};
9194461822SHui Xie assert(std::ranges::equal(result, expected));
9294461822SHui Xie }
9394461822SHui Xie
9494461822SHui Xie // Test `v | views::keys`
9594461822SHui Xie {
9694461822SHui Xie using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>;
9794461822SHui Xie std::same_as<Result> decltype(auto) result = buff | std::views::keys;
9894461822SHui Xie auto expected = {1, 3, 5};
9994461822SHui Xie assert(std::ranges::equal(result, expected));
10094461822SHui Xie }
10194461822SHui Xie
10294461822SHui Xie // Test `v | views::values`
10394461822SHui Xie {
10494461822SHui Xie using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>;
10594461822SHui Xie std::same_as<Result> decltype(auto) result = buff | std::views::values;
10694461822SHui Xie auto expected = {2, 4, 6};
10794461822SHui Xie assert(std::ranges::equal(result, expected));
10894461822SHui Xie }
10994461822SHui Xie
11094461822SHui Xie // Test views::elements<0> | views::elements<0>
11194461822SHui Xie {
11294461822SHui Xie std::pair<std::tuple<int>, std::tuple<int>> nested[] = {{{1}, {2}}, {{3}, {4}}, {{5}, {6}}};
11394461822SHui Xie using Result = std::ranges::elements_view<
11494461822SHui Xie std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int>>[3]>, 0>,
11594461822SHui Xie 0>;
11694461822SHui Xie auto const partial = std::views::elements<0> | std::views::elements<0>;
11794461822SHui Xie std::same_as<Result> decltype(auto) result = nested | partial;
11894461822SHui Xie auto expected = {1, 3, 5};
11994461822SHui Xie assert(std::ranges::equal(result, expected));
12094461822SHui Xie }
12194461822SHui Xie
12294461822SHui Xie // Test views::keys | views::keys
12394461822SHui Xie {
12494461822SHui Xie std::pair<std::tuple<int>, std::tuple<int>> nested[] = {{{1}, {2}}, {{3}, {4}}, {{5}, {6}}};
12594461822SHui Xie using Result = std::ranges::elements_view<
12694461822SHui Xie std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int>>[3]>, 0>,
12794461822SHui Xie 0>;
12894461822SHui Xie auto const partial = std::views::keys | std::views::keys;
12994461822SHui Xie std::same_as<Result> decltype(auto) result = nested | partial;
13094461822SHui Xie auto expected = {1, 3, 5};
13194461822SHui Xie assert(std::ranges::equal(result, expected));
13294461822SHui Xie }
13394461822SHui Xie
13494461822SHui Xie // Test views::values | views::values
13594461822SHui Xie {
13694461822SHui Xie std::pair<std::tuple<int>, std::tuple<int, int>> nested[] = {{{1}, {2, 3}}, {{4}, {5, 6}}, {{7}, {8, 9}}};
13794461822SHui Xie using Result = std::ranges::elements_view<
13894461822SHui Xie std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int, int>>[3]>, 1>,
13994461822SHui Xie 1>;
14094461822SHui Xie auto const partial = std::views::values | std::views::values;
14194461822SHui Xie std::same_as<Result> decltype(auto) result = nested | partial;
14294461822SHui Xie auto expected = {3, 6, 9};
14394461822SHui Xie assert(std::ranges::equal(result, expected));
14494461822SHui Xie }
14594461822SHui Xie
14694461822SHui Xie // Test views::keys | views::values
14794461822SHui Xie {
14894461822SHui Xie std::pair<std::tuple<int, int>, std::tuple<int>> nested[] = {{{1, 2}, {3}}, {{4, 5}, {6}}, {{7, 8}, {9}}};
14994461822SHui Xie using Result = std::ranges::elements_view<
15094461822SHui Xie std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int, int>, std::tuple<int>>[3]>, 0>,
15194461822SHui Xie 1>;
15294461822SHui Xie auto const partial = std::views::keys | std::views::values;
15394461822SHui Xie std::same_as<Result> decltype(auto) result = nested | partial;
15494461822SHui Xie auto expected = {2, 5, 8};
15594461822SHui Xie assert(std::ranges::equal(result, expected));
15694461822SHui Xie }
15794461822SHui Xie
15894461822SHui Xie // Test views::values | views::keys
15994461822SHui Xie {
16094461822SHui Xie std::pair<std::tuple<int>, std::tuple<int, int>> nested[] = {{{1}, {2, 3}}, {{4}, {5, 6}}, {{7}, {8, 9}}};
16194461822SHui Xie using Result = std::ranges::elements_view<
16294461822SHui Xie std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int, int>>[3]>, 1>,
16394461822SHui Xie 0>;
16494461822SHui Xie auto const partial = std::views::values | std::views::keys;
16594461822SHui Xie std::same_as<Result> decltype(auto) result = nested | partial;
16694461822SHui Xie auto expected = {2, 5, 8};
16794461822SHui Xie assert(std::ranges::equal(result, expected));
16894461822SHui Xie }
16994461822SHui Xie
17094461822SHui Xie return true;
17194461822SHui Xie }
17294461822SHui Xie
main(int,char **)17394461822SHui Xie int main(int, char**) {
17494461822SHui Xie test();
17594461822SHui Xie static_assert(test());
17694461822SHui Xie
17794461822SHui Xie return 0;
17894461822SHui Xie }
179