diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -36,6 +36,10 @@ ranges::end(__t); }; + template<class _Range> + concept borrowed_range = range<_Range> && + (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>); + // `iterator_t` defined in <__ranges/access.h> template <range _Rp> diff --git a/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp @@ -26,7 +26,7 @@ static_assert(!stdr::view<range>); static_assert(!stdr::random_access_range<range>); static_assert(stdr::sized_range<range>); -static_assert(stdr::borrowed_range<range const>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -34,4 +34,4 @@ static_assert(!stdr::view<range const>); static_assert(!stdr::random_access_range<range const>); static_assert(stdr::sized_range<range const>); -static_assert(stdr::borrowed_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::view<range>); static_assert(!stdr::random_access_range<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::view<range const>); static_assert(!stdr::random_access_range<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::view<range>); static_assert(!stdr::random_access_range<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::view<range const>); static_assert(!stdr::random_access_range<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp @@ -27,6 +27,7 @@ static_assert(stdr::input_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::bidirectional_range<range const>); @@ -35,3 +36,4 @@ static_assert(stdr::input_range<range>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp @@ -25,9 +25,11 @@ static_assert(stdr::common_range<range>); static_assert(stdr::random_access_range<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(!stdr::view<range const>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); static_assert(stdr::random_access_range<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp @@ -25,9 +25,11 @@ static_assert(stdr::random_access_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); static_assert(stdr::random_access_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::bidirectional_range<range>); static_assert(!stdr::view<range>); static_assert(!stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range<range const>); static_assert(!stdr::view<range const>); static_assert(!stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::view<range>); static_assert(!stdr::random_access_range<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::view<range const>); static_assert(!stdr::random_access_range<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp @@ -25,9 +25,11 @@ static_assert(stdr::random_access_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); static_assert(stdr::random_access_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp @@ -25,9 +25,11 @@ static_assert(stdr::random_access_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); static_assert(stdr::random_access_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::bidirectional_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::bidirectional_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::bidirectional_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp @@ -26,6 +26,7 @@ static_assert(!stdr::bidirectional_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(!stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>); static_assert(stdr::common_range<range const>); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(!stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp @@ -25,9 +25,11 @@ static_assert(stdr::random_access_range<range>); static_assert(!stdr::view<range>); static_assert(stdr::sized_range<range>); +static_assert(stdr::borrowed_range<range>); static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>); static_assert(stdr::common_range<range const>); static_assert(stdr::random_access_range<range const>); static_assert(!stdr::view<range const>); static_assert(stdr::sized_range<range const>); +static_assert(stdr::borrowed_range<range const>); diff --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp @@ -25,21 +25,25 @@ static_assert(stdr::input_range<fs::directory_iterator>); static_assert(!stdr::view<fs::directory_iterator>); static_assert(!stdr::sized_range<fs::directory_iterator>); +static_assert(!stdr::borrowed_range<fs::directory_iterator>); static_assert(std::same_as<stdr::iterator_t<fs::directory_iterator const>, fs::directory_iterator>); static_assert(stdr::common_range<fs::directory_iterator const>); static_assert(stdr::input_range<fs::directory_iterator const>); static_assert(!stdr::view<fs::directory_iterator const>); static_assert(!stdr::sized_range<fs::directory_iterator const>); +static_assert(!stdr::borrowed_range<fs::directory_iterator const>); static_assert(std::same_as<stdr::iterator_t<fs::recursive_directory_iterator>, fs::recursive_directory_iterator>); static_assert(stdr::common_range<fs::recursive_directory_iterator>); static_assert(stdr::input_range<fs::recursive_directory_iterator>); static_assert(!stdr::view<fs::recursive_directory_iterator>); static_assert(!stdr::sized_range<fs::recursive_directory_iterator>); +static_assert(!stdr::borrowed_range<fs::recursive_directory_iterator>); static_assert(std::same_as<stdr::iterator_t<fs::recursive_directory_iterator const>, fs::recursive_directory_iterator>); static_assert(stdr::common_range<fs::recursive_directory_iterator const>); static_assert(stdr::input_range<fs::recursive_directory_iterator const>); static_assert(!stdr::view<fs::recursive_directory_iterator const>); static_assert(!stdr::sized_range<fs::recursive_directory_iterator const>); +static_assert(!stdr::borrowed_range<fs::recursive_directory_iterator const>); diff --git a/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp @@ -25,6 +25,7 @@ static_assert(!stdr::view<fs::path>); static_assert(!stdr::random_access_range<fs::path>); static_assert(!stdr::sized_range<fs::path>); +static_assert(!stdr::borrowed_range<fs::path>); static_assert(std::same_as<stdr::iterator_t<fs::path const>, fs::path::const_iterator>); static_assert(stdr::common_range<fs::path const>); @@ -32,3 +33,4 @@ static_assert(!stdr::view<fs::path const>); static_assert(!stdr::random_access_range<fs::path const>); static_assert(!stdr::sized_range<fs::path const>); +static_assert(!stdr::borrowed_range<fs::path const>); diff --git a/libcxx/test/std/ranges/range.range/borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.range/borrowed_range.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.range/borrowed_range.compile.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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: gcc-10 + +// template<class T> +// concept borrowed_range; + +#include <ranges> + +struct NotRange { + int begin() const; + int end() const; +}; + +struct Range { + int *begin(); + int *end(); +}; + +struct ConstRange { + int *begin() const; + int *end() const; +}; + +struct BorrowedRange { + int *begin() const; + int *end() const; +}; + +template<> +inline constexpr bool std::ranges::enable_borrowed_range<BorrowedRange> = true; + +static_assert(!std::ranges::borrowed_range<NotRange>); +static_assert(!std::ranges::borrowed_range<NotRange&>); +static_assert(!std::ranges::borrowed_range<const NotRange>); +static_assert(!std::ranges::borrowed_range<const NotRange&>); +static_assert(!std::ranges::borrowed_range<NotRange&&>); + +static_assert(!std::ranges::borrowed_range<Range>); +static_assert( std::ranges::borrowed_range<Range&>); +static_assert(!std::ranges::borrowed_range<const Range>); +static_assert(!std::ranges::borrowed_range<const Range&>); +static_assert(!std::ranges::borrowed_range<Range&&>); + +static_assert(!std::ranges::borrowed_range<ConstRange>); +static_assert( std::ranges::borrowed_range<ConstRange&>); +static_assert(!std::ranges::borrowed_range<const ConstRange>); +static_assert( std::ranges::borrowed_range<const ConstRange&>); +static_assert(!std::ranges::borrowed_range<ConstRange&&>); + +static_assert( std::ranges::borrowed_range<BorrowedRange>); +static_assert( std::ranges::borrowed_range<BorrowedRange&>); +static_assert( std::ranges::borrowed_range<const BorrowedRange>); +static_assert( std::ranges::borrowed_range<const BorrowedRange&>); +static_assert( std::ranges::borrowed_range<BorrowedRange&&>); diff --git a/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp @@ -24,9 +24,11 @@ static_assert(stdr::random_access_range<std::cmatch>); static_assert(!stdr::view<std::cmatch>); static_assert(stdr::sized_range<std::cmatch>); +static_assert(!stdr::borrowed_range<std::cmatch>); static_assert(std::same_as<stdr::iterator_t<std::cmatch const>, std::cmatch::const_iterator>); static_assert(stdr::common_range<std::cmatch const>); static_assert(stdr::random_access_range<std::cmatch const>); static_assert(!stdr::view<std::cmatch const>); static_assert(stdr::sized_range<std::cmatch const>); +static_assert(!stdr::borrowed_range<std::cmatch const>); diff --git a/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp @@ -24,9 +24,11 @@ static_assert(stdr::random_access_range<std::string>); static_assert(!stdr::view<std::string>); static_assert(stdr::sized_range<std::string>); +static_assert(!stdr::borrowed_range<std::string>); static_assert(std::same_as<stdr::iterator_t<std::string const>, std::string::const_iterator>); static_assert(stdr::common_range<std::string const>); static_assert(stdr::random_access_range<std::string const>); static_assert(!stdr::view<std::string const>); static_assert(stdr::sized_range<std::string const>); +static_assert(!stdr::borrowed_range<std::string const>); diff --git a/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp @@ -24,9 +24,11 @@ static_assert(stdr::random_access_range<std::string_view>); static_assert(!stdr::view<std::string_view>); static_assert(stdr::sized_range<std::string_view>); +static_assert(stdr::borrowed_range<std::string_view>); static_assert(std::same_as<stdr::iterator_t<std::string_view const>, std::string_view::const_iterator>); static_assert(stdr::common_range<std::string_view const>); static_assert(stdr::random_access_range<std::string_view const>); static_assert(!stdr::view<std::string_view const>); static_assert(stdr::sized_range<std::string_view const>); +static_assert(stdr::borrowed_range<std::string_view const>);