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// std::ranges::ssize
12
13#include <ranges>
14
15#include <cassert>
16#include "test_macros.h"
17#include "test_iterators.h"
18
19using RangeSSizeT = decltype(std::ranges::ssize);
20
21static_assert(!std::is_invocable_v<RangeSSizeT, int[]>);
22static_assert( std::is_invocable_v<RangeSSizeT, int[1]>);
23static_assert( std::is_invocable_v<RangeSSizeT, int (&&)[1]>);
24static_assert( std::is_invocable_v<RangeSSizeT, int (&)[1]>);
25
26struct SizeMember {
27 constexpr std::size_t size() { return 42; }
28};
29static_assert(!std::is_invocable_v<decltype(std::ranges::ssize), const SizeMember&>);
30
31struct SizeFunction {
32 friend constexpr std::size_t size(SizeFunction) { return 42; }
33};
34
35struct SizeFunctionSigned {
36 friend constexpr std::ptrdiff_t size(SizeFunctionSigned) { return 42; }
37};
38
39struct SizedSentinelRange {
40 int data_[2] = {};
41 constexpr int *begin() { return data_; }
42 constexpr auto end() { return sized_sentinel<int*>(data_ + 2); }
43};
44
45struct ShortUnsignedReturnType {
46 constexpr unsigned short size() { return 42; }
47};
48
49// size_t changes depending on the platform.
50using SignedSizeT = std::make_signed_t<std::size_t>;
51
52constexpr bool test() {
53 int a[4];
54
55 assert(std::ranges::ssize(a) == 4);
56 ASSERT_SAME_TYPE(decltype(std::ranges::ssize(a)), SignedSizeT);
57
58 assert(std::ranges::ssize(SizeMember()) == 42);
59 ASSERT_SAME_TYPE(decltype(std::ranges::ssize(SizeMember())), SignedSizeT);
60
61 assert(std::ranges::ssize(SizeFunction()) == 42);
62 ASSERT_SAME_TYPE(decltype(std::ranges::ssize(SizeFunction())), SignedSizeT);
63
64 assert(std::ranges::ssize(SizeFunctionSigned()) == 42);
65 ASSERT_SAME_TYPE(decltype(std::ranges::ssize(SizeFunctionSigned())), std::ptrdiff_t);
66
67 SizedSentinelRange b;
68 assert(std::ranges::ssize(b) == 2);
69 ASSERT_SAME_TYPE(decltype(std::ranges::ssize(b)), std::ptrdiff_t);
70
71 // This gets converted to ptrdiff_t because it's wider.
72 ShortUnsignedReturnType c;
73 assert(std::ranges::ssize(c) == 42);
74 ASSERT_SAME_TYPE(decltype(std::ranges::ssize(c)), std::ptrdiff_t);
75
76 return true;
77}
78
79// Test ADL-proofing.
80struct Incomplete;
81template<class T> struct Holder { T t; };
82static_assert(!std::is_invocable_v<RangeSSizeT, Holder<Incomplete>*>);
83static_assert(!std::is_invocable_v<RangeSSizeT, Holder<Incomplete>*&>);
84
85int main(int, char**) {
86 test();
87 static_assert(test());
88
89 return 0;
90}
91

source code of libcxx/test/std/ranges/range.access/ssize.pass.cpp