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::size
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 RangeSizeT = decltype(std::ranges::size);
206842f52aSArthur O'Dwyer
216842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, int[]>);
226842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, int[1]>);
236842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, int (&&)[1]>);
246842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, int (&)[1]>);
256842f52aSArthur O'Dwyer
266842f52aSArthur O'Dwyer struct Incomplete;
276842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, Incomplete[]>);
286842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, Incomplete(&)[]>);
296842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, Incomplete(&&)[]>);
306842f52aSArthur O'Dwyer
316842f52aSArthur O'Dwyer extern Incomplete array_of_incomplete[42];
326842f52aSArthur O'Dwyer static_assert(std::ranges::size(array_of_incomplete) == 42);
336842f52aSArthur O'Dwyer static_assert(std::ranges::size(std::move(array_of_incomplete)) == 42);
346842f52aSArthur O'Dwyer static_assert(std::ranges::size(std::as_const(array_of_incomplete)) == 42);
356842f52aSArthur O'Dwyer static_assert(std::ranges::size(static_cast<const Incomplete(&&)[42]>(array_of_incomplete)) == 42);
366842f52aSArthur O'Dwyer
376842f52aSArthur O'Dwyer struct SizeMember {
sizeSizeMember38fb855eb9SMark de Wever constexpr std::size_t size() { return 42; }
396842f52aSArthur O'Dwyer };
406842f52aSArthur O'Dwyer
416842f52aSArthur O'Dwyer struct StaticSizeMember {
sizeStaticSizeMember42fb855eb9SMark de Wever constexpr static std::size_t size() { return 42; }
436842f52aSArthur O'Dwyer };
446842f52aSArthur O'Dwyer
456842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, const SizeMember>);
466842f52aSArthur O'Dwyer
476842f52aSArthur O'Dwyer struct SizeFunction {
size(SizeFunction)48fb855eb9SMark de Wever friend constexpr std::size_t size(SizeFunction) { return 42; }
496842f52aSArthur O'Dwyer };
506842f52aSArthur O'Dwyer
516842f52aSArthur O'Dwyer // Make sure the size member is preferred.
526842f52aSArthur O'Dwyer struct SizeMemberAndFunction {
sizeSizeMemberAndFunction53fb855eb9SMark de Wever constexpr std::size_t size() { return 42; }
size(SizeMemberAndFunction)54fb855eb9SMark de Wever friend constexpr std::size_t size(SizeMemberAndFunction) { return 0; }
556842f52aSArthur O'Dwyer };
566842f52aSArthur O'Dwyer
testArrayType()576842f52aSArthur O'Dwyer bool constexpr testArrayType() {
586842f52aSArthur O'Dwyer int a[4];
596842f52aSArthur O'Dwyer int b[1];
606842f52aSArthur O'Dwyer SizeMember c[4];
616842f52aSArthur O'Dwyer SizeFunction d[4];
626842f52aSArthur O'Dwyer
636842f52aSArthur O'Dwyer assert(std::ranges::size(a) == 4);
64fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(a)), std::size_t);
656842f52aSArthur O'Dwyer assert(std::ranges::size(b) == 1);
66fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(b)), std::size_t);
676842f52aSArthur O'Dwyer assert(std::ranges::size(c) == 4);
68fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(c)), std::size_t);
696842f52aSArthur O'Dwyer assert(std::ranges::size(d) == 4);
70fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(d)), std::size_t);
716842f52aSArthur O'Dwyer
726842f52aSArthur O'Dwyer return true;
736842f52aSArthur O'Dwyer }
746842f52aSArthur O'Dwyer
756842f52aSArthur O'Dwyer struct SizeMemberConst {
sizeSizeMemberConst76fb855eb9SMark de Wever constexpr std::size_t size() const { return 42; }
776842f52aSArthur O'Dwyer };
786842f52aSArthur O'Dwyer
796842f52aSArthur O'Dwyer struct SizeMemberSigned {
sizeSizeMemberSigned806842f52aSArthur O'Dwyer constexpr long size() { return 42; }
816842f52aSArthur O'Dwyer };
826842f52aSArthur O'Dwyer
testHasSizeMember()836842f52aSArthur O'Dwyer bool constexpr testHasSizeMember() {
846842f52aSArthur O'Dwyer assert(std::ranges::size(SizeMember()) == 42);
85fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(SizeMember())), std::size_t);
866842f52aSArthur O'Dwyer
876842f52aSArthur O'Dwyer const SizeMemberConst sizeMemberConst;
886842f52aSArthur O'Dwyer assert(std::ranges::size(sizeMemberConst) == 42);
896842f52aSArthur O'Dwyer
906842f52aSArthur O'Dwyer assert(std::ranges::size(SizeMemberAndFunction()) == 42);
916842f52aSArthur O'Dwyer
926842f52aSArthur O'Dwyer assert(std::ranges::size(SizeMemberSigned()) == 42);
936842f52aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(std::ranges::size(SizeMemberSigned())), long);
946842f52aSArthur O'Dwyer
956842f52aSArthur O'Dwyer assert(std::ranges::size(StaticSizeMember()) == 42);
96fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(StaticSizeMember())), std::size_t);
976842f52aSArthur O'Dwyer
986842f52aSArthur O'Dwyer return true;
996842f52aSArthur O'Dwyer }
1006842f52aSArthur O'Dwyer
1016842f52aSArthur O'Dwyer struct MoveOnlySizeFunction {
1026842f52aSArthur O'Dwyer MoveOnlySizeFunction() = default;
1036842f52aSArthur O'Dwyer MoveOnlySizeFunction(MoveOnlySizeFunction &&) = default;
1046842f52aSArthur O'Dwyer MoveOnlySizeFunction(MoveOnlySizeFunction const&) = delete;
1056842f52aSArthur O'Dwyer
size(MoveOnlySizeFunction)106fb855eb9SMark de Wever friend constexpr std::size_t size(MoveOnlySizeFunction) { return 42; }
1076842f52aSArthur O'Dwyer };
1086842f52aSArthur O'Dwyer
1096842f52aSArthur O'Dwyer enum EnumSizeFunction {
1106842f52aSArthur O'Dwyer a, b
1116842f52aSArthur O'Dwyer };
1126842f52aSArthur O'Dwyer
size(EnumSizeFunction)113fb855eb9SMark de Wever constexpr std::size_t size(EnumSizeFunction) { return 42; }
1146842f52aSArthur O'Dwyer
1156842f52aSArthur O'Dwyer struct SizeFunctionConst {
size(const SizeFunctionConst)116fb855eb9SMark de Wever friend constexpr std::size_t size(const SizeFunctionConst) { return 42; }
1176842f52aSArthur O'Dwyer };
1186842f52aSArthur O'Dwyer
1196842f52aSArthur O'Dwyer struct SizeFunctionRef {
size(SizeFunctionRef &)120fb855eb9SMark de Wever friend constexpr std::size_t size(SizeFunctionRef&) { return 42; }
1216842f52aSArthur O'Dwyer };
1226842f52aSArthur O'Dwyer
1236842f52aSArthur O'Dwyer struct SizeFunctionConstRef {
size(SizeFunctionConstRef const &)124fb855eb9SMark de Wever friend constexpr std::size_t size(SizeFunctionConstRef const&) { return 42; }
1256842f52aSArthur O'Dwyer };
1266842f52aSArthur O'Dwyer
1276842f52aSArthur O'Dwyer struct SizeFunctionSigned {
size(SizeFunctionSigned)1286842f52aSArthur O'Dwyer friend constexpr long size(SizeFunctionSigned) { return 42; }
1296842f52aSArthur O'Dwyer };
1306842f52aSArthur O'Dwyer
testHasSizeFunction()1316842f52aSArthur O'Dwyer bool constexpr testHasSizeFunction() {
1326842f52aSArthur O'Dwyer assert(std::ranges::size(SizeFunction()) == 42);
133fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(SizeFunction())), std::size_t);
1346842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, MoveOnlySizeFunction>);
1356842f52aSArthur O'Dwyer assert(std::ranges::size(EnumSizeFunction()) == 42);
1366842f52aSArthur O'Dwyer assert(std::ranges::size(SizeFunctionConst()) == 42);
1376842f52aSArthur O'Dwyer
1386842f52aSArthur O'Dwyer SizeFunctionRef a;
1396842f52aSArthur O'Dwyer assert(std::ranges::size(a) == 42);
1406842f52aSArthur O'Dwyer
1416842f52aSArthur O'Dwyer const SizeFunctionConstRef b;
1426842f52aSArthur O'Dwyer assert(std::ranges::size(b) == 42);
1436842f52aSArthur O'Dwyer
1446842f52aSArthur O'Dwyer assert(std::ranges::size(SizeFunctionSigned()) == 42);
1456842f52aSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(std::ranges::size(SizeFunctionSigned())), long);
1466842f52aSArthur O'Dwyer
1476842f52aSArthur O'Dwyer return true;
1486842f52aSArthur O'Dwyer }
1496842f52aSArthur O'Dwyer
1506842f52aSArthur O'Dwyer struct Empty { };
1516842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, Empty>);
1526842f52aSArthur O'Dwyer
1536842f52aSArthur O'Dwyer struct InvalidReturnTypeMember {
1546842f52aSArthur O'Dwyer Empty size();
1556842f52aSArthur O'Dwyer };
1566842f52aSArthur O'Dwyer
1576842f52aSArthur O'Dwyer struct InvalidReturnTypeFunction {
1586842f52aSArthur O'Dwyer friend Empty size(InvalidReturnTypeFunction);
1596842f52aSArthur O'Dwyer };
1606842f52aSArthur O'Dwyer
1616842f52aSArthur O'Dwyer struct Convertible {
162fb855eb9SMark de Wever operator std::size_t();
1636842f52aSArthur O'Dwyer };
1646842f52aSArthur O'Dwyer
1656842f52aSArthur O'Dwyer struct ConvertibleReturnTypeMember {
1666842f52aSArthur O'Dwyer Convertible size();
1676842f52aSArthur O'Dwyer };
1686842f52aSArthur O'Dwyer
1696842f52aSArthur O'Dwyer struct ConvertibleReturnTypeFunction {
1706842f52aSArthur O'Dwyer friend Convertible size(ConvertibleReturnTypeFunction);
1716842f52aSArthur O'Dwyer };
1726842f52aSArthur O'Dwyer
1736842f52aSArthur O'Dwyer struct BoolReturnTypeMember {
1746842f52aSArthur O'Dwyer bool size() const;
1756842f52aSArthur O'Dwyer };
1766842f52aSArthur O'Dwyer
1776842f52aSArthur O'Dwyer struct BoolReturnTypeFunction {
1786842f52aSArthur O'Dwyer friend bool size(BoolReturnTypeFunction const&);
1796842f52aSArthur O'Dwyer };
1806842f52aSArthur O'Dwyer
1816842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, InvalidReturnTypeMember>);
1826842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, InvalidReturnTypeFunction>);
1836842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, InvalidReturnTypeMember (&)[4]>);
1846842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, InvalidReturnTypeFunction (&)[4]>);
1856842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, ConvertibleReturnTypeMember>);
1866842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, ConvertibleReturnTypeFunction>);
1876842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, BoolReturnTypeMember const&>);
1886842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, BoolReturnTypeFunction const&>);
1896842f52aSArthur O'Dwyer
1906842f52aSArthur O'Dwyer struct SizeMemberDisabled {
sizeSizeMemberDisabled191fb855eb9SMark de Wever std::size_t size() { return 42; }
1926842f52aSArthur O'Dwyer };
1936842f52aSArthur O'Dwyer
1946842f52aSArthur O'Dwyer template <>
1956842f52aSArthur O'Dwyer inline constexpr bool std::ranges::disable_sized_range<SizeMemberDisabled> = true;
1966842f52aSArthur O'Dwyer
1976842f52aSArthur O'Dwyer struct ImproperlyDisabledMember {
sizeImproperlyDisabledMember198fb855eb9SMark de Wever std::size_t size() const { return 42; }
1996842f52aSArthur O'Dwyer };
2006842f52aSArthur O'Dwyer
2016842f52aSArthur O'Dwyer // Intentionally disabling "const ConstSizeMemberDisabled". This doesn't disable anything
2026842f52aSArthur O'Dwyer // because T is always uncvrefed before being checked.
2036842f52aSArthur O'Dwyer template <>
2046842f52aSArthur O'Dwyer inline constexpr bool std::ranges::disable_sized_range<const ImproperlyDisabledMember> = true;
2056842f52aSArthur O'Dwyer
2066842f52aSArthur O'Dwyer struct SizeFunctionDisabled {
size(SizeFunctionDisabled)207fb855eb9SMark de Wever friend std::size_t size(SizeFunctionDisabled) { return 42; }
2086842f52aSArthur O'Dwyer };
2096842f52aSArthur O'Dwyer
2106842f52aSArthur O'Dwyer template <>
2116842f52aSArthur O'Dwyer inline constexpr bool std::ranges::disable_sized_range<SizeFunctionDisabled> = true;
2126842f52aSArthur O'Dwyer
2136842f52aSArthur O'Dwyer struct ImproperlyDisabledFunction {
size(ImproperlyDisabledFunction const &)214fb855eb9SMark de Wever friend std::size_t size(ImproperlyDisabledFunction const&) { return 42; }
2156842f52aSArthur O'Dwyer };
2166842f52aSArthur O'Dwyer
2176842f52aSArthur O'Dwyer template <>
2186842f52aSArthur O'Dwyer inline constexpr bool std::ranges::disable_sized_range<const ImproperlyDisabledFunction> = true;
2196842f52aSArthur O'Dwyer
2206842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, ImproperlyDisabledMember&>);
2216842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, const ImproperlyDisabledMember&>);
222*12978b3eSJakub Mazurkiewicz static_assert(std::is_invocable_v<RangeSizeT,
223*12978b3eSJakub Mazurkiewicz ImproperlyDisabledFunction&>); // Ill-formed before P2602R2 Poison Pills are Too Toxic
2246842f52aSArthur O'Dwyer static_assert( std::is_invocable_v<RangeSizeT, const ImproperlyDisabledFunction&>);
2256842f52aSArthur O'Dwyer
2266842f52aSArthur O'Dwyer // No begin end.
2276842f52aSArthur O'Dwyer struct HasMinusOperator {
operator -(HasMinusOperator,HasMinusOperator)228fb855eb9SMark de Wever friend constexpr std::size_t operator-(HasMinusOperator, HasMinusOperator) { return 2; }
2296842f52aSArthur O'Dwyer };
2306842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, HasMinusOperator>);
2316842f52aSArthur O'Dwyer
2326842f52aSArthur O'Dwyer struct HasMinusBeginEnd {
2336842f52aSArthur O'Dwyer struct sentinel {
2346842f52aSArthur O'Dwyer friend bool operator==(sentinel, forward_iterator<int*>);
operator -HasMinusBeginEnd2356842f52aSArthur O'Dwyer friend constexpr std::ptrdiff_t operator-(const sentinel, const forward_iterator<int*>) { return 2; }
operator -HasMinusBeginEnd2366842f52aSArthur O'Dwyer friend constexpr std::ptrdiff_t operator-(const forward_iterator<int*>, const sentinel) { return 2; }
2376842f52aSArthur O'Dwyer };
2386842f52aSArthur O'Dwyer
begin(HasMinusBeginEnd)2396842f52aSArthur O'Dwyer friend constexpr forward_iterator<int*> begin(HasMinusBeginEnd) { return {}; }
end(HasMinusBeginEnd)2406842f52aSArthur O'Dwyer friend constexpr sentinel end(HasMinusBeginEnd) { return {}; }
2416842f52aSArthur O'Dwyer };
2426842f52aSArthur O'Dwyer
2436842f52aSArthur O'Dwyer struct other_forward_iterator : forward_iterator<int*> { };
2446842f52aSArthur O'Dwyer
2456842f52aSArthur O'Dwyer struct InvalidMinusBeginEnd {
2466842f52aSArthur O'Dwyer struct sentinel {
2476842f52aSArthur O'Dwyer friend bool operator==(sentinel, other_forward_iterator);
operator -InvalidMinusBeginEnd2486842f52aSArthur O'Dwyer friend constexpr std::ptrdiff_t operator-(const sentinel, const other_forward_iterator) { return 2; }
operator -InvalidMinusBeginEnd2496842f52aSArthur O'Dwyer friend constexpr std::ptrdiff_t operator-(const other_forward_iterator, const sentinel) { return 2; }
2506842f52aSArthur O'Dwyer };
2516842f52aSArthur O'Dwyer
begin(InvalidMinusBeginEnd)2526842f52aSArthur O'Dwyer friend constexpr other_forward_iterator begin(InvalidMinusBeginEnd) { return {}; }
end(InvalidMinusBeginEnd)2536842f52aSArthur O'Dwyer friend constexpr sentinel end(InvalidMinusBeginEnd) { return {}; }
2546842f52aSArthur O'Dwyer };
2556842f52aSArthur O'Dwyer
2566842f52aSArthur O'Dwyer // short is integer-like, but it is not other_forward_iterator's difference_type.
2576842f52aSArthur O'Dwyer static_assert(!std::same_as<other_forward_iterator::difference_type, short>);
2586842f52aSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, InvalidMinusBeginEnd>);
2596842f52aSArthur O'Dwyer
2606842f52aSArthur O'Dwyer struct RandomAccessRange {
2616842f52aSArthur O'Dwyer struct sentinel {
2626842f52aSArthur O'Dwyer friend bool operator==(sentinel, random_access_iterator<int*>);
operator -RandomAccessRange2636842f52aSArthur O'Dwyer friend constexpr std::ptrdiff_t operator-(const sentinel, const random_access_iterator<int*>) { return 2; }
operator -RandomAccessRange2646842f52aSArthur O'Dwyer friend constexpr std::ptrdiff_t operator-(const random_access_iterator<int*>, const sentinel) { return 2; }
2656842f52aSArthur O'Dwyer };
2666842f52aSArthur O'Dwyer
beginRandomAccessRange2676842f52aSArthur O'Dwyer constexpr random_access_iterator<int*> begin() { return {}; }
endRandomAccessRange2686842f52aSArthur O'Dwyer constexpr sentinel end() { return {}; }
2696842f52aSArthur O'Dwyer };
2706842f52aSArthur O'Dwyer
2716842f52aSArthur O'Dwyer struct IntPtrBeginAndEnd {
2726842f52aSArthur O'Dwyer int buff[8];
beginIntPtrBeginAndEnd2736842f52aSArthur O'Dwyer constexpr int* begin() { return buff; }
endIntPtrBeginAndEnd2746842f52aSArthur O'Dwyer constexpr int* end() { return buff + 8; }
2756842f52aSArthur O'Dwyer };
2766842f52aSArthur O'Dwyer
2776842f52aSArthur O'Dwyer struct DisabledSizeRangeWithBeginEnd {
2786842f52aSArthur O'Dwyer int buff[8];
beginDisabledSizeRangeWithBeginEnd2796842f52aSArthur O'Dwyer constexpr int* begin() { return buff; }
endDisabledSizeRangeWithBeginEnd2806842f52aSArthur O'Dwyer constexpr int* end() { return buff + 8; }
sizeDisabledSizeRangeWithBeginEnd281fb855eb9SMark de Wever constexpr std::size_t size() { return 1; }
2826842f52aSArthur O'Dwyer };
2836842f52aSArthur O'Dwyer
2846842f52aSArthur O'Dwyer template <>
2856842f52aSArthur O'Dwyer inline constexpr bool std::ranges::disable_sized_range<DisabledSizeRangeWithBeginEnd> = true;
2866842f52aSArthur O'Dwyer
2876842f52aSArthur O'Dwyer struct SizeBeginAndEndMembers {
2886842f52aSArthur O'Dwyer int buff[8];
beginSizeBeginAndEndMembers2896842f52aSArthur O'Dwyer constexpr int* begin() { return buff; }
endSizeBeginAndEndMembers2906842f52aSArthur O'Dwyer constexpr int* end() { return buff + 8; }
sizeSizeBeginAndEndMembers291fb855eb9SMark de Wever constexpr std::size_t size() { return 1; }
2926842f52aSArthur O'Dwyer };
2936842f52aSArthur O'Dwyer
testRanges()2946842f52aSArthur O'Dwyer constexpr bool testRanges() {
2956842f52aSArthur O'Dwyer HasMinusBeginEnd a;
2966842f52aSArthur O'Dwyer assert(std::ranges::size(a) == 2);
2976842f52aSArthur O'Dwyer // Ensure that this is converted to an *unsigned* type.
298fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(a)), std::size_t);
2996842f52aSArthur O'Dwyer
3006842f52aSArthur O'Dwyer IntPtrBeginAndEnd b;
3016842f52aSArthur O'Dwyer assert(std::ranges::size(b) == 8);
3026842f52aSArthur O'Dwyer
3036842f52aSArthur O'Dwyer DisabledSizeRangeWithBeginEnd c;
3046842f52aSArthur O'Dwyer assert(std::ranges::size(c) == 8);
3056842f52aSArthur O'Dwyer
3066842f52aSArthur O'Dwyer RandomAccessRange d;
3076842f52aSArthur O'Dwyer assert(std::ranges::size(d) == 2);
308fb855eb9SMark de Wever ASSERT_SAME_TYPE(decltype(std::ranges::size(d)), std::size_t);
3096842f52aSArthur O'Dwyer
3106842f52aSArthur O'Dwyer SizeBeginAndEndMembers e;
3116842f52aSArthur O'Dwyer assert(std::ranges::size(e) == 1);
3126842f52aSArthur O'Dwyer
3136842f52aSArthur O'Dwyer return true;
3146842f52aSArthur O'Dwyer }
3156842f52aSArthur O'Dwyer
31685073836SArthur O'Dwyer // Test ADL-proofing.
31785073836SArthur O'Dwyer struct Incomplete;
31885073836SArthur O'Dwyer template<class T> struct Holder { T t; };
31985073836SArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, Holder<Incomplete>*>);
3209be193bcSArthur O'Dwyer static_assert(!std::is_invocable_v<RangeSizeT, Holder<Incomplete>*&>);
32185073836SArthur O'Dwyer
main(int,char **)3226842f52aSArthur O'Dwyer int main(int, char**) {
3236842f52aSArthur O'Dwyer testArrayType();
3246842f52aSArthur O'Dwyer static_assert(testArrayType());
3256842f52aSArthur O'Dwyer
3266842f52aSArthur O'Dwyer testHasSizeMember();
3276842f52aSArthur O'Dwyer static_assert(testHasSizeMember());
3286842f52aSArthur O'Dwyer
3296842f52aSArthur O'Dwyer testHasSizeFunction();
3306842f52aSArthur O'Dwyer static_assert(testHasSizeFunction());
3316842f52aSArthur O'Dwyer
3326842f52aSArthur O'Dwyer testRanges();
3336842f52aSArthur O'Dwyer static_assert(testRanges());
3346842f52aSArthur O'Dwyer
3356842f52aSArthur O'Dwyer return 0;
3366842f52aSArthur O'Dwyer }
337