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 + concept borrowed_range = range<_Range> && + (is_lvalue_reference_v<_Range> || enable_borrowed_range>); + // `iterator_t` defined in <__ranges/access.h> template 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); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); -static_assert(stdr::borrowed_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -34,4 +34,4 @@ static_assert(!stdr::view); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); -static_assert(stdr::borrowed_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::view); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::view); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::bidirectional_range); @@ -35,3 +36,4 @@ static_assert(stdr::input_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(!stdr::view); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range); static_assert(!stdr::view); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::view); static_assert(!stdr::random_access_range); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); @@ -33,3 +34,4 @@ static_assert(!stdr::bidirectional_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(stdr::borrowed_range); static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, fs::directory_iterator>); static_assert(stdr::common_range); static_assert(stdr::input_range); static_assert(!stdr::view); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, fs::recursive_directory_iterator>); static_assert(stdr::common_range); static_assert(stdr::input_range); static_assert(!stdr::view); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, fs::recursive_directory_iterator>); static_assert(stdr::common_range); static_assert(stdr::input_range); static_assert(!stdr::view); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::random_access_range); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, fs::path::const_iterator>); static_assert(stdr::common_range); @@ -32,3 +33,4 @@ static_assert(!stdr::view); static_assert(!stdr::random_access_range); static_assert(!stdr::sized_range); +static_assert(!stdr::borrowed_range); 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 +// concept borrowed_range; + +#include + +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 = true; + +static_assert(!std::ranges::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); + +static_assert(!std::ranges::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); + +static_assert(!std::ranges::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); + +static_assert( std::ranges::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); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, std::cmatch::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); static_assert(std::same_as, std::string::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(!stdr::borrowed_range); 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); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(stdr::borrowed_range); static_assert(std::same_as, std::string_view::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); static_assert(!stdr::view); static_assert(stdr::sized_range); +static_assert(stdr::borrowed_range);