1 // Copyright (C) 2019-2021 Free Software Foundation, Inc. 2 // 3 // This file is part of the GNU ISO C++ Library. This library is free 4 // software; you can redistribute it and/or modify it under the 5 // terms of the GNU General Public License as published by the 6 // Free Software Foundation; either version 3, or (at your option) 7 // any later version. 8 9 // This library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 14 // You should have received a copy of the GNU General Public License along 15 // with this library; see the file COPYING3. If not see 16 // <http://www.gnu.org/licenses/>. 17 18 // { dg-options "-std=gnu++2a" } 19 // { dg-do run { target c++2a } } 20 21 #include <ranges> 22 #include <testsuite_hooks.h> 23 #include <testsuite_iterators.h> 24 25 void test01()26test01() 27 { 28 constexpr int a[10] = { }; 29 static_assert( std::ranges::size(a) == 10 ); 30 static_assert( noexcept(std::ranges::size(a)) ); 31 32 int a2[2]; 33 VERIFY( std::ranges::size(a2) == 2); 34 static_assert( noexcept(std::ranges::size(a2)) ); 35 36 struct Incomplete; 37 using A = Incomplete[2]; // bounded array of incomplete type 38 extern A& f(); 39 static_assert( std::same_as<decltype(std::ranges::size(f())), std::size_t> ); 40 } 41 42 void test02()43test02() 44 { 45 struct R 46 { 47 int size() { return 1; } 48 long size() const noexcept { return 2; } 49 }; 50 R r; 51 const R& c = r; 52 VERIFY( std::ranges::size(r) == 1 ); 53 static_assert( !noexcept(std::ranges::size(r)) ); 54 VERIFY( std::ranges::size(c) == 2L ); 55 static_assert( noexcept(std::ranges::size(c)) ); 56 57 int a[3] = { }; 58 __gnu_test::test_sized_range<int, __gnu_test::input_iterator_wrapper> ri(a); 59 VERIFY( std::ranges::size(ri) == 3 ); 60 static_assert( noexcept(std::ranges::size(ri)) ); 61 } 62 63 struct R3 64 { sizeR365 int* size() { return nullptr; } size(R3 &)66 friend int size(R3&) noexcept { return 1; } size(const R3 &)67 friend long size(const R3&) { return 2L; } size(R3 &&)68 friend unsigned int size(R3&&) { return 3U; } size(const R3 &&)69 friend unsigned long size(const R3&&) noexcept { return 4UL; } 70 }; 71 72 void test03()73test03() 74 { 75 R3 r; 76 const R3& c = r; 77 VERIFY( std::ranges::size(r) == 1 ); 78 static_assert( noexcept(std::ranges::size(r)) ); 79 // PR libstdc++/100824 80 // ranges::size should treat the subexpression as an lvalue 81 VERIFY( std::ranges::size(std::move(r)) == 1 ); 82 static_assert( noexcept(std::ranges::size(std::move(r))) ); 83 VERIFY( std::ranges::size(c) == 2L ); 84 static_assert( !noexcept(std::ranges::size(c)) ); 85 VERIFY( std::ranges::size(std::move(c)) == 2L ); 86 static_assert( !noexcept(std::ranges::size(std::move(c))) ); 87 } 88 89 void test04()90test04() 91 { 92 int a[] = { 0, 1 }; 93 __gnu_test::test_range<int, __gnu_test::random_access_iterator_wrapper> r(a); 94 VERIFY( std::ranges::size(r) == unsigned(std::ranges::end(r) - std::ranges::begin(r)) ); 95 } 96 97 struct R5 98 { sizeR599 int size() const noexcept { return 0; } beginR5100 R5* begin() { return this; } endR5101 R5* end() { return this + 1; } 102 }; 103 104 template<> 105 constexpr bool std::ranges::disable_sized_range<R5> = true; 106 107 void test05()108test05() 109 { 110 R5 r; 111 VERIFY( std::ranges::size(r) == 1 ); 112 } 113 114 void test06()115test06() 116 { 117 // PR libstdc++/100824 118 // ranges::size should treat the subexpression as an lvalue 119 struct R { constexpr int size() & { return 42; } }; 120 static_assert( std::ranges::size(R{}) == 42 ); 121 } 122 123 int main()124main() 125 { 126 test01(); 127 test02(); 128 test03(); 129 test04(); 130 test05(); 131 test06(); 132 } 133