[libcxx-commits] [libcxx] [libcxx] P2278R4: implement `{basic_, }const_iterator`, and have `cbegin` et. al. return it (PR #99915)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 29 12:46:27 PDT 2024
================
@@ -0,0 +1,222 @@
+// -*- 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_CONST_ACCESS_H
+#define _LIBCPP___RANGES_CONST_ACCESS_H
+
+#include <__iterator/const_iterator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/rbegin.h>
+#include <__ranges/rend.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+// [range.const]
+# if _LIBCPP_STD_VER >= 23
+namespace ranges {
+template <input_range _Rp>
+_LIBCPP_HIDE_FROM_ABI constexpr auto& __possibly_const_range(_Rp& __rng) noexcept {
+ if constexpr (constant_range<const _Rp> && !constant_range<_Rp>) {
+ return const_cast<const _Rp&>(__rng);
+ } else {
+ return __rng;
+ }
+}
+} // namespace ranges
+# endif // _LIBCPP_STD_VER >= 23
+
+// [range.access.cbegin]
+namespace ranges {
+
+template <class _Type>
+concept __const_accessible_range = (!is_rvalue_reference_v<_Type&&> || enable_borrowed_range<remove_cv_t<_Type>>);
+
+namespace __cbegin {
+struct __fn {
+# if _LIBCPP_STD_VER >= 23
+ template <class _Rng>
+ using _UType = decltype(ranges::begin(ranges::__possibly_const_range(std::declval<_Rng&>())));
+
+ template <__const_accessible_range _Rng>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static auto
+ operator()(_Rng&& __rng) noexcept(noexcept(const_iterator<_UType<_Rng>>(
+ ranges::begin(ranges::__possibly_const_range(__rng))))) -> const_iterator<_UType<_Rng>> {
+ return const_iterator<_UType<_Rng>>(ranges::begin(ranges::__possibly_const_range(__rng)));
+ }
+# else // ^^^ _LIBCPP_STD_VER >= 23 / _LIBCPP_STD_VER < 23 vvv
+ template <class _Tp>
+ requires is_lvalue_reference_v<_Tp&&>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))))
+ -> decltype(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))) {
+ return ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t));
+ }
+
+ template <class _Tp>
+ requires is_rvalue_reference_v<_Tp&&>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::begin(static_cast<const _Tp&&>(__t))))
+ -> decltype(ranges::begin(static_cast<const _Tp&&>(__t))) {
+ return ranges::begin(static_cast<const _Tp&&>(__t));
+ }
+# endif // ^^^ _LIBCPP_STD_VER < 23
+};
+} // namespace __cbegin
+
+inline namespace __cpo {
+inline constexpr auto cbegin = __cbegin::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+# if _LIBCPP_STD_VER >= 23
+// [range.range]
+namespace ranges {
----------------
ldionne wrote:
Can we avoid closing and reopening the `ranges` namespace here and above? IMO that would make the code a bit lighter.
https://github.com/llvm/llvm-project/pull/99915
More information about the libcxx-commits
mailing list