forked from OSchip/llvm-project
[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
This commit is contained in:
parent
aa80ea8a61
commit
01ace074fc
|
@ -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","",""
|
||||
|
|
|
|
@ -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","* *",""
|
||||
|
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -409,6 +409,10 @@ module std [system] {
|
|||
export initializer_list
|
||||
export *
|
||||
}
|
||||
module ranges {
|
||||
header "ranges"
|
||||
export *
|
||||
}
|
||||
module ratio {
|
||||
header "ratio"
|
||||
export *
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 ==
|
||||
|
|
|
@ -143,6 +143,7 @@
|
|||
#endif
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
#include <ratio>
|
||||
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
|
||||
# include <regex>
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
#endif
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <ranges>
|
||||
#include <ratio>
|
||||
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
|
||||
# include <regex>
|
||||
|
|
|
@ -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; }
|
|
@ -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>);
|
||||
}
|
|
@ -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; }
|
|
@ -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.
|
||||
}
|
|
@ -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> >);
|
||||
}
|
|
@ -42,7 +42,7 @@ mandatory_inclusions = {
|
|||
"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"],
|
||||
|
|
Loading…
Reference in New Issue