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