xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp (revision b2cc4b994e5fb85053b1acedec5ea0d1d42e5ec4)
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // Some basic examples of how elements_view might be used in the wild. This is a general
12 // collection of sample algorithms and functions that try to mock general usage of
13 // this view.
14 
15 #include <algorithm>
16 #include <array>
17 #include <cassert>
18 #include <map>
19 #include <ranges>
20 #include <string_view>
21 #include <tuple>
22 #include <utility>
23 
24 #include "test_iterators.h"
25 
main(int,char **)26 int main(int, char**) {
27   using namespace std::string_view_literals;
28   auto historicalFigures =
29       std::map{std::pair{"Lovelace"sv, 1815}, {"Turing"sv, 1912}, {"Babbage"sv, 1791}, {"Hamilton"sv, 1936}};
30   auto expectedYears = {1791, 1936, 1815, 1912};
31 
32   // views::elements<N>
33   {
34     auto names         = historicalFigures | std::views::elements<0>;
35     auto expectedNames = {"Babbage"sv, "Hamilton"sv, "Lovelace"sv, "Turing"sv};
36     assert(std::ranges::equal(names, expectedNames));
37 
38     auto birth_years = historicalFigures | std::views::elements<1>;
39     assert(std::ranges::equal(birth_years, expectedYears));
40   }
41 
42   // views::keys
43   {
44     auto names         = historicalFigures | std::views::keys;
45     auto expectedNames = {"Babbage"sv, "Hamilton"sv, "Lovelace"sv, "Turing"sv};
46     assert(std::ranges::equal(names, expectedNames));
47   }
48 
49   // views::values
50   {
51     auto is_even = [](const auto x) { return x % 2 == 0; };
52     assert(std::ranges::count_if(historicalFigures | std::views::values, is_even) == 2);
53   }
54 
55   // array
56   {
57     std::array<int, 3> arrs[] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
58     auto ev                   = arrs | std::views::elements<2>;
59     auto expected             = {3, 6, 9};
60     assert(std::ranges::equal(ev, expected));
61   }
62 
63   // pair
64   {
65     std::pair<double, int> ps[] = {{1.0, 2}, {3.0, 4}, {5.0, 6}};
66     auto ev                     = ps | std::views::elements<1>;
67     auto expected               = {2, 4, 6};
68     assert(std::ranges::equal(ev, expected));
69   }
70 
71   // tuple
72   {
73     std::tuple<short> tps[] = {{short{1}}, {short{2}}, {short{3}}};
74     auto ev                 = tps | std::views::elements<0>;
75     auto expected           = {1, 2, 3};
76     assert(std::ranges::equal(ev, expected));
77   }
78 
79   // subrange
80   {
81     int is[]       = {1, 2, 3, 4, 5, 6, 7, 8, 9};
82     using Iter     = forward_iterator<int*>;
83     using Sent     = sentinel_wrapper<Iter>;
84     using SubRange = std::ranges::subrange<Iter, Sent>;
85     SubRange sr[]  = {
86         {Iter{is}, Sent{Iter{is + 1}}},
87         {Iter{is + 2}, Sent{Iter{is + 5}}},
88         {Iter{is + 6}, Sent{Iter{is + 8}}},
89     };
90 
91     auto iters = sr | std::views::elements<0>;
92     static_assert(std::is_same_v<Iter, std::ranges::range_reference_t<decltype(iters)>>);
93     auto expectedIters = {is, is + 2, is + 6};
94     assert(std::ranges::equal(iters | std::views::transform([](auto&& iter) { return base(iter); }), expectedIters));
95 
96     auto sentinels = sr | std::views::elements<1>;
97     static_assert(std::is_same_v<Sent, std::ranges::range_reference_t<decltype(sentinels)>>);
98     auto expectedSentinels = {is + 1, is + 5, is + 8};
99     assert(std::ranges::equal(
100         sentinels | std::views::transform([](auto&& st) { return base(base(st)); }), expectedSentinels));
101   }
102   return 0;
103 }
104