//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17 // template // constexpr range_difference_t ranges::distance(R&& r); #include #include #include #include "test_iterators.h" #include "test_macros.h" template constexpr void test_ordinary() { struct R { mutable int a[3] = {1, 2, 3}; constexpr It begin() const { return It(a); } constexpr Sent end() const { return Sent(It(a + 3)); } }; R r; assert(std::ranges::distance(r) == 3); assert(std::ranges::distance(static_cast(r)) == 3); assert(std::ranges::distance(static_cast(r)) == 3); assert(std::ranges::distance(static_cast(r)) == 3); ASSERT_SAME_TYPE(decltype(std::ranges::distance(r)), std::ranges::range_difference_t); } constexpr bool test() { { using R = int[3]; int a[] = {1, 2, 3}; assert(std::ranges::distance(static_cast(a)) == 3); assert(std::ranges::distance(static_cast(a)) == 3); assert(std::ranges::distance(static_cast(a)) == 3); assert(std::ranges::distance(static_cast(a)) == 3); ASSERT_SAME_TYPE(decltype(std::ranges::distance(a)), std::ptrdiff_t); ASSERT_SAME_TYPE(decltype(std::ranges::distance(a)), std::ranges::range_difference_t); } { // Unsized range, non-copyable iterator type, rvalue-ref-qualified begin() using It = cpp20_input_iterator; using Sent = sentinel_wrapper>; using R = std::ranges::subrange; int a[] = {1, 2, 3}; { auto r = R(It(a), Sent(It(a + 3))); assert(std::ranges::distance(r) == 3); } { auto r = R(It(a), Sent(It(a + 3))); assert(std::ranges::distance(static_cast(r)) == 3); } static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); } { // Sized range (unsized sentinel type), non-copyable iterator type, rvalue-ref-qualified begin() using It = cpp20_input_iterator; using Sent = sentinel_wrapper>; using R = std::ranges::subrange; int a[] = {1, 2, 3}; { auto r = R(It(a), Sent(It(a + 3)), 3); assert(std::ranges::distance(r) == 3); } { auto r = R(It(a), Sent(It(a + 3)), 3); assert(std::ranges::distance(static_cast(r)) == 3); } static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); } { // Sized range (sized sentinel type), non-copyable iterator type test_ordinary, sized_sentinel>>(); } test_ordinary, sentinel_wrapper>>(); test_ordinary, sentinel_wrapper>>(); test_ordinary, sentinel_wrapper>>(); test_ordinary, sentinel_wrapper>>(); test_ordinary, sentinel_wrapper>>(); test_ordinary, sentinel_wrapper>>(); test_ordinary, sentinel_wrapper>>(); test_ordinary>(); test_ordinary, sized_sentinel>>(); test_ordinary, sized_sentinel>>(); test_ordinary, sized_sentinel>>(); test_ordinary, sized_sentinel>>(); test_ordinary, sized_sentinel>>(); test_ordinary, sized_sentinel>>(); test_ordinary, sized_sentinel>>(); test_ordinary>(); test_ordinary(); // Calling it on a non-range isn't allowed. static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); return true; } int main(int, char**) { test(); static_assert(test()); return 0; }