// Copyright (C) 2020 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . // { dg-options "-std=gnu++2a" } // { dg-do run { target c++2a } } #include #include #include #include using __gnu_test::test_range; using __gnu_test::random_access_iterator_wrapper; namespace ranges = std::ranges; namespace views = std::ranges::views; void test01() { int x[] = {1,2,3,4,5}; auto is_odd = [] (int i) { return i%2==1; }; auto v = x | views::transform(is_odd); VERIFY( ranges::equal(v, (int[]){1,0,1,0,1}) ); using R = decltype(v); static_assert(std::same_as); static_assert(ranges::view); static_assert(ranges::sized_range); static_assert(ranges::random_access_range); } struct X { int i,j; }; void test02() { X x[] = {{1,2},{3,4},{5,6},{7,8},{9,10}}; test_range rx(x); auto v = rx | views::transform(&X::i); VERIFY( ranges::size(v) == 5 ); VERIFY( ranges::distance(v.begin(), v.end()) == 5 ); VERIFY( ranges::equal(v, (int[]){1,3,5,7,9}) ); VERIFY( ranges::equal(v | views::reverse, (int[]){9,7,5,3,1}) ); using R = decltype(v); static_assert(std::same_as); static_assert(std::same_as>>); static_assert(ranges::view); static_assert(ranges::sized_range); static_assert(!ranges::common_range); static_assert(ranges::random_access_range); } void test03() { auto id = [] (int i) { return i; }; auto v = views::iota(0) | (views::filter(id) | views::transform(id) | views::take(5)); VERIFY( ranges::equal(v, (int[]){1,2,3,4,5}) ); } void test04() { // LWG 3301 { auto f = [] (int x) { return x; }; int x[] = {1,2,3,4,5}; auto v = x | views::transform(f); auto i = v.begin(); using Cat = decltype(i)::iterator_category; static_assert(std::same_as); } { auto f = [] (int &x) -> int& { return x; }; int x[] = {1,2,3,4,5}; auto v = x | views::transform(f); auto i = v.begin(); using Cat = decltype(i)::iterator_category; static_assert(std::derived_from); } } void test05() { int x[] = {1,2,3,4,5}; auto i = std::counted_iterator(x, 5); auto r = ranges::subrange{i, std::default_sentinel}; auto v = r | views::transform(std::negate{}); // Verify that _Iterator is implicitly convertible to _Iterator. static_assert(!std::same_as); auto a = ranges::cbegin(v); a = ranges::begin(v); // Verify that _Sentinel is implicitly convertible to _Sentinel. static_assert(!ranges::common_range); static_assert(!std::same_as); auto b = ranges::cend(v); b = ranges::end(v); } struct Y { using Iter = __gnu_test::forward_iterator_wrapper; friend auto operator-(Iter l, Iter r) { return l.ptr - r.ptr; } }; void test06() { using ranges::next; using ranges::begin; // LWG 3483 Y y[3]; __gnu_test::test_forward_range r(y); auto v = views::transform(r, std::identity{}); auto b = begin(v); static_assert( !ranges::random_access_range ); static_assert( std::sized_sentinel_for ); VERIFY( (next(b, 1) - b) == 1 ); const auto v_const = v; auto b_const = begin(v_const); VERIFY( (next(b_const, 2) - b_const) == 2 ); } int main() { test01(); test02(); test03(); test04(); test05(); test06(); }