[libcxx-commits] [libcxx] 01ace07 - [libc++] Implements ranges::enable_borrowed_range

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sun Apr 18 04:35:13 PDT 2021


Author: Mark de Wever
Date: 2021-04-18T13:35:08+02:00
New Revision: 01ace074fcb6a497fc16b1578fc10480dc7d563d

URL: https://github.com/llvm/llvm-project/commit/01ace074fcb6a497fc16b1578fc10480dc7d563d
DIFF: https://github.com/llvm/llvm-project/commit/01ace074fcb6a497fc16b1578fc10480dc7d563d.diff

LOG: [libc++] Implements ranges::enable_borrowed_range

This is the initial patch to implement ranges in libc++.

Implements parts of:
- P0896R4 One Ranges Proposal
- P1870 forwarding-range is too subtle
- LWG3379 in several library names is misleading

Reviewed By: ldionne, #libc, cjdb, zoecarver, Quuxplusone

Differential Revision: https://reviews.llvm.org/D90999

Added: 
    libcxx/include/__ranges/enable_borrowed_range.h
    libcxx/include/ranges
    libcxx/test/libcxx/inclusions/ranges.inclusions.compile.pass.cpp
    libcxx/test/libcxx/ranges/version.compile.pass.cpp
    libcxx/test/std/containers/views/enable_borrowed_range.compile.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.pass.cpp
    libcxx/test/std/ranges/range.range/enable_borrowed_range.compile.pass.cpp
    libcxx/test/std/strings/string.view/enable_borrowed_range.compile.pass.cpp

Modified: 
    libcxx/docs/Cxx2aStatusIssuesStatus.csv
    libcxx/docs/Cxx2aStatusPaperStatus.csv
    libcxx/include/CMakeLists.txt
    libcxx/include/module.modulemap
    libcxx/include/span
    libcxx/include/string_view
    libcxx/test/libcxx/double_include.sh.cpp
    libcxx/test/libcxx/min_max_macros.compile.pass.cpp
    libcxx/test/libcxx/no_assert_include.compile.pass.cpp
    libcxx/utils/generate_header_inclusion_tests.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Cxx2aStatusIssuesStatus.csv b/libcxx/docs/Cxx2aStatusIssuesStatus.csv
index a471cd4f8b0a1..7512630b24726 100644
--- a/libcxx/docs/Cxx2aStatusIssuesStatus.csv
+++ b/libcxx/docs/Cxx2aStatusIssuesStatus.csv
@@ -281,7 +281,7 @@
 "`3374 <https://wg21.link/LWG3374>`__","P0653 + P1006 should have made the other ``std::to_address``\  overload ``constexpr``\ ","Prague","|Complete|","12.0"
 "`3375 <https://wg21.link/LWG3375>`__","``decay``\  in ``viewable_range``\  should be ``remove_cvref``\ ","Prague","",""
 "`3377 <https://wg21.link/LWG3377>`__","``elements_view::iterator``\  befriends a specialization of itself","Prague","",""
-"`3379 <https://wg21.link/LWG3379>`__","""``safe``\ "" in several library names is misleading","Prague","",""
+"`3379 <https://wg21.link/LWG3379>`__","""``safe``\ "" in several library names is misleading","Prague","|In Progress|",""
 "`3380 <https://wg21.link/LWG3380>`__","``common_type``\  and comparison categories","Prague","",""
 "`3381 <https://wg21.link/LWG3381>`__","``begin``\  and ``data``\  must agree for ``contiguous_range``\ ","Prague","",""
 "`3382 <https://wg21.link/LWG3382>`__","NTTP for ``pair``\  and ``array``\ ","Prague","",""

diff  --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv
index f478f31d162b9..1c5a84c200397 100644
--- a/libcxx/docs/Cxx2aStatusPaperStatus.csv
+++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv
@@ -153,7 +153,7 @@
 "`P1862 <https://wg21.link/P1862>`__","LWG","Ranges adaptors for non-copyable iterators","Belfast","* *",""
 "`P1865 <https://wg21.link/P1865>`__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0"
 "`P1869 <https://wg21.link/P1869>`__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *",""
-"`P1870 <https://wg21.link/P1870>`__","LWG","forwarding-range is too subtle","Belfast","* *",""
+"`P1870 <https://wg21.link/P1870>`__","LWG","forwarding-range is too subtle","Belfast","|In Progress|",""
 "`P1871 <https://wg21.link/P1871>`__","LWG","Should concepts be enabled or disabled?","Belfast","* *",""
 "`P1872 <https://wg21.link/P1872>`__","LWG","span should have size_type, not index_type","Belfast","|Complete|","10.0"
 "`P1878 <https://wg21.link/P1878>`__","LWG","Constraining Readable Types","Belfast","* *",""

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 8050fd95a82a7..683f790c9a473 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -30,6 +30,7 @@ set(files
   __mutex_base
   __node_handle
   __nullptr
+  __ranges/enable_borrowed_range.h
   __split_buffer
   __sso_allocator
   __std_stream
@@ -141,6 +142,7 @@ set(files
   ostream
   queue
   random
+  ranges
   ratio
   regex
   scoped_allocator

diff  --git a/libcxx/include/__ranges/enable_borrowed_range.h b/libcxx/include/__ranges/enable_borrowed_range.h
new file mode 100644
index 0000000000000..618b2223c7169
--- /dev/null
+++ b/libcxx/include/__ranges/enable_borrowed_range.h
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+//===------------------ __ranges/enable_borrowed_range.h ------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
+#define _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
+
+// These customization variables are used in <span> and <string_view>. The
+// separate header is used to avoid including the entire <ranges> header in
+// <span> and <string_view>.
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges
+{
+
+// [range.range], ranges
+
+template <class>
+inline constexpr bool enable_borrowed_range = false;
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H

diff  --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 56b49c473070f..c970082b56005 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -409,6 +409,10 @@ module std [system] {
     export initializer_list
     export *
   }
+  module ranges {
+    header "ranges"
+    export *
+  }
   module ratio {
     header "ratio"
     export *

diff  --git a/libcxx/include/ranges b/libcxx/include/ranges
new file mode 100644
index 0000000000000..3bcb62be28d41
--- /dev/null
+++ b/libcxx/include/ranges
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+//===--------------------------- ranges -----------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_RANGES
+#define _LIBCPP_RANGES
+
+/*
+
+#include <compare>              // see [compare.syn]
+#include <initializer_list>     // see [initializer.list.syn]
+#include <iterator>             // see [iterator.synopsis]
+
+namespace std::ranges {
+  // [range.range], ranges
+  template<class T>
+    inline constexpr bool enable_borrowed_range = false;
+}
+
+*/
+
+#include <__config>
+#include <__ranges/enable_borrowed_range.h>
+#include <compare>          // Required by the standard.
+#include <initializer_list> // Required by the standard.
+#include <iterator>         // Required by the standard.
+#include <type_traits>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_RANGES

diff  --git a/libcxx/include/span b/libcxx/include/span
index 4f63d0ac4e1f1..b47574084b2ac 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -22,6 +22,9 @@ inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
 template <class ElementType, size_t Extent = dynamic_extent>
     class span;
 
+template<class ElementType, size_t Extent>
+    inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
+
 // [span.objectrep], views of object representation
 template <class ElementType, size_t Extent>
     span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
@@ -32,7 +35,6 @@ template <class ElementType, size_t Extent>
         (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
 
 
-namespace std {
 template <class ElementType, size_t Extent = dynamic_extent>
 class span {
 public:
@@ -123,6 +125,7 @@ template<class Container>
 */
 
 #include <__config>
+#include <__ranges/enable_borrowed_range.h>
 #include <array>        // for array
 #include <cstddef>      // for byte
 #include <iterator>     // for iterators
@@ -516,6 +519,11 @@ private:
     size_type __size;
 };
 
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+template <class _Tp, size_t _Extent>
+inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
 //  as_bytes & as_writable_bytes
 template <class _Tp, size_t _Extent>
 _LIBCPP_INLINE_VISIBILITY

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index 3177fcd778316..e957a649f62dd 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -19,6 +19,9 @@ namespace std {
     template<class charT, class traits = char_traits<charT>>
         class basic_string_view;
 
+    template<class charT, class traits>
+    inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true;  // C++20
+
     // 7.9, basic_string_view non-member comparison functions
     template<class charT, class traits>
     constexpr bool operator==(basic_string_view<charT, traits> x,
@@ -179,6 +182,7 @@ namespace std {
 */
 
 #include <__config>
+#include <__ranges/enable_borrowed_range.h>
 #include <__string>
 #include <iosfwd>
 #include <algorithm>
@@ -649,6 +653,10 @@ private:
     size_type           __size;
 };
 
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+template <class _CharT, class _Traits>
+inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
 
 // [string.view.comparison]
 // operator ==

diff  --git a/libcxx/test/libcxx/double_include.sh.cpp b/libcxx/test/libcxx/double_include.sh.cpp
index 84486edb46550..eb9de0b64b1ab 100644
--- a/libcxx/test/libcxx/double_include.sh.cpp
+++ b/libcxx/test/libcxx/double_include.sh.cpp
@@ -143,6 +143,7 @@
 #endif
 #include <queue>
 #include <random>
+#include <ranges>
 #include <ratio>
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
 #    include <regex>

diff  --git a/libcxx/test/libcxx/inclusions/ranges.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/ranges.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..316d141041589
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/ranges.inclusions.compile.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <ranges>
+
+// Test that <ranges> includes all the other headers it's supposed to.
+
+#include <ranges>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_RANGES)
+ #   error "<ranges> was expected to define _LIBCPP_RANGES"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<ranges> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<ranges> should include <initializer_list> in C++20 and later"
+#endif
+#if !defined(_LIBCPP_ITERATOR)
+ #   error "<ranges> should include <iterator> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
index 3e75de51a6ece..520fd3cc15907 100644
--- a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
+++ b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
@@ -218,6 +218,8 @@ TEST_MACROS();
 TEST_MACROS();
 #include <random>
 TEST_MACROS();
+#include <ranges>
+TEST_MACROS();
 #include <ratio>
 TEST_MACROS();
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION

diff  --git a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
index 221c39a07b2b8..60839d52ea5fe 100644
--- a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
+++ b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
@@ -136,6 +136,7 @@
 #endif
 #include <queue>
 #include <random>
+#include <ranges>
 #include <ratio>
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
 #    include <regex>

diff  --git a/libcxx/test/libcxx/ranges/version.compile.pass.cpp b/libcxx/test/libcxx/ranges/version.compile.pass.cpp
new file mode 100644
index 0000000000000..817b9eede4d25
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/version.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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+#include <ranges>
+
+#include "test_macros.h"
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+// Required for MSVC internal test runner compatibility.
+int main(int, char**) { return 0; }

diff  --git a/libcxx/test/std/containers/views/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/containers/views/enable_borrowed_range.compile.pass.cpp
new file mode 100644
index 0000000000000..946cb5c1cd334
--- /dev/null
+++ b/libcxx/test/std/containers/views/enable_borrowed_range.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <span>
+
+// template<class ElementType, size_t Extent>
+// inline constexpr bool ranges::enable_borrowed_range<
+//     span<ElementType, Extent>> = true;
+
+#include <span>
+
+#include "test_macros.h"
+
+void test() {
+  static_assert(std::ranges::enable_borrowed_range<std::span<int, 0> >);
+  static_assert(std::ranges::enable_borrowed_range<std::span<int, 42> >);
+  static_assert(std::ranges::enable_borrowed_range<std::span<int, std::dynamic_extent> >);
+  static_assert(!std::ranges::enable_borrowed_range<std::span<int, 42>&>);
+  static_assert(!std::ranges::enable_borrowed_range<std::span<int, 42> const>);
+}

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.pass.cpp
new file mode 100644
index 0000000000000..96496add7622f
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <ranges>
+
+// Test the feature test macros defined by <ranges>
+
+/*  Constant            Value
+    __cpp_lib_ranges    201811L [C++20]
+*/
+
+#include <ranges>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_ranges
+#   error "__cpp_lib_ranges should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_ranges
+#   error "__cpp_lib_ranges should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_ranges
+#   error "__cpp_lib_ranges should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# if !defined(_LIBCPP_VERSION)
+#   ifndef __cpp_lib_ranges
+#     error "__cpp_lib_ranges should be defined in c++20"
+#   endif
+#   if __cpp_lib_ranges != 201811L
+#     error "__cpp_lib_ranges should have the value 201811L in c++20"
+#   endif
+# else // _LIBCPP_VERSION
+#   ifdef __cpp_lib_ranges
+#     error "__cpp_lib_ranges should not be defined because it is unimplemented in libc++!"
+#   endif
+# endif
+
+#elif TEST_STD_VER > 20
+
+# if !defined(_LIBCPP_VERSION)
+#   ifndef __cpp_lib_ranges
+#     error "__cpp_lib_ranges should be defined in c++2b"
+#   endif
+#   if __cpp_lib_ranges != 201811L
+#     error "__cpp_lib_ranges should have the value 201811L in c++2b"
+#   endif
+# else // _LIBCPP_VERSION
+#   ifdef __cpp_lib_ranges
+#     error "__cpp_lib_ranges should not be defined because it is unimplemented in libc++!"
+#   endif
+# endif
+
+#endif // TEST_STD_VER > 20
+
+int main(int, char**) { return 0; }

diff  --git a/libcxx/test/std/ranges/range.range/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.range/enable_borrowed_range.compile.pass.cpp
new file mode 100644
index 0000000000000..46755e3129c05
--- /dev/null
+++ b/libcxx/test/std/ranges/range.range/enable_borrowed_range.compile.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <ranges>
+
+// template<class>
+//  inline constexpr bool enable_borrowed_range = false;
+
+#include <ranges>
+#include <array>
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <map>
+#include <queue>
+#include <set>
+#include <stack>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "test_macros.h"
+
+struct S {};
+
+void test() {
+  using std::ranges::enable_borrowed_range;
+  static_assert(!enable_borrowed_range<char>);
+  static_assert(!enable_borrowed_range<int>);
+  static_assert(!enable_borrowed_range<double>);
+  static_assert(!enable_borrowed_range<S>);
+
+  // Sequence containers
+  static_assert(!enable_borrowed_range<std::array<int, 0> >);
+  static_assert(!enable_borrowed_range<std::array<int, 42> >);
+  static_assert(!enable_borrowed_range<std::deque<int> >);
+  static_assert(!enable_borrowed_range<std::forward_list<int> >);
+  static_assert(!enable_borrowed_range<std::list<int> >);
+  static_assert(!enable_borrowed_range<std::vector<int> >);
+
+  // Associative containers
+  static_assert(!enable_borrowed_range<std::set<int> >);
+  static_assert(!enable_borrowed_range<std::map<int, int> >);
+  static_assert(!enable_borrowed_range<std::multiset<int> >);
+  static_assert(!enable_borrowed_range<std::multimap<int, int> >);
+
+  // Unordered associative containers
+  static_assert(!enable_borrowed_range<std::unordered_set<int> >);
+  static_assert(!enable_borrowed_range<std::unordered_map<int, int> >);
+  static_assert(!enable_borrowed_range<std::unordered_multiset<int> >);
+  static_assert(!enable_borrowed_range<std::unordered_multimap<int, int> >);
+
+  // Container adaptors
+  static_assert(!enable_borrowed_range<std::stack<int> >);
+  static_assert(!enable_borrowed_range<std::queue<int> >);
+  static_assert(!enable_borrowed_range<std::priority_queue<int> >);
+
+  // Both std::span and std::string_view have their own test.
+}

diff  --git a/libcxx/test/std/strings/string.view/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/strings/string.view/enable_borrowed_range.compile.pass.cpp
new file mode 100644
index 0000000000000..f19dd1a17e0b5
--- /dev/null
+++ b/libcxx/test/std/strings/string.view/enable_borrowed_range.compile.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <string_view>
+
+// template<class charT, class traits>
+// inline constexpr bool ranges::enable_borrowed_range<
+//     basic_string_view<charT, traits>> = true;
+
+#include <string_view>
+
+#include "test_macros.h"
+
+void test() {
+  using std::ranges::enable_borrowed_range;
+  static_assert(enable_borrowed_range<std::basic_string_view<char> >);
+  static_assert(enable_borrowed_range<std::basic_string_view<wchar_t> >);
+  static_assert(enable_borrowed_range<std::basic_string_view<char8_t> >);
+}

diff  --git a/libcxx/utils/generate_header_inclusion_tests.py b/libcxx/utils/generate_header_inclusion_tests.py
index 0bf318ea440e8..5596872c339b1 100755
--- a/libcxx/utils/generate_header_inclusion_tests.py
+++ b/libcxx/utils/generate_header_inclusion_tests.py
@@ -42,7 +42,7 @@ def get_libcxx_paths():
     "optional": ["compare"],
     "queue": ["compare", "initializer_list"],
     "random": ["initializer_list"],
-    # TODO "ranges": ["compare", "initializer_list", "iterator"],
+    "ranges": ["compare", "initializer_list", "iterator"],
     "regex": ["compare", "initializer_list"],
     "set": ["compare", "initializer_list"],
     "stack": ["compare", "initializer_list"],


        


More information about the libcxx-commits mailing list