[libcxx-commits] [libcxx] 74fd3cb - [libcxx][ranges] implements dangling, borrowed_iterator_t, borrowed_subrange_t
Christopher Di Bella via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jul 21 14:35:12 PDT 2021
Author: Christopher Di Bella
Date: 2021-07-21T21:34:13Z
New Revision: 74fd3cb8cd3ea41219d522412f4408d9993352ef
URL: https://github.com/llvm/llvm-project/commit/74fd3cb8cd3ea41219d522412f4408d9993352ef
DIFF: https://github.com/llvm/llvm-project/commit/74fd3cb8cd3ea41219d522412f4408d9993352ef.diff
LOG: [libcxx][ranges] implements dangling, borrowed_iterator_t, borrowed_subrange_t
* Implements part of P0896 'The One Ranges Proposal'
* Implements http://wg21.link/range.dangling
Reviewed By: zoecarver
Differential Revision: https://reviews.llvm.org/D105205
Added:
libcxx/include/__ranges/dangling.h
libcxx/test/libcxx/diagnostics/detail.headers/ranges/dangling.module.verify.cpp
libcxx/test/std/ranges/range.utility/range.dangling/borrowed_iterator.compile.pass.cpp
libcxx/test/std/ranges/range.utility/range.dangling/borrowed_subrange.compile.pass.cpp
libcxx/test/std/ranges/range.utility/range.dangling/dangling.pass.cpp
Modified:
libcxx/docs/Status/RangesPaper.csv
libcxx/include/CMakeLists.txt
libcxx/include/__ranges/subrange.h
libcxx/include/module.modulemap
libcxx/include/ranges
Removed:
################################################################################
diff --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv
index 3fadfc3f15fa..02c764c8e8bc 100644
--- a/libcxx/docs/Status/RangesPaper.csv
+++ b/libcxx/docs/Status/RangesPaper.csv
@@ -133,7 +133,7 @@ Section,Description,Dependencies,Assignee,Complete
`[range.dangling] <http://wg21.link/range.dangling>`_,"| ranges::dangling
| ranges::borrowed_iterator_t
| ranges::borrowed_subrange_t","| [range.range]
-| [range.subrange]",Unassigned,Not started
+| [range.subrange]",Christopher Di Bella,✅
`[range.all] <http://wg21.link/range.all>`_,`view::all <https://llvm.org/D102028>`_,"[range.subrange], [range.view.ref]",Zoe Carver,✅
`[range.view.ref] <http://wg21.link/range.view>`_,`ref-view <https://llvm.org/D102020>`_,[view.interface],Zoe Carver,✅
`[range.filter] <http://wg21.link/range.filter>`_,filter_view,[range.all],Louis Dionne,Not started
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index fd86cf114822..007d3f6a4c5b 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -186,6 +186,7 @@ set(files
__ranges/all.h
__ranges/concepts.h
__ranges/copyable_box.h
+ __ranges/dangling.h
__ranges/data.h
__ranges/drop_view.h
__ranges/empty_view.h
diff --git a/libcxx/include/__ranges/dangling.h b/libcxx/include/__ranges/dangling.h
new file mode 100644
index 000000000000..deb02a1a448d
--- /dev/null
+++ b/libcxx/include/__ranges/dangling.h
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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_DANGLING_H
+#define _LIBCPP___RANGES_DANGLING_H
+
+#include <__config>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+struct dangling {
+ dangling() = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr dangling(auto&&...) noexcept {}
+};
+
+template <range _Rp>
+using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>;
+
+// borrowed_subrange_t defined in <__ranges/subrange.h>
+} // namespace ranges
+
+#endif // !_LIBCPP_HAS_NO_RANGES
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_DANGLING_H
diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h
index e3ed8657583f..25d333db02de 100644
--- a/libcxx/include/__ranges/subrange.h
+++ b/libcxx/include/__ranges/subrange.h
@@ -16,6 +16,7 @@
#include <__iterator/advance.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
@@ -248,6 +249,9 @@ namespace ranges {
template<class _Ip, class _Sp, subrange_kind _Kp>
inline constexpr bool enable_borrowed_range<subrange<_Ip, _Sp, _Kp>> = true;
+
+ template<range _Rp>
+ using borrowed_subrange_t = _If<borrowed_range<_Rp>, subrange<iterator_t<_Rp> >, dangling>;
} // namespace ranges
using ranges::get;
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index ecd853c8536b..69316985467e 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -606,6 +606,7 @@ module std [system] {
module all { private header "__ranges/all.h" }
module concepts { private header "__ranges/concepts.h" }
module copyable_box { private header "__ranges/copyable_box.h" }
+ module dangling { private header "__ranges/dangling.h" }
module data { private header "__ranges/data.h" }
module drop_view { private header "__ranges/drop_view.h" }
module empty { private header "__ranges/empty.h" }
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 367ad60226d4..45825fde7293 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -103,6 +103,15 @@ namespace std::ranges {
template<class I, class S, subrange_kind K>
inline constexpr bool enable_borrowed_range<subrange<I, S, K>> = true;
+ // [range.dangling], dangling iterator handling
+ struct dangling;
+
+ template<range R>
+ using borrowed_iterator_t = see below;
+
+ template<range R>
+ using borrowed_subrange_t = see below;
+
// [range.empty], empty view
template<class T>
requires is_object_v<T>
@@ -145,6 +154,7 @@ namespace std::ranges {
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
#include <__ranges/data.h>
#include <__ranges/drop_view.h>
#include <__ranges/empty.h>
diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/ranges/dangling.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/ranges/dangling.module.verify.cpp
new file mode 100644
index 000000000000..5f4fa40cac61
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/detail.headers/ranges/dangling.module.verify.cpp
@@ -0,0 +1,16 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: modules-build
+
+// WARNING: This test was generated by 'generate_private_header_tests.py'
+// and should not be edited manually.
+
+// expected-error@*:* {{use of private header from outside its module: '__ranges/dangling.h'}}
+#include <__ranges/dangling.h>
diff --git a/libcxx/test/std/ranges/range.utility/range.dangling/borrowed_iterator.compile.pass.cpp b/libcxx/test/std/ranges/range.utility/range.dangling/borrowed_iterator.compile.pass.cpp
new file mode 100644
index 000000000000..bff34a75c834
--- /dev/null
+++ b/libcxx/test/std/ranges/range.utility/range.dangling/borrowed_iterator.compile.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// std::ranges::borrowed_iterator_t;
+
+#include <ranges>
+
+#include <concepts>
+#include <span>
+#include <string>
+#include <string_view>
+#include <vector>
+
+static_assert(std::same_as<std::ranges::borrowed_iterator_t<std::string>, std::ranges::dangling>);
+static_assert(std::same_as<std::ranges::borrowed_iterator_t<std::string&&>, std::ranges::dangling>);
+static_assert(std::same_as<std::ranges::borrowed_iterator_t<std::vector<int> >, std::ranges::dangling>);
+
+static_assert(std::same_as<std::ranges::borrowed_iterator_t<std::string&>, std::string::iterator>);
+static_assert(std::same_as<std::ranges::borrowed_iterator_t<std::string_view>, std::string_view::iterator>);
+static_assert(std::same_as<std::ranges::borrowed_iterator_t<std::span<int> >, std::span<int>::iterator>);
+
+template <class T>
+constexpr bool has_borrowed_iterator = requires {
+ typename std::ranges::borrowed_iterator_t<T>;
+};
+
+static_assert(!has_borrowed_iterator<int>);
diff --git a/libcxx/test/std/ranges/range.utility/range.dangling/borrowed_subrange.compile.pass.cpp b/libcxx/test/std/ranges/range.utility/range.dangling/borrowed_subrange.compile.pass.cpp
new file mode 100644
index 000000000000..73271450e5f1
--- /dev/null
+++ b/libcxx/test/std/ranges/range.utility/range.dangling/borrowed_subrange.compile.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// std::ranges::borrowed_subrange_t;
+
+#include <ranges>
+
+#include <concepts>
+#include <span>
+#include <string>
+#include <string_view>
+#include <vector>
+
+static_assert(std::same_as<std::ranges::borrowed_subrange_t<std::string>, std::ranges::dangling>);
+static_assert(std::same_as<std::ranges::borrowed_subrange_t<std::string&&>, std::ranges::dangling>);
+static_assert(std::same_as<std::ranges::borrowed_subrange_t<std::vector<int> >, std::ranges::dangling>);
+
+static_assert(
+ std::same_as<std::ranges::borrowed_subrange_t<std::string&>, std::ranges::subrange<std::string::iterator> >);
+
+static_assert(
+ std::same_as<std::ranges::borrowed_subrange_t<std::span<int> >, std::ranges::subrange<std::span<int>::iterator> >);
+
+static_assert(std::same_as<std::ranges::borrowed_subrange_t<std::string_view>,
+ std::ranges::subrange<std::string_view::iterator> >);
+
+template <class T>
+constexpr bool has_type = requires {
+ typename std::ranges::borrowed_subrange_t<T>;
+};
+
+static_assert(!has_type<int>);
+
+struct S {};
+static_assert(!has_type<S>);
diff --git a/libcxx/test/std/ranges/range.utility/range.dangling/dangling.pass.cpp b/libcxx/test/std/ranges/range.utility/range.dangling/dangling.pass.cpp
new file mode 100644
index 000000000000..b04d823c31c0
--- /dev/null
+++ b/libcxx/test/std/ranges/range.utility/range.dangling/dangling.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// std::ranges::dangling;
+
+#include <ranges>
+
+#include <concepts>
+#include <type_traits>
+
+static_assert(std::is_empty_v<std::ranges::dangling>);
+
+template<int> struct S { };
+static_assert(std::is_nothrow_constructible_v<std::ranges::dangling>);
+static_assert(std::is_nothrow_constructible_v<std::ranges::dangling, S<0>>);
+static_assert(std::is_nothrow_constructible_v<std::ranges::dangling, S<0>, S<1>>);
+static_assert(std::is_nothrow_constructible_v<std::ranges::dangling, S<0>, S<1>, S<2>>);
+
+constexpr bool test_dangling() {
+ [[maybe_unused]] auto a = std::ranges::dangling();
+ [[maybe_unused]] auto b = std::ranges::dangling(S<0>());
+ [[maybe_unused]] auto c = std::ranges::dangling(S<0>(), S<1>());
+ [[maybe_unused]] auto d = std::ranges::dangling(S<0>(), S<1>(), S<2>());
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(test_dangling());
+ test_dangling();
+ return 0;
+}
More information about the libcxx-commits
mailing list