xref: /llvm-project/libcxx/test/std/ranges/range.access/ssize.pass.cpp (revision d868135691bb0d5c924b8fd2ae26171fbf5d1387)
16842f52aSArthur O'Dwyer //===----------------------------------------------------------------------===//
26842f52aSArthur O'Dwyer //
36842f52aSArthur O'Dwyer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
46842f52aSArthur O'Dwyer // See https://llvm.org/LICENSE.txt for license information.
56842f52aSArthur O'Dwyer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66842f52aSArthur O'Dwyer //
76842f52aSArthur O'Dwyer //===----------------------------------------------------------------------===//
86842f52aSArthur O'Dwyer 
96842f52aSArthur O'Dwyer // UNSUPPORTED: c++03, c++11, c++14, c++17
106842f52aSArthur O'Dwyer 
116842f52aSArthur O'Dwyer // std::ranges::ssize
126842f52aSArthur O'Dwyer 
136842f52aSArthur O'Dwyer #include <ranges>
146842f52aSArthur O'Dwyer 
156842f52aSArthur O'Dwyer #include <cassert>
166842f52aSArthur O'Dwyer #include "test_macros.h"
176842f52aSArthur O'Dwyer #include "test_iterators.h"
186842f52aSArthur O'Dwyer 
196842f52aSArthur O'Dwyer using RangeSSizeT = decltype(std::ranges::ssize);
206842f52aSArthur O'Dwyer 
216842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSSizeT, int[]>);
226842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSSizeT, int[1]>);
236842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSSizeT, int (&&)[1]>);
246842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSSizeT, int (&)[1]>);
256842f52aSArthur O'Dwyer 
266842f52aSArthur O'Dwyer struct SizeMember {
sizeSizeMember27fb855eb9SMark de Wever   constexpr std::size_t size() { return 42; }
286842f52aSArthur O'Dwyer };
296842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<decltype(std::ranges::ssize), const SizeMember&>);
306842f52aSArthur O'Dwyer 
316842f52aSArthur O'Dwyer struct SizeFunction {
size(SizeFunction)32fb855eb9SMark de Wever   friend constexpr std::size_t size(SizeFunction) { return 42; }
336842f52aSArthur O'Dwyer };
346842f52aSArthur O'Dwyer 
356842f52aSArthur O'Dwyer struct SizeFunctionSigned {
size(SizeFunctionSigned)366842f52aSArthur O'Dwyer   friend constexpr std::ptrdiff_t size(SizeFunctionSigned) { return 42; }
376842f52aSArthur O'Dwyer };
386842f52aSArthur O'Dwyer 
396842f52aSArthur O'Dwyer struct SizedSentinelRange {
406842f52aSArthur O'Dwyer   int data_[2] = {};
beginSizedSentinelRange416842f52aSArthur O'Dwyer   constexpr int *begin() { return data_; }
endSizedSentinelRange426842f52aSArthur O'Dwyer   constexpr auto end() { return sized_sentinel<int*>(data_ + 2); }
436842f52aSArthur O'Dwyer };
446842f52aSArthur O'Dwyer 
456842f52aSArthur O'Dwyer struct ShortUnsignedReturnType {
sizeShortUnsignedReturnType466842f52aSArthur O'Dwyer   constexpr unsigned short size() { return 42; }
476842f52aSArthur O'Dwyer };
486842f52aSArthur O'Dwyer 
496842f52aSArthur O'Dwyer // size_t changes depending on the platform.
50fb855eb9SMark de Wever using SignedSizeT = std::make_signed_t<std::size_t>;
516842f52aSArthur O'Dwyer 
test()526842f52aSArthur O'Dwyer constexpr bool test() {
536842f52aSArthur O'Dwyer   int a[4];
546842f52aSArthur O'Dwyer 
556842f52aSArthur O'Dwyer   assert(std::ranges::ssize(a) == 4);
566842f52aSArthur O'Dwyer   ASSERT_SAME_TYPE(decltype(std::ranges::ssize(a)), SignedSizeT);
576842f52aSArthur O'Dwyer 
586842f52aSArthur O'Dwyer   assert(std::ranges::ssize(SizeMember()) == 42);
596842f52aSArthur O'Dwyer   ASSERT_SAME_TYPE(decltype(std::ranges::ssize(SizeMember())), SignedSizeT);
606842f52aSArthur O'Dwyer 
616842f52aSArthur O'Dwyer   assert(std::ranges::ssize(SizeFunction()) == 42);
626842f52aSArthur O'Dwyer   ASSERT_SAME_TYPE(decltype(std::ranges::ssize(SizeFunction())), SignedSizeT);
636842f52aSArthur O'Dwyer 
646842f52aSArthur O'Dwyer   assert(std::ranges::ssize(SizeFunctionSigned()) == 42);
656842f52aSArthur O'Dwyer   ASSERT_SAME_TYPE(decltype(std::ranges::ssize(SizeFunctionSigned())), std::ptrdiff_t);
666842f52aSArthur O'Dwyer 
676842f52aSArthur O'Dwyer   SizedSentinelRange b;
686842f52aSArthur O'Dwyer   assert(std::ranges::ssize(b) == 2);
696842f52aSArthur O'Dwyer   ASSERT_SAME_TYPE(decltype(std::ranges::ssize(b)), std::ptrdiff_t);
706842f52aSArthur O'Dwyer 
716842f52aSArthur O'Dwyer   // This gets converted to ptrdiff_t because it's wider.
726842f52aSArthur O'Dwyer   ShortUnsignedReturnType c;
736842f52aSArthur O'Dwyer   assert(std::ranges::ssize(c) == 42);
74*d8681356SMark de Wever   ASSERT_SAME_TYPE(decltype(std::ranges::ssize(c)), std::ptrdiff_t);
756842f52aSArthur O'Dwyer 
766842f52aSArthur O'Dwyer   return true;
776842f52aSArthur O'Dwyer }
786842f52aSArthur O'Dwyer 
7985073836SArthur O'Dwyer // Test ADL-proofing.
8085073836SArthur O'Dwyer struct Incomplete;
8185073836SArthur O'Dwyer template<class T> struct Holder { T t; };
8285073836SArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSSizeT, Holder<Incomplete>*>);
839be193bcSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSSizeT, Holder<Incomplete>*&>);
8485073836SArthur O'Dwyer 
main(int,char **)856842f52aSArthur O'Dwyer int main(int, char**) {
866842f52aSArthur O'Dwyer   test();
876842f52aSArthur O'Dwyer   static_assert(test());
886842f52aSArthur O'Dwyer 
896842f52aSArthur O'Dwyer   return 0;
906842f52aSArthur O'Dwyer }
91