Remove __cplusplus > 201703L checks that are redundant when used alongside __glibcxx_concepts checks, because <version> already guarantees that __glibcxx_concepts is only defined for C++20 and later.
Prefer to check __glibcxx_ranges for features such as move_sentinel that were added by the One Ranges proposal (P0896R4), or for features which depend on other components introduced by that proposal. But prefer to check __glibcxx_concepts for constraints that only depend on requires-clauses and concepts defined in <concepts>, even if those constraints were added by the Ranges proposal (e.g. the constraints on non-member operators for move_iterator). Prefer #ifdef to #if when just testing for the presence of __glibcxx_foo macros with caring about their value. Also add/tweak some Doxygen comments. libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h: Make use of feature test macros more consistent. Improve doxygen comments. --- Tested x86_64-linux. Pushed to trunk. libstdc++-v3/include/bits/stl_iterator.h | 102 ++++++++++++----------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 5962ab3af3b..8c86cb214b2 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -91,7 +91,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ -#if __glibcxx_concepts +#ifdef __glibcxx_concepts + /// @cond undocumented namespace __detail { // Weaken iterator_category _Cat to _Limit if it is derived from that, @@ -100,6 +101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __clamp_iter_cat = __conditional_t<derived_from<_Cat, _Limit>, _Limit, _Otherwise>; } + /// @endcond #endif // Ignore warnings about std::iterator. @@ -136,7 +138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Iter> friend class reverse_iterator; -#if __glibcxx_concepts +#ifdef __glibcxx_concepts // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3435. three_way_comparable_with<reverse_iterator<int*>, [...]> template<typename _Iter> @@ -152,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: typedef _Iterator iterator_type; typedef typename __traits_type::pointer pointer; -#if ! __glibcxx_concepts +#ifndef __glibcxx_concepts typedef typename __traits_type::difference_type difference_type; typedef typename __traits_type::reference reference; #else @@ -208,7 +210,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * underlying %iterator can be converted to the type of @c current. */ template<typename _Iter> -#if __glibcxx_concepts +#ifdef __glibcxx_concepts requires __convertible<_Iter> #endif _GLIBCXX17_CONSTEXPR @@ -219,10 +221,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L template<typename _Iter> -#if __glibcxx_concepts +# ifdef __glibcxx_concepts requires __convertible<_Iter> && assignable_from<_Iterator&, const _Iter&> -#endif +# endif _GLIBCXX17_CONSTEXPR reverse_iterator& operator=(const reverse_iterator<_Iter>& __x) @@ -231,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION current = __x.current; return *this; } -#endif +#endif // C++11 /** * @return @c current, the %iterator used for underlying work. @@ -268,7 +270,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_NODISCARD _GLIBCXX17_CONSTEXPR pointer operator->() const -#if __cplusplus > 201703L && __cpp_concepts >= 201907L +#ifdef __glibcxx_concepts requires is_pointer_v<_Iterator> || requires(const _Iterator __i) { __i.operator->(); } #endif @@ -386,7 +388,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator[](difference_type __n) const { return *(*this + __n); } -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges [[nodiscard]] friend constexpr iter_rvalue_reference_t<_Iterator> iter_move(const reverse_iterator& __i) @@ -410,7 +412,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __ytmp = __y.base(); ranges::iter_swap(--__xtmp, --__ytmp); } -#endif +#endif // ranges private: template<typename _Tp> @@ -434,7 +436,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * iterators. * */ -#if __cplusplus <= 201703L || ! defined __glibcxx_concepts +#ifndef __glibcxx_concepts template<typename _Iterator> _GLIBCXX_NODISCARD inline _GLIBCXX17_CONSTEXPR bool @@ -645,7 +647,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION make_reverse_iterator(_Iterator __i) { return reverse_iterator<_Iterator>(__i); } -# if __cplusplus > 201703L && defined __glibcxx_concepts +# ifdef __glibcxx_ranges template<typename _Iterator1, typename _Iterator2> requires (!sized_sentinel_for<_Iterator1, _Iterator2>) inline constexpr bool @@ -681,7 +683,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: /// A nested typedef for the type of whatever container you used. typedef _Container container_type; -#if __cplusplus > 201703L +#ifdef __glibcxx_ranges using difference_type = ptrdiff_t; #endif @@ -782,7 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: /// A nested typedef for the type of whatever container you used. typedef _Container container_type; -#if __cplusplus > 201703L +#ifdef __glibcxx_ranges using difference_type = ptrdiff_t; #endif @@ -881,7 +883,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class insert_iterator : public iterator<output_iterator_tag, void, void, void, void> { -#if __cplusplus > 201703L && defined __glibcxx_concepts +#ifdef __glibcxx_ranges using _Iter = std::__detail::__range_iter_t<_Container>; #else typedef typename _Container::iterator _Iter; @@ -894,7 +896,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// A nested typedef for the type of whatever container you used. typedef _Container container_type; -#if __cplusplus > 201703L && defined __glibcxx_concepts +#ifdef __glibcxx_ranges using difference_type = ptrdiff_t; #endif @@ -990,7 +992,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * template parameter deduction, making the compiler match the correct * types for you. */ -#if __cplusplus > 201703L && defined __glibcxx_concepts +#ifdef __glibcxx_ranges template<typename _Container> [[nodiscard]] constexpr insert_iterator<_Container> @@ -1042,7 +1044,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename __traits_type::reference reference; typedef typename __traits_type::pointer pointer; -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges using iterator_concept = std::__detail::__iter_concept<_Iterator>; #endif @@ -1168,7 +1170,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // provide overloads whose operands are of the same type. Can someone // remind me what generic programming is about? -- Gaby -#if __cpp_lib_three_way_comparison +#ifdef __cpp_lib_three_way_comparison template<typename _IteratorL, typename _IteratorR, typename _Container> [[nodiscard, __gnu__::__always_inline__]] constexpr bool @@ -1354,7 +1356,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges + /// A sentinel adaptor for use with std::move_iterator. template<semiregular _Sent> class move_sentinel { @@ -1394,11 +1397,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: _Sent _M_last; }; -#endif // C++20 + /// @cond undocumented namespace __detail { -#if __cplusplus > 201703L && __glibcxx_concepts template<typename _Iterator> struct __move_iter_cat { }; @@ -1411,11 +1413,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION = __clamp_iter_cat<__iter_category_t<_Iterator>, random_access_iterator_tag>; }; -#endif } + /// @endcond +#endif // ranges // 24.4.3 Move iterators - /** + /** @brief An iterator adaptor that yields an rvalue reference. + * * Class template move_iterator is an iterator adapter with the same * behavior as the underlying iterator except that its dereference * operator implicitly converts the value returned by the underlying @@ -1425,21 +1429,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _Iterator> class move_iterator -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges : public __detail::__move_iter_cat<_Iterator> #endif { _Iterator _M_current; using __traits_type = iterator_traits<_Iterator>; -#if ! (__cplusplus > 201703L && __glibcxx_concepts) +#ifndef __glibcxx_ranges using __base_ref = typename __traits_type::reference; #endif template<typename _Iter2> friend class move_iterator; -#if __glibcxx_concepts // C++20 && concepts +#ifdef __glibcxx_concepts // C++20 && concepts // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3435. three_way_comparable_with<reverse_iterator<int*>, [...]> template<typename _Iter2> @@ -1447,7 +1451,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && convertible_to<const _Iter2&, _Iterator>; #endif -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges static auto _S_iter_concept() { @@ -1496,7 +1500,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_current(std::move(__i)) { } template<typename _Iter> -#if __glibcxx_concepts +#ifdef __glibcxx_concepts requires __convertible<_Iter> #endif _GLIBCXX17_CONSTEXPR @@ -1504,7 +1508,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_current(__i._M_current) { } template<typename _Iter> -#if __glibcxx_concepts +#ifdef __glibcxx_concepts requires __convertible<_Iter> && assignable_from<_Iterator&, const _Iter&> #endif @@ -1535,7 +1539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[__nodiscard__]] _GLIBCXX17_CONSTEXPR reference operator*() const -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges { return ranges::iter_move(_M_current); } #else { return static_cast<reference>(*_M_current); } @@ -1561,7 +1565,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __tmp; } -#if __glibcxx_concepts +#ifdef __glibcxx_concepts constexpr void operator++(int) requires (!forward_iterator<_Iterator>) { ++_M_current; } @@ -1609,13 +1613,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[__nodiscard__]] _GLIBCXX17_CONSTEXPR reference operator[](difference_type __n) const -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges { return ranges::iter_move(_M_current + __n); } #else { return std::move(_M_current[__n]); } #endif -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges template<sentinel_for<_Iterator> _Sent> [[nodiscard]] friend constexpr bool @@ -1653,12 +1657,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline _GLIBCXX17_CONSTEXPR bool operator==(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_concepts requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; } #endif { return __x.base() == __y.base(); } -#if __cpp_lib_three_way_comparison +#ifdef __cpp_lib_three_way_comparison template<typename _IteratorL, three_way_comparable_with<_IteratorL> _IteratorR> [[__nodiscard__]] @@ -1680,7 +1684,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline _GLIBCXX17_CONSTEXPR bool operator<(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_concepts requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; } #endif { return __x.base() < __y.base(); } @@ -1690,7 +1694,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline _GLIBCXX17_CONSTEXPR bool operator<=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_concepts requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; } #endif { return !(__y < __x); } @@ -1700,7 +1704,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline _GLIBCXX17_CONSTEXPR bool operator>(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_concepts requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; } #endif { return __y < __x; } @@ -1710,7 +1714,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline _GLIBCXX17_CONSTEXPR bool operator>=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_concepts requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; } #endif { return !(__x < __y); } @@ -1725,7 +1729,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const move_iterator<_Iterator>& __y) { return __x.base() == __y.base(); } -#if __cpp_lib_three_way_comparison +#ifdef __cpp_lib_three_way_comparison template<three_way_comparable _Iterator> [[__nodiscard__]] constexpr compare_three_way_result_t<_Iterator> @@ -1825,7 +1829,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter) #endif // C++11 -#if __cplusplus > 201703L && __glibcxx_concepts +#ifdef __glibcxx_ranges // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3736. move_iterator missing disable_sized_sentinel_for specialization template<typename _Iterator1, typename _Iterator2> @@ -1836,6 +1840,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [iterators.common] Common iterators + /// @cond undocumented namespace __detail { template<typename _It> @@ -1850,6 +1855,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && constructible_from<iter_value_t<_It>, iter_reference_t<_It>> && move_constructible<iter_value_t<_It>>; } // namespace __detail + /// @endcond /// An iterator/sentinel adaptor for representing a non-common range. template<input_or_output_iterator _It, sentinel_for<_It> _Sent> @@ -2309,6 +2315,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [iterators.counted] Counted iterators + /// @cond undocumented namespace __detail { template<typename _It> @@ -2337,6 +2344,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __counted_iter_cat<_It> { using iterator_category = typename _It::iterator_category; }; } + /// @endcond /// An iterator adaptor that keeps track of the distance to the end. template<input_or_output_iterator _It> @@ -2583,7 +2591,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void>; }; -#if __glibcxx_ranges_as_const // >= C++23 +#ifdef __glibcxx_ranges_as_const // >= C++23 template<indirectly_readable _It> using iter_const_reference_t = common_reference_t<const iter_value_t<_It>&&, iter_reference_t<_It>>; @@ -2956,8 +2964,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION make_const_sentinel(_Sent __s) noexcept(is_nothrow_convertible_v<_Sent, const_sentinel<_Sent>>) { return __s; } -#endif // C++23 -#endif // C++20 +#endif // C++23 ranges_as_const +#endif // C++20 ranges /// @} group iterators @@ -3072,7 +3080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // of associative containers. template<typename _InputIterator> using __iter_key_t = remove_const_t< -#if __glibcxx_tuple_like // >= C++23 +#ifdef __glibcxx_tuple_like // >= C++23 tuple_element_t<0, typename iterator_traits<_InputIterator>::value_type>>; #else typename iterator_traits<_InputIterator>::value_type::first_type>; @@ -3080,7 +3088,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _InputIterator> using __iter_val_t -#if __glibcxx_tuple_like // >= C++23 +#ifdef __glibcxx_tuple_like // >= C++23 = tuple_element_t<1, typename iterator_traits<_InputIterator>::value_type>; #else = typename iterator_traits<_InputIterator>::value_type::second_type; -- 2.47.0