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 19 using RangeSSizeT = decltype(std::ranges::ssize); 20 21 static_assert(!std::is_invocable_v<RangeSSizeT, int[]>); 22 static_assert( std::is_invocable_v<RangeSSizeT, int[1]>); 23 static_assert( std::is_invocable_v<RangeSSizeT, int (&&)[1]>); 24 static_assert( std::is_invocable_v<RangeSSizeT, int (&)[1]>); 25 26 struct SizeMember { 27 constexpr std::size_t size() { return 42; } 28 }; 29 static_assert(!std::is_invocable_v<decltype(std::ranges::ssize), const SizeMember&>); 30 31 struct SizeFunction { 32 friend constexpr std::size_t size(SizeFunction) { return 42; } 33 }; 34 35 struct SizeFunctionSigned { 36 friend constexpr std::ptrdiff_t size(SizeFunctionSigned) { return 42; } 37 }; 38 39 struct SizedSentinelRange { 40 int data_[2] = {}; 41 constexpr int *begin() { return data_; } 42 constexpr auto end() { return sized_sentinel<int*>(data_ + 2); } 43 }; 44 45 struct ShortUnsignedReturnType { 46 constexpr unsigned short size() { return 42; } 47 }; 48 49 // size_t changes depending on the platform. 50 using SignedSizeT = std::make_signed_t<std::size_t>; 51 52 constexpr 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)), ptrdiff_t); 75 76 return true; 77 } 78 79 // Test ADL-proofing. 80 struct Incomplete; 81 template<class T> struct Holder { T t; }; 82 static_assert(!std::is_invocable_v<RangeSSizeT, Holder<Incomplete>*>); 83 static_assert(!std::is_invocable_v<RangeSSizeT, Holder<Incomplete>*&>); 84 85 int main(int, char**) { 86 test(); 87 static_assert(test()); 88 89 return 0; 90 } 91