Skip to content

Commit 01ace07

Browse files
committed
[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
1 parent aa80ea8 commit 01ace07

18 files changed

+379
-4
lines changed

libcxx/docs/Cxx2aStatusIssuesStatus.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@
281281
"`3374 <https://wg21.link/LWG3374>`__","P0653 + P1006 should have made the other ``std::to_address``\ overload ``constexpr``\ ","Prague","|Complete|","12.0"
282282
"`3375 <https://wg21.link/LWG3375>`__","``decay``\ in ``viewable_range``\ should be ``remove_cvref``\ ","Prague","",""
283283
"`3377 <https://wg21.link/LWG3377>`__","``elements_view::iterator``\ befriends a specialization of itself","Prague","",""
284-
"`3379 <https://wg21.link/LWG3379>`__","""``safe``\ "" in several library names is misleading","Prague","",""
284+
"`3379 <https://wg21.link/LWG3379>`__","""``safe``\ "" in several library names is misleading","Prague","|In Progress|",""
285285
"`3380 <https://wg21.link/LWG3380>`__","``common_type``\ and comparison categories","Prague","",""
286286
"`3381 <https://wg21.link/LWG3381>`__","``begin``\ and ``data``\ must agree for ``contiguous_range``\ ","Prague","",""
287287
"`3382 <https://wg21.link/LWG3382>`__","NTTP for ``pair``\ and ``array``\ ","Prague","",""

libcxx/docs/Cxx2aStatusPaperStatus.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153
"`P1862 <https://wg21.link/P1862>`__","LWG","Ranges adaptors for non-copyable iterators","Belfast","* *",""
154154
"`P1865 <https://wg21.link/P1865>`__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0"
155155
"`P1869 <https://wg21.link/P1869>`__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *",""
156-
"`P1870 <https://wg21.link/P1870>`__","LWG","forwarding-range is too subtle","Belfast","* *",""
156+
"`P1870 <https://wg21.link/P1870>`__","LWG","forwarding-range is too subtle","Belfast","|In Progress|",""
157157
"`P1871 <https://wg21.link/P1871>`__","LWG","Should concepts be enabled or disabled?","Belfast","* *",""
158158
"`P1872 <https://wg21.link/P1872>`__","LWG","span should have size_type, not index_type","Belfast","|Complete|","10.0"
159159
"`P1878 <https://wg21.link/P1878>`__","LWG","Constraining Readable Types","Belfast","* *",""

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ set(files
3030
__mutex_base
3131
__node_handle
3232
__nullptr
33+
__ranges/enable_borrowed_range.h
3334
__split_buffer
3435
__sso_allocator
3536
__std_stream
@@ -141,6 +142,7 @@ set(files
141142
ostream
142143
queue
143144
random
145+
ranges
144146
ratio
145147
regex
146148
scoped_allocator
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// -*- C++ -*-
2+
//===------------------ __ranges/enable_borrowed_range.h ------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
11+
#define _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
12+
13+
// These customization variables are used in <span> and <string_view>. The
14+
// separate header is used to avoid including the entire <ranges> header in
15+
// <span> and <string_view>.
16+
17+
#include <__config>
18+
19+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20+
#pragma GCC system_header
21+
#endif
22+
23+
_LIBCPP_PUSH_MACROS
24+
#include <__undef_macros>
25+
26+
_LIBCPP_BEGIN_NAMESPACE_STD
27+
28+
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
29+
30+
namespace ranges
31+
{
32+
33+
// [range.range], ranges
34+
35+
template <class>
36+
inline constexpr bool enable_borrowed_range = false;
37+
38+
} // namespace ranges
39+
40+
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
41+
42+
_LIBCPP_END_NAMESPACE_STD
43+
44+
_LIBCPP_POP_MACROS
45+
46+
#endif // _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H

libcxx/include/module.modulemap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ module std [system] {
409409
export initializer_list
410410
export *
411411
}
412+
module ranges {
413+
header "ranges"
414+
export *
415+
}
412416
module ratio {
413417
header "ratio"
414418
export *

libcxx/include/ranges

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// -*- C++ -*-
2+
//===--------------------------- ranges -----------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP_RANGES
11+
#define _LIBCPP_RANGES
12+
13+
/*
14+
15+
#include <compare> // see [compare.syn]
16+
#include <initializer_list> // see [initializer.list.syn]
17+
#include <iterator> // see [iterator.synopsis]
18+
19+
namespace std::ranges {
20+
// [range.range], ranges
21+
template<class T>
22+
inline constexpr bool enable_borrowed_range = false;
23+
}
24+
25+
*/
26+
27+
#include <__config>
28+
#include <__ranges/enable_borrowed_range.h>
29+
#include <compare> // Required by the standard.
30+
#include <initializer_list> // Required by the standard.
31+
#include <iterator> // Required by the standard.
32+
#include <type_traits>
33+
#include <version>
34+
35+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
36+
#pragma GCC system_header
37+
#endif
38+
39+
_LIBCPP_PUSH_MACROS
40+
#include <__undef_macros>
41+
42+
_LIBCPP_BEGIN_NAMESPACE_STD
43+
44+
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
45+
46+
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
47+
48+
_LIBCPP_END_NAMESPACE_STD
49+
50+
_LIBCPP_POP_MACROS
51+
52+
#endif // _LIBCPP_RANGES

libcxx/include/span

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
2222
template <class ElementType, size_t Extent = dynamic_extent>
2323
class span;
2424
25+
template<class ElementType, size_t Extent>
26+
inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
27+
2528
// [span.objectrep], views of object representation
2629
template <class ElementType, size_t Extent>
2730
span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
@@ -32,7 +35,6 @@ template <class ElementType, size_t Extent>
3235
(sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
3336
3437
35-
namespace std {
3638
template <class ElementType, size_t Extent = dynamic_extent>
3739
class span {
3840
public:
@@ -123,6 +125,7 @@ template<class Container>
123125
*/
124126

125127
#include <__config>
128+
#include <__ranges/enable_borrowed_range.h>
126129
#include <array> // for array
127130
#include <cstddef> // for byte
128131
#include <iterator> // for iterators
@@ -516,6 +519,11 @@ private:
516519
size_type __size;
517520
};
518521

522+
#if !defined(_LIBCPP_HAS_NO_RANGES)
523+
template <class _Tp, size_t _Extent>
524+
inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
525+
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
526+
519527
// as_bytes & as_writable_bytes
520528
template <class _Tp, size_t _Extent>
521529
_LIBCPP_INLINE_VISIBILITY

libcxx/include/string_view

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ namespace std {
1919
template<class charT, class traits = char_traits<charT>>
2020
class basic_string_view;
2121
22+
template<class charT, class traits>
23+
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20
24+
2225
// 7.9, basic_string_view non-member comparison functions
2326
template<class charT, class traits>
2427
constexpr bool operator==(basic_string_view<charT, traits> x,
@@ -179,6 +182,7 @@ namespace std {
179182
*/
180183

181184
#include <__config>
185+
#include <__ranges/enable_borrowed_range.h>
182186
#include <__string>
183187
#include <iosfwd>
184188
#include <algorithm>
@@ -649,6 +653,10 @@ private:
649653
size_type __size;
650654
};
651655

656+
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
657+
template <class _CharT, class _Traits>
658+
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
659+
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
652660

653661
// [string.view.comparison]
654662
// operator ==

libcxx/test/libcxx/double_include.sh.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
#endif
144144
#include <queue>
145145
#include <random>
146+
#include <ranges>
146147
#include <ratio>
147148
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
148149
# include <regex>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// WARNING: This test was generated by generate_header_inclusion_tests.py
10+
// and should not be edited manually.
11+
//
12+
// clang-format off
13+
14+
// UNSUPPORTED: c++03, c++11, c++14, c++17
15+
16+
// <ranges>
17+
18+
// Test that <ranges> includes all the other headers it's supposed to.
19+
20+
#include <ranges>
21+
#include "test_macros.h"
22+
23+
#if !defined(_LIBCPP_RANGES)
24+
# error "<ranges> was expected to define _LIBCPP_RANGES"
25+
#endif
26+
#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
27+
# error "<ranges> should include <compare> in C++20 and later"
28+
#endif
29+
#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
30+
# error "<ranges> should include <initializer_list> in C++20 and later"
31+
#endif
32+
#if !defined(_LIBCPP_ITERATOR)
33+
# error "<ranges> should include <iterator> in C++20 and later"
34+
#endif

0 commit comments

Comments
 (0)