aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-04-14 10:32:12 -0400
committerPatrick Palka <ppalka@redhat.com>2023-04-14 10:32:12 -0400
commit0d94c6df183375caaa7f672e288a2094ca813749 (patch)
tree0d5f5f1c1a656b0632467f560cb721e65298b112 /libstdc++-v3/include/std
parent2ab0d83e8880fe747af3f137aef382d2d4c09e4c (diff)
downloadgcc-0d94c6df183375caaa7f672e288a2094ca813749.zip
gcc-0d94c6df183375caaa7f672e288a2094ca813749.tar.gz
gcc-0d94c6df183375caaa7f672e288a2094ca813749.tar.bz2
libstdc++: Implement P2278R4 "cbegin should always return a constant iterator"
This also implements the approved follow-up LWG issues 3765, 3766, 3769, 3770, 3811, 3850, 3853, 3862 and 3872. libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (const_iterator_t): Define for C++23. (const_sentinel_t): Likewise. (range_const_reference_t): Likewise. (constant_range): Likewise. (__cust_access::__possibly_const_range): Likewise, replacing ... (__cust_access::__as_const): ... this. (__cust_access::_CBegin::operator()): Redefine for C++23 as per P2278R4. (__cust_access::_CEnd::operator()): Likewise. (__cust_access::_CRBegin::operator()): Likewise. (__cust_access::_CREnd::operator()): Likewise. (__cust_access::_CData::operator()): Likewise. * include/bits/ranges_util.h (ranges::__detail::__different_from): Make it an alias of std::__detail::__different_from. (view_interface::cbegin): Define for C++23. (view_interface::cend): Likewise. * include/bits/stl_iterator.h (__detail::__different_from): Define. (iter_const_reference_t): Define for C++23. (__detail::__constant_iterator): Likewise. (__detail::__is_const_iterator): Likewise. (__detail::__not_a_const_iterator): Likewise. (__detail::__iter_const_rvalue_reference_t): Likewise. (__detail::__basic_const_iter_cat):: Likewise. (const_iterator): Likewise. (__detail::__const_sentinel): Likewise. (const_sentinel): Likewise. (basic_const_iterator): Likewise. (common_type<basic_const_iterator<_Tp>, _Up>): Likewise. (common_type<_Up, basic_const_iterator<_Tp>>): Likewise. (common_type<basic_const_iterator<_Tp>, basic_const_iterator<Up>>): Likewise. (make_const_iterator): Define for C++23. (make_const_sentinel): Likewise. * include/std/ranges (__cpp_lib_ranges_as_const): Likewise. (as_const_view): Likewise. (enable_borrowed_range<as_const_view>): Likewise. (views::__detail::__is_ref_view): Likewise. (views::__detail::__can_is_const_view): Likewise. (views::_AsConst, views::as_const): Likewise. * include/std/span (span::const_iterator): Likewise. (span::const_reverse_iterator): Likewise. (span::cbegin): Likewise. (span::cend): Likewise. (span::crbegin): Likewise. (span::crend): Likewise. * include/std/version (__cpp_lib_ranges_as_const): Likewise. * testsuite/std/ranges/adaptors/join.cc (test06): Adjust to behave independently of C++20 vs C++23. * testsuite/std/ranges/version_c++23.cc: Verify value of __cpp_lib_ranges_as_const macro. * testsuite/24_iterators/const_iterator/1.cc: New test. * testsuite/std/ranges/adaptors/as_const/1.cc: New test.
Diffstat (limited to 'libstdc++-v3/include/std')
-rw-r--r--libstdc++-v3/include/std/ranges106
-rw-r--r--libstdc++-v3/include/std/span22
-rw-r--r--libstdc++-v3/include/std/version1
3 files changed, 129 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 3f6ff50..283d757 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -8929,6 +8929,112 @@ namespace views::__adaptor
inline constexpr _Enumerate enumerate;
}
+
+#define __cpp_lib_ranges_as_const 202207L
+
+ template<view _Vp>
+ requires input_range<_Vp>
+ class as_const_view : public view_interface<as_const_view<_Vp>>
+ {
+ _Vp _M_base = _Vp();
+
+ public:
+ as_const_view() requires default_initializable<_Vp> = default;
+
+ constexpr explicit
+ as_const_view(_Vp __base)
+ noexcept(is_nothrow_move_constructible_v<_Vp>)
+ : _M_base(std::move(__base))
+ { }
+
+ constexpr _Vp
+ base() const &
+ noexcept(is_nothrow_copy_constructible_v<_Vp>)
+ requires copy_constructible<_Vp>
+ { return _M_base; }
+
+ constexpr _Vp
+ base() &&
+ noexcept(is_nothrow_move_constructible_v<_Vp>)
+ { return std::move(_M_base); }
+
+ constexpr auto
+ begin() requires (!__detail::__simple_view<_Vp>)
+ { return ranges::cbegin(_M_base); }
+
+ constexpr auto
+ begin() const requires range<const _Vp>
+ { return ranges::cbegin(_M_base); }
+
+ constexpr auto
+ end() requires (!__detail::__simple_view<_Vp>)
+ { return ranges::cend(_M_base); }
+
+ constexpr auto
+ end() const requires range<const _Vp>
+ { return ranges::cend(_M_base); }
+
+ constexpr auto
+ size() requires sized_range<_Vp>
+ { return ranges::size(_M_base); }
+
+ constexpr auto
+ size() const requires sized_range<const _Vp>
+ { return ranges::size(_M_base); }
+ };
+
+ template<typename _Range>
+ as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
+
+ template<typename _Tp>
+ inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
+ = enable_borrowed_range<_Tp>;
+
+ namespace views
+ {
+ namespace __detail
+ {
+ template<typename _Tp>
+ inline constexpr bool __is_ref_view = false;
+
+ template<typename _Range>
+ inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
+
+ template<typename _Range>
+ concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
+ }
+
+ struct _AsConst : __adaptor::_RangeAdaptorClosure
+ {
+ template<viewable_range _Range>
+ constexpr auto
+ operator()(_Range&& __r) const
+ noexcept(noexcept(as_const_view(std::declval<_Range>())))
+ requires __detail::__can_as_const_view<_Range>
+ {
+ using _Tp = remove_cvref_t<_Range>;
+ using element_type = remove_reference_t<range_reference_t<_Range>>;
+ if constexpr (constant_range<views::all_t<_Range>>)
+ return views::all(std::forward<_Range>(__r));
+ else if constexpr (__detail::__is_empty_view<_Tp>)
+ return views::empty<const element_type>;
+ else if constexpr (std::__detail::__is_span<_Tp>)
+ return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
+ else if constexpr (__detail::__is_ref_view<_Tp>
+ && constant_range<const element_type>)
+ return ref_view(static_cast<const element_type&>
+ (std::forward<_Range>(__r).base()));
+ else if constexpr (is_lvalue_reference_v<_Range>
+ && constant_range<_Tp>
+ && !view<_Tp>)
+ return ref_view(static_cast<const _Tp&>(__r));
+ else
+ return as_const_view(std::forward<_Range>(__r));
+ }
+ };
+
+ inline constexpr _AsConst as_const;
+ }
#endif // C++23
} // namespace ranges
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 06d5c18..6763389 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -137,6 +137,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using const_reference = const element_type&;
using iterator = __gnu_cxx::__normal_iterator<pointer, span>;
using reverse_iterator = std::reverse_iterator<iterator>;
+#if __cplusplus > 202002L
+ using const_iterator = std::const_iterator<iterator>;
+ using const_reverse_iterator = std::const_iterator<reverse_iterator>;
+#endif
// member constants
static constexpr size_t extent = _Extent;
@@ -301,6 +305,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
rend() const noexcept
{ return reverse_iterator(this->begin()); }
+#if __cplusplus > 202002L
+ constexpr const_iterator
+ cbegin() const noexcept
+ { return begin(); }
+
+ constexpr const_iterator
+ cend() const noexcept
+ { return end(); }
+
+ constexpr const_reverse_iterator
+ crbegin() const noexcept
+ { return rbegin(); }
+
+ constexpr const_reverse_iterator
+ crend() const noexcept
+ { return rend(); }
+#endif
+
// subviews
template<size_t _Count>
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index d233b03..9f31f25 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -339,6 +339,7 @@
#define __cpp_lib_ranges_stride 202207L
#define __cpp_lib_ranges_cartesian_product 202207L
#define __cpp_lib_ranges_as_rvalue 202207L
+#define __cpp_lib_ranges_as_const 202207L
#define __cpp_lib_ranges_enumerate 202302L
#define __cpp_lib_fold 202207L
#if __cpp_constexpr_dynamic_alloc