[libcxx][ranges] Add `ranges::common_view`.
Differential Revision: https://reviews.llvm.org/D105753
NOKEYCHECK=True
GitOrigin-RevId: e5d8b93e5a25072ec27260e162f5a036a2c32dc2
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index fc095df..dd4b812 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -184,6 +184,7 @@
__random/uniform_int_distribution.h
__ranges/access.h
__ranges/all.h
+ __ranges/common_view.h
__ranges/concepts.h
__ranges/copyable_box.h
__ranges/dangling.h
diff --git a/include/__ranges/common_view.h b/include/__ranges/common_view.h
new file mode 100644
index 0000000..dab8260
--- /dev/null
+++ b/include/__ranges/common_view.h
@@ -0,0 +1,113 @@
+// -*- 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_COMMON_VIEW_H
+#define _LIBCPP___RANGES_COMMON_VIEW_H
+
+#include <__config>
+#include <__iterator/common_iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <concepts>
+#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 {
+
+template<view _View>
+ requires (!common_range<_View> && copyable<iterator_t<_View>>)
+class common_view : public view_interface<common_view<_View>> {
+ _View __base_ = _View();
+
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ common_view() requires default_initializable<_View> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit common_view(_View __v) : __base_(_VSTD::move(__v)) { }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() && { return _VSTD::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin() {
+ if constexpr (random_access_range<_View> && sized_range<_View>)
+ return ranges::begin(__base_);
+ else
+ return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin() const requires range<const _View> {
+ if constexpr (random_access_range<const _View> && sized_range<const _View>)
+ return ranges::begin(__base_);
+ else
+ return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() {
+ if constexpr (random_access_range<_View> && sized_range<_View>)
+ return ranges::begin(__base_) + ranges::size(__base_);
+ else
+ return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() const requires range<const _View> {
+ if constexpr (random_access_range<const _View> && sized_range<const _View>)
+ return ranges::begin(__base_) + ranges::size(__base_);
+ else
+ return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto size() requires sized_range<_View> {
+ return ranges::size(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto size() const requires sized_range<const _View> {
+ return ranges::size(__base_);
+ }
+};
+
+template<class _Range>
+common_view(_Range&&)
+ -> common_view<views::all_t<_Range>>;
+
+template<class _View>
+inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>;
+
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_COMMON_VIEW_H
diff --git a/include/module.modulemap b/include/module.modulemap
index 982002e..11cabad 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -613,6 +613,7 @@
module __ranges {
module access { private header "__ranges/access.h" }
module all { private header "__ranges/all.h" }
+ module common_view { private header "__ranges/common_view.h" }
module concepts { private header "__ranges/concepts.h" }
module copyable_box { private header "__ranges/copyable_box.h" }
module dangling { private header "__ranges/dangling.h" }
diff --git a/include/ranges b/include/ranges
index 45825fd..ff78973 100644
--- a/include/ranges
+++ b/include/ranges
@@ -146,6 +146,13 @@
can-reference<invoke_result_t<F&, range_reference_t<V>>>
class transform_view;
+ // [range.common], common view
+ template<view V>
+ requires (!common_range<V> && copyable<iterator_t<V>>)
+ class common_view;
+
+ template<class T>
+ inline constexpr bool enable_borrowed_range<common_view<T>> = enable_borrowed_range<T>;
}
*/
@@ -153,6 +160,7 @@
#include <__config>
#include <__ranges/access.h>
#include <__ranges/all.h>
+#include <__ranges/common_view.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
#include <__ranges/data.h>