[libc++] Split ABI flag for removing iterator bases and removing the second member in reverse_iterator (#143079)

Currently `_LIBCPP_NO_ITERATOR_BASES` controls both whether specific
classes derive from `iterator` and whether `reverse_iterator` has a
second member variable. These two changes are orthogonal though, and one
can be applied in all langauge modes while the other change is only
conforming for C++17 and later.
This commit is contained in:
Nikolas Klauser 2025-09-04 09:18:49 +02:00 committed by GitHub
parent cd44260ee6
commit e8fa13ca4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 61 additions and 69 deletions

View file

@ -44,6 +44,10 @@ This removes the ``iterator`` base class from ``back_insert_iterator``, ``front_
This doesn't directly affect the layout of these types in most cases, but may result in more padding being used when
they are used in combination, for example ``reverse_iterator<reverse_iterator<T>>``.
``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER``
-------------------------------------------------
This removes a second member in ``reverse_iterator`` that is unused after LWG2360.
``_LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION``
-------------------------------------------------
This changes the index type used inside ``variant`` to the smallest required type to reduce the datasize of variants in

View file

@ -75,11 +75,19 @@ Potentially breaking changes
first element being returned from ``find`` will be broken, and ``lower_bound`` or ``equal_range`` should be used
instead.
- The ABI flag ``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` has been split off from
``_LIBCPP_ABI_NO_ITERATOR_BASES``. If you are using this flag and care about ABI stability, you should set
``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` as well.
Announcements About Future Releases
-----------------------------------
ABI Affecting Changes
---------------------
- The ABI flag ``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` has been split off from
``_LIBCPP_ABI_NO_ITERATOR_BASES``. If you are using this flag and care about ABI stability, you should set
``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` as well.
Build System Changes
--------------------

View file

@ -72,6 +72,7 @@
# define _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE
# define _LIBCPP_ABI_NO_ITERATOR_BASES
# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT
# define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
@ -98,6 +99,15 @@
# endif
#endif
// TODO(LLVM 22): Remove this check
#if defined(_LIBCPP_ABI_NO_ITERATOR_BASES) && !defined(_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER)
# ifndef _LIBCPP_ONLY_NO_ITERATOR_BASES
# error "You probably want to define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER. This has been split out from" \
" _LIBCPP_ABI_NO_ITERATOR_BASES to allow only removing the second iterator member, since they aren't really related." \
"If you actually want this ABI configuration, please define _LIBCPP_ONLY_NO_ITERATOR_BASES instead."
# endif
#endif
// We had some bugs where we use [[no_unique_address]] together with construct_at,
// which causes UB as the call on construct_at could write to overlapping subobjects
//

View file

@ -26,15 +26,9 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Container>
class back_insert_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<back_insert_iterator<_Container>, output_iterator_tag, void, void, void, void> {
protected:
_Container* container;

View file

@ -26,15 +26,9 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Container>
class front_insert_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<front_insert_iterator<_Container>, output_iterator_tag, void, void, void, void> {
protected:
_Container* container;

View file

@ -35,15 +35,9 @@ template <class _Container>
using __insert_iterator_iter_t _LIBCPP_NODEBUG = typename _Container::iterator;
#endif
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Container>
class insert_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<insert_iterator<_Container>, output_iterator_tag, void, void, void, void> {
protected:
_Container* container;
__insert_iterator_iter_t<_Container> iter;

View file

@ -25,15 +25,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
class istream_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<istream_iterator<_Tp, _CharT, _Traits, _Distance>,
input_iterator_tag,
_Tp,
_Distance,
const _Tp*,
const _Tp&> {
public:
typedef input_iterator_tag iterator_category;
typedef _Tp value_type;

View file

@ -25,15 +25,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _CharT, class _Traits>
class istreambuf_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, _CharT*, _CharT>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<istreambuf_iterator<_CharT, _Traits>,
input_iterator_tag,
_CharT,
typename _Traits::off_type,
_CharT*,
_CharT> {
public:
typedef input_iterator_tag iterator_category;
typedef _CharT value_type;

View file

@ -28,6 +28,19 @@ struct _LIBCPP_DEPRECATED_IN_CXX17 iterator {
typedef _Category iterator_category;
};
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#ifdef _LIBCPP_ABI_NO_ITERATOR_BASES
template <class _Derived>
struct __no_iterator_base {};
template <class _Derived, class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
using __iterator_base _LIBCPP_NODEBUG = __no_iterator_base<_Derived>;
#else
template <class _Derived, class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
using __iterator_base _LIBCPP_NODEBUG = iterator<_Category, _Tp, _Distance, _Pointer, _Reference>;
#endif
_LIBCPP_SUPPRESS_DEPRECATED_POP
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_ITERATOR_H

View file

@ -24,15 +24,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
class ostream_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<ostream_iterator<_Tp, _CharT, _Traits>, output_iterator_tag, void, void, void, void> {
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;

View file

@ -25,15 +25,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _CharT, class _Traits>
class ostreambuf_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<ostreambuf_iterator<_CharT, _Traits>, output_iterator_tag, void, void, void, void> {
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;

View file

@ -46,21 +46,16 @@
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Iter>
class reverse_iterator
#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<typename iterator_traits<_Iter>::iterator_category,
typename iterator_traits<_Iter>::value_type,
typename iterator_traits<_Iter>::difference_type,
typename iterator_traits<_Iter>::pointer,
typename iterator_traits<_Iter>::reference>
#endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<reverse_iterator<_Iter>,
typename iterator_traits<_Iter>::iterator_category,
typename iterator_traits<_Iter>::value_type,
typename iterator_traits<_Iter>::difference_type,
typename iterator_traits<_Iter>::pointer,
typename iterator_traits<_Iter>::reference> {
private:
#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
#ifndef _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
_Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break
#endif
@ -91,7 +86,7 @@ public:
using reference = typename iterator_traits<_Iter>::reference;
#endif
#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
#ifndef _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : __t_(), current() {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {}

View file

@ -28,15 +28,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR)
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _OutputIterator, class _Tp>
class _LIBCPP_DEPRECATED_IN_CXX17 raw_storage_iterator
# if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<output_iterator_tag, void, void, void, void>
# endif
{
_LIBCPP_SUPPRESS_DEPRECATED_POP
: public __iterator_base<raw_storage_iterator<_OutputIterator, _Tp>, output_iterator_tag, void, void, void, void> {
private:
_OutputIterator __x_;