1 // Copyright (C) 2020-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 static_assert(__gnu_test::is_customization_point_object(std::ranges::ssize));
26
27 using std::ptrdiff_t;
28
29 void
test01()30 test01()
31 {
32 constexpr int a[10] = { };
33 static_assert( std::same_as<decltype(std::ranges::ssize(a)), ptrdiff_t> );
34 static_assert( std::ranges::ssize(a) == 10 );
35 static_assert( noexcept(std::ranges::ssize(a)) );
36
37 int a2[2];
38 static_assert( std::same_as<decltype(std::ranges::ssize(a2)), ptrdiff_t> );
39 VERIFY( std::ranges::ssize(a2) == 2);
40 static_assert( noexcept(std::ranges::ssize(a2)) );
41 }
42
43 void
test02()44 test02()
45 {
46 int a[3] = { };
47 __gnu_test::test_sized_range<int, __gnu_test::input_iterator_wrapper> ri(a);
48 VERIFY( std::ranges::ssize(ri) == 3 );
49 static_assert( noexcept(std::ranges::ssize(ri)) );
50 }
51
52 void
test04()53 test04()
54 {
55 int a[] = { 0, 1 };
56 __gnu_test::test_range<int, __gnu_test::random_access_iterator_wrapper> r(a);
57 VERIFY( std::ranges::ssize(r) == std::ranges::end(r) - std::ranges::begin(r) );
58 }
59
60 struct R5
61 {
sizeR562 int size() const noexcept { return 0; }
beginR563 R5* begin() { return this; }
endR564 R5* end() { return this + 1; }
65 };
66
67 template<>
68 constexpr bool std::ranges::disable_sized_range<R5> = true;
69
70 void
test05()71 test05()
72 {
73 R5 r;
74 VERIFY( std::ranges::ssize(r) == 1 );
75 }
76
77 void
test06()78 test06()
79 {
80 auto i = std::views::iota(1ull, 5u);
81 auto s = std::ranges::size(i);
82 auto ss = std::ranges::ssize(i);
83 // std::ranges::range_difference_t<decltype(i)> is larger than long long,
84 // but LWG 3403 says ranges::ssize(i) returns the signed version of the
85 // type that ranges::size(i) returns, not the range's difference_type.
86 static_assert( std::same_as<decltype(ss), std::make_signed_t<decltype(s)>> );
87 VERIFY( s == 4 );
88 }
89
90 void
test07()91 test07()
92 {
93 #ifdef __SIZEOF_INT128__
94 struct R
95 {
96 unsigned __int128 size() const { return 4; }
97 };
98 R r;
99 static_assert( std::same_as<decltype(std::ranges::ssize(r)), __int128> );
100 VERIFY( std::ranges::ssize(r) == 4 );
101 #endif
102 }
103
104 int
main()105 main()
106 {
107 test01();
108 test02();
109 test04();
110 test05();
111 test06();
112 test07();
113 }
114