Index: libcxx/include/__ranges/empty_view.h =================================================================== --- libcxx/include/__ranges/empty_view.h +++ libcxx/include/__ranges/empty_view.h @@ -10,6 +10,7 @@ #define _LIBCPP___RANGES_EMPTY_VIEW_H #include <__config> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/view_interface.h> #include @@ -32,6 +33,9 @@ _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; } _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; } }; + + template + inline constexpr bool enable_borrowed_range> = true; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) Index: libcxx/include/__ranges/ref_view.h =================================================================== --- libcxx/include/__ranges/ref_view.h +++ libcxx/include/__ranges/ref_view.h @@ -18,6 +18,7 @@ #include <__ranges/concepts.h> #include <__ranges/data.h> #include <__ranges/empty.h> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/size.h> #include <__ranges/view_interface.h> #include <__utility/forward.h> @@ -74,6 +75,8 @@ template ref_view(_Range&) -> ref_view<_Range>; + template + inline constexpr bool enable_borrowed_range> = true; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) Index: libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/borrowing.compile.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/borrowing.compile.pass.cpp +++ libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/borrowing.compile.pass.cpp @@ -14,20 +14,8 @@ // inline constexpr bool enable_borrowed_range> = enable_borrowed_range; #include -#include -struct Range { - int *begin() const; - int *end() const; -}; +#include "test_range.h" -struct BorrowableRange { - int *begin() const; - int *end() const; -}; - -template<> -inline constexpr bool std::ranges::enable_borrowed_range = true; - -static_assert(!std::ranges::enable_borrowed_range>); -static_assert( std::ranges::enable_borrowed_range>); +static_assert( std::ranges::borrowed_range>); +static_assert(!std::ranges::borrowed_range>); Index: libcxx/test/std/ranges/range.adaptors/range.all/range.ref.view/borrowing.compile.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.all/range.ref.view/borrowing.compile.pass.cpp +++ libcxx/test/std/ranges/range.adaptors/range.all/range.ref.view/borrowing.compile.pass.cpp @@ -10,14 +10,13 @@ // UNSUPPORTED: libcpp-no-concepts // UNSUPPORTED: libcpp-has-no-incomplete-ranges -// class std::ranges::subrange; +// template +// inline constexpr bool enable_borrowed_range> = true; #include -#include "test_iterators.h" +#include "test_range.h" -namespace ranges = std::ranges; - -static_assert(ranges::borrowed_range>); -static_assert(ranges::borrowed_range>); -static_assert(ranges::borrowed_range, ranges::subrange_kind::unsized>>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); Index: libcxx/test/std/ranges/range.adaptors/range.common.view/borrowing.compile.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.common.view/borrowing.compile.pass.cpp +++ libcxx/test/std/ranges/range.adaptors/range.common.view/borrowing.compile.pass.cpp @@ -14,21 +14,13 @@ // inline constexpr bool enable_borrowed_range> = enable_borrowed_range; #include -#include -#include "test_iterators.h" - -struct View : std::ranges::view_base { - int *begin() const; - sentinel_wrapper end() const; -}; - -struct BorrowableView : std::ranges::view_base { - int *begin() const; - sentinel_wrapper end() const; +// common_view can only wrap Ts that are `view && !common_range`, so we need to invent one. +struct Uncommon : std::ranges::view_base { + int *begin() const; + std::unreachable_sentinel_t end() const; }; -template<> -inline constexpr bool std::ranges::enable_borrowed_range = true; -static_assert(!std::ranges::enable_borrowed_range>); -static_assert( std::ranges::enable_borrowed_range>); +static_assert(!std::ranges::borrowed_range>); +static_assert(!std::ranges::borrowed_range>>); +static_assert( std::ranges::borrowed_range>>); Index: libcxx/test/std/ranges/range.adaptors/range.empty/borrowing.compile.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/ranges/range.adaptors/range.empty/borrowing.compile.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// template +// inline constexpr bool enable_borrowed_range> = true; + +#include + +#include "test_range.h" + +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); Index: libcxx/test/std/ranges/range.adaptors/range.reverse/borrowing.compile.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.reverse/borrowing.compile.pass.cpp +++ libcxx/test/std/ranges/range.adaptors/range.reverse/borrowing.compile.pass.cpp @@ -14,26 +14,8 @@ // inline constexpr bool enable_borrowed_range> = enable_borrowed_range; #include -#include -#include "test_iterators.h" +#include "test_range.h" -struct View : std::ranges::view_base { - friend int* begin(View&); - friend int* begin(View const&); - friend sentinel_wrapper end(View&); - friend sentinel_wrapper end(View const&); -}; - -struct BorrowableView : std::ranges::view_base { - friend int* begin(BorrowableView&); - friend int* begin(BorrowableView const&); - friend sentinel_wrapper end(BorrowableView&); - friend sentinel_wrapper end(BorrowableView const&); -}; - -template<> -inline constexpr bool std::ranges::enable_borrowed_range = true; - -static_assert(!std::ranges::enable_borrowed_range>); -static_assert( std::ranges::enable_borrowed_range>); +static_assert( std::ranges::borrowed_range>); +static_assert(!std::ranges::borrowed_range>); Index: libcxx/test/std/ranges/range.adaptors/range.take/borrowing.compile.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.take/borrowing.compile.pass.cpp +++ libcxx/test/std/ranges/range.adaptors/range.take/borrowing.compile.pass.cpp @@ -14,26 +14,8 @@ // inline constexpr bool enable_borrowed_range> = enable_borrowed_range; #include -#include -#include "test_iterators.h" +#include "test_range.h" -struct View : std::ranges::view_base { - friend int* begin(View&); - friend int* begin(View const&); - friend sentinel_wrapper end(View&); - friend sentinel_wrapper end(View const&); -}; - -struct BorrowableView : std::ranges::view_base { - friend int* begin(BorrowableView&); - friend int* begin(BorrowableView const&); - friend sentinel_wrapper end(BorrowableView&); - friend sentinel_wrapper end(BorrowableView const&); -}; - -template<> -inline constexpr bool std::ranges::enable_borrowed_range = true; - -static_assert(!std::ranges::enable_borrowed_range>); -static_assert( std::ranges::enable_borrowed_range>); +static_assert( std::ranges::borrowed_range>); +static_assert(!std::ranges::borrowed_range>); Index: libcxx/test/std/ranges/range.factories/range.iota.view/borrowing.compile.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.factories/range.iota.view/borrowing.compile.pass.cpp +++ libcxx/test/std/ranges/range.factories/range.iota.view/borrowing.compile.pass.cpp @@ -14,12 +14,8 @@ // inline constexpr bool enable_borrowed_range> = true; #include -#include -#include -#include "test_macros.h" -#include "types.h" - -static_assert(std::ranges::enable_borrowed_range>); -static_assert(std::ranges::enable_borrowed_range>); -static_assert(std::ranges::enable_borrowed_range>>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); Index: libcxx/test/std/ranges/range.factories/range.single.view/borrowing.compile.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/ranges/range.factories/range.single.view/borrowing.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// single_view does not specialize enable_borrowed_range + +#include + +#include "test_range.h" + +static_assert(!std::ranges::borrowed_range>); +static_assert(!std::ranges::borrowed_range>); +static_assert(!std::ranges::borrowed_range>); +static_assert(!std::ranges::borrowed_range>); Index: libcxx/test/std/ranges/range.utility/range.subrange/borrowing.compile.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/ranges/range.utility/range.subrange/borrowing.compile.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// template +// inline constexpr bool enable_borrowed_range> = true; + +#include + +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); +static_assert(std::ranges::borrowed_range>); Index: libcxx/test/support/test_range.h =================================================================== --- libcxx/test/support/test_range.h +++ libcxx/test/support/test_range.h @@ -62,4 +62,21 @@ sentinel end() const; }; +struct BorrowedRange { + int *begin() const; + int *end() const; + BorrowedRange(BorrowedRange&&) = delete; +}; +template<> inline constexpr bool std::ranges::enable_borrowed_range = true; +static_assert(!std::ranges::view); +static_assert(std::ranges::borrowed_range); + +using BorrowedView = std::ranges::empty_view; +static_assert(std::ranges::view); +static_assert(std::ranges::borrowed_range); + +using NonBorrowedView = std::ranges::single_view; +static_assert(std::ranges::view); +static_assert(!std::ranges::borrowed_range); + #endif // LIBCXX_TEST_SUPPORT_TEST_RANGE_H