Hi
libstdc++: [_GLIBCXX_DEBUG] Make constant evaluation compatible
In a constant evaluation context the _GLIBCXX_DEBUG is working in a
degradated mode where only iterators are keeping a link to their
container,
the container won't have a list of its iterators.
In std::__debug::vector and std::__debug::inplace_vector remove all
calls to
std::is_constant_evaluated and code associated to it when returning
true. The
same code is now used in both contexts.
Issues will be reported thanks to an invalid call to a not-constexpr
__gnu_debug::__glibcxx_fail() function.
libstdc++-v3/ChangeLog:
* include/debug/forward_list (_Sequence_traits<>::_S_size):
Declare as C++20
constexpr.
* include/debug/functions.h
(__check_valid_range<_Ite>): Remove
std::__is_constant_evaluated check.
(__foreign_iterator): Declare as C++20 constexpr and add
std::__is_constant_evaluated
check.
* include/debug/helper_functions.h (__check_singular_aux):
Declare as C++22 constexpr.
(__check_singular<_Ite>(_Ite const&)): Remove
std::__is_constant_evaluated check.
* include/debug/inplace_vector: Remove all calls to
std::is_contant_evaluated().
* include/debug/list (_Sequence_traits<>::_S_size): Declare
as C++20 constexpr.
* include/debug/macros.h (__gnu_debug::__glibcxx_fail): New.
(_GLIBCXX_DEBUG_VERIFY_AT_F): Add
std::__is_constant_evaluated section.
* include/debug/safe_base.h
(_Safe_iterator_base::_M_attach_to): New.
(_Safe_iterator_base::_M_detach_sequence): New.
(_Safe_iterator_base(const _Safe_sequence_base*, bool): Remove
__is_constant_evaluated check and call _M_attach_to.
(_Safe_iterator_base(const _Safe_iterator_base&, bool)):
Likewise.
(~_Safe_iterator_base()): Remove __is_constant_evaluated
check and call
_M_detach_sequence.
(_Safe_iterator_base::_M_is_singular): New.
(_Safe_iterator_base::_M_is_comparable): New.
(__check_singular_aux(const _Safe_iterator_base*)): Declare
as C++20 constexpr
and call _M_is_singular.
* include/debug/safe_container.h
(_Safe_container::_M_swap_base): Declare as
C++20 constexpr and skip operation if in constant
evaluation context.
(_Safe_container(_Safe_container&&, const _Alloc&,
std::false_type)): Remove
__is_constant_evaluated check.
(_Safe_container::operator=(_Safe_container<>&&)): Likewise.
* include/debug/safe_iterator.h
(_GLIBCXX_DEBUG_VERIFY_OPERANDS): Likewise.
(_BeforeBeginHelper<>::_S_Is): Declare as C++20 constexpr.
(_BeforeBeginHelper<>::_S_Is_Beginnest): Declare as C++20
constexpr.
(_Sequence_traits<>::_S_size): Declare as C++20 constexpr.
(_Safe_iterator::_Iter_base, _Safe_iterator::_Safe_base):
Remove.
(_Safe_iterator(const _Safe_iterator&, _Unchecked)): Remove
__is_constant_evaluated
check.
(_Safe_iterator(const _Safe_iterator&)): Likewise.
(_Safe_iterator(_Safe_iterator&&)): Likewise.
(_Safe_iterator<>::operator=(const _Safe_iterator&)): Adapt
use of __is_constant_evaluated
to avoid __scoped_lock instantiation.
(_Safe_iterator<>::operator=(_Safe_iterator&&)): Likewise.
(_Safe_iterator<>::operator++()): Likewise.
(_Safe_iterator<>::operator*()): Remove
__is_constant_evaluated check.
(_Safe_iterator<>::operator->()): Likewise.
(_Safe_iterator<>::operator++(int)): Likewise.
(_Safe_iterator<>::_M_singular()): New, C++20 constexpr.
(_Safe_iterator<>::_M_can_compare(const
_Safe_iterator_base&)): New, C++20 constexpr.
(_Safe_iterator<>::_M_attach()): Declare as C++20
constexpr, use base class
_M_attach_sequence().
(_Safe_iterator<>::_M_detach()): New, C++20 constexpr, use
base class
_M_detach_sequence().
(_Safe_iterator<>::_M_dereferenceable()): Declare as C++20
constexpr.
(_Safe_iterator<>::_M_before_dereferenceable()): Likewise.
(_Safe_iterator<>::_M_incrementable()): Likewise.
(_Safe_iterator<>::_M_value_initialized()): Likewise.
(_Safe_iterator<>::_M_can_advance()): Likewise.
(_Safe_iterator<>::_M_valid_range): Likewise.
(_Safe_iterator<>::_M_get_sequence()): Likewise.
(_Safe_iterator<>::_M_get_distance_from_begin()): Likewise.
(_Safe_iterator<>::_M_get_distance_to_end()): Likewise.
(_Safe_iterator<>::_M_is_end()): Likewise.
(_Safe_iterator<>::_M_is_before_begin()): Likewise.
(_Safe_iterator<>::_M_is_beginnest()): Likewise.
(_Safe_iterator<>::operator--()): Adapt use of
__is_constant_evaluated to avoid
__scoped_lock instantiation.
(_Safe_iterator<>::operator+=(difference_type)): Likewise.
(_Safe_iterator<>::operator-=(difference_type)): Likewise.
(_Safe_iterator<>::operator--(int)): Declare as C++20
constexpr.
(_Safe_iterator<>::_M_decrementable()): Likewise.
(_Safe_iterator<>::operator[](difference_type)): Likewise.
(operator<(const _Safe_iterator<>&, const
_Safe_iterator<>&)): Likewise.
(operator<=(const _Safe_iterator<>&, const
_Safe_iterator<>&)): Likewise.
(operator>(const _Safe_iterator<>&, const
_Safe_iterator<>&)): Likewise.
(operator>=(const _Safe_iterator<>&, const
_Safe_iterator<>&)): Likewise.
(operator+(const _Safe_iterator<>&, difference_type)):
Likewise.
(operator+(difference_type, const _Safe_iterator<>&)):
Likewise.
(operator-(const _Safe_iterator<>&, difference_type)):
Likewise.
(operator-(difference_type, const _Safe_iterator<>&)):
Likewise.
(__valid_range<>): Likewise.
(__can_advance<>): Likewise.
* include/debug/safe_iterator.tcc: Adapt method with C++20
constexpr declaration.
* include/debug/safe_local_iterator.h
(_Safe_local_iterator<>::_Iter_base,
_Safe_local_iterator<>::_Safe_base):
Remove.
(_Safe_local_iterator<>::_M_singular): New.
(_Safe_local_iterator<>::_M_can_compare(const
_Safe_iterator_base&)): New.
(_Safe_local_iterator<>::_M_attach): Declare C++20
constexpr, use base class
_M_attach_to.
* include/debug/safe_sequence.h
(_Safe_sequence<>::_M_invalidate_if_impl): New.
(_Safe_sequence<>::_M_invalidate_if): Call later if not
__is_constant_evaluated.
* include/debug/safe_sequence.tcc: Rename _M_invalidate_if into
_M_invalidate_if_impl and not C++20 constexpr.
* include/debug/safe_unordered_base.h: Remove useless this->.
* include/debug/vector: Adapt, remove all use of
std::__is_constant_evaluated.
* src/c++11/debug.cc
(_Safe_sequence_base::_M_detach_singular()): Use new
_M_is_singular.
(_Safe_sequence_base::_M_detach_single(_Safe_iterator_base* it)):
Do not check if it equals _M_iterators if it was equal to
_M_const_iterators.
(_Safe_iterator_base::_M_singular): Use _M_is_singular.
(_Safe_iterator_base::_M_singular)[_GLIBCXX_INLINE_VERSION]: Remove.
(_Safe_iterator_base::_M_can_compare): Use _M_is_comparable.
(_Safe_iterator_base::_M_can_compare)[_GLIBCXX_INLINE_VERSION]: Remove.
(_Safe_unordered_container_base::_M_detach_local_single(_Safe_iterator_base*)):
Do not check if it equals _M_local_iterators if it was equal to
_M_const_local_iterators.
PR: https://forge.sourceware.org/gcc/gcc-TEST/pulls/136
I noticed on the PR that some bot is running tests and spotted some
regressions that are now fixed.
I run some tests locally and requested an access to the compiler farm.
François
diff --git a/libstdc++-v3/include/debug/forward_list
b/libstdc++-v3/include/debug/forward_list
index 7d615978000..9a53de8afe2 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -1030,7 +1030,7 @@ namespace __gnu_debug
{
typedef typename std::__debug::forward_list<_Tp, _Alloc>::iterator _It;
- static typename _Distance_traits<_It>::__type
+ static _GLIBCXX20_CONSTEXPR typename _Distance_traits<_It>::__type
_S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq)
{
return __seq.empty()
diff --git a/libstdc++-v3/include/debug/functions.h
b/libstdc++-v3/include/debug/functions.h
index 99a0c41758d..9626d344cbc 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -60,12 +60,8 @@ namespace __gnu_debug
unsigned int __line,
const char* __function)
{
- if (!std::__is_constant_evaluated())
- {
- __glibcxx_check_valid_range_at(__first, __last,
- __file, __line, __function);
- }
-
+ __glibcxx_check_valid_range_at(__first, __last,
+ __file, __line, __function);
return __first;
}
@@ -193,11 +189,14 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence, typename _Category,
typename _InputIterator>
- inline bool
+ inline _GLIBCXX20_CONSTEXPR bool
__foreign_iterator(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
_InputIterator __other, _InputIterator __other_end)
{
+ if (std::__is_constant_evaluated())
+ return true;
+
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
}
diff --git a/libstdc++-v3/include/debug/helper_functions.h
b/libstdc++-v3/include/debug/helper_functions.h
index 8ef21684650..d693db16b95 100644
--- a/libstdc++-v3/include/debug/helper_functions.h
+++ b/libstdc++-v3/include/debug/helper_functions.h
@@ -116,11 +116,11 @@ namespace __gnu_debug
}
// An arbitrary iterator pointer is not singular.
- inline bool
+ inline _GLIBCXX20_CONSTEXPR bool
__check_singular_aux(const void*) { return false; }
// Defined in <debug/safe_base.h>
- bool
+ _GLIBCXX20_CONSTEXPR bool
__check_singular_aux(const class _Safe_iterator_base*);
// We may have an iterator that derives from _Safe_iterator_base but isn't
@@ -129,10 +129,7 @@ namespace __gnu_debug
_GLIBCXX_CONSTEXPR
inline bool
__check_singular(_Iterator const& __x)
- {
- return ! std::__is_constant_evaluated()
- && __gnu_debug::__check_singular_aux(std::__addressof(__x));
- }
+ { return __gnu_debug::__check_singular_aux(std::__addressof(__x)); }
/** Non-NULL pointers are nonsingular. */
template<typename _Tp>
diff --git a/libstdc++-v3/include/debug/inplace_vector
b/libstdc++-v3/include/debug/inplace_vector
index 750b0a7343c..1b01e0b0541 100644
--- a/libstdc++-v3/include/debug/inplace_vector
+++ b/libstdc++-v3/include/debug/inplace_vector
@@ -412,11 +412,6 @@ namespace __debug
constexpr iterator
emplace(const_iterator __position, _Args&&... __args)
{
- if (std::is_constant_evaluated())
- return iterator(_Base::emplace(__position.base(),
- std::forward<_Args>(__args)...),
- this);
-
__glibcxx_check_insert(__position);
const difference_type __offset = __position.base() - _Base::cbegin();
_Base_iterator __res = _Base::emplace(__position.base(),
@@ -436,10 +431,7 @@ namespace __debug
constexpr iterator
insert(const_iterator __position, size_type __n, const _Tp& __x)
{
- if (std::is_constant_evaluated())
- return iterator(_Base::insert(__position.base(), __n, __x), this);
-
- __glibcxx_check_insert(__position);
+ __glibcxx_check_insert(__position);
const difference_type __offset = __position.base() - _Base::cbegin();
_Base_iterator __res = _Base::insert(__position.base(), __n, __x);
_M_invalidate_after_nth(__offset);
@@ -451,11 +443,6 @@ namespace __debug
insert(const_iterator __position, _InputIterator __first,
_InputIterator __last)
{
- if (std::is_constant_evaluated())
- return iterator(_Base::insert(__position.base(),
- __gnu_debug::__unsafe(__first),
- __gnu_debug::__unsafe(__last)), this);
-
typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
__glibcxx_check_insert_range(__position, __first, __last, __dist);
@@ -469,7 +456,7 @@ namespace __debug
__res = _Base::insert(__position.base(), __first, __last);
_M_invalidate_after_nth(__offset);
- return { __res, this };
+ return iterator(__res, this);
}
template<__detail::__container_compatible_range<_Tp> _Rg>
@@ -488,9 +475,6 @@ namespace __debug
constexpr iterator
insert(const_iterator __position, initializer_list<_Tp> __il)
{
- if (std::is_constant_evaluated())
- return iterator(_Base::insert(__position.base(), __il), this);
-
__glibcxx_check_insert(__position);
const auto __size = size();
difference_type __offset = __position.base() - _Base::begin();
@@ -503,9 +487,6 @@ namespace __debug
constexpr iterator
erase(const_iterator __position)
{
- if (std::is_constant_evaluated())
- return iterator(_Base::erase(__position.base()), this);
-
__glibcxx_check_erase(__position);
difference_type __offset = __position.base() - _Base::cbegin();
_Base_iterator __res = _Base::erase(__position.base());
@@ -516,10 +497,6 @@ namespace __debug
constexpr iterator
erase(const_iterator __first, const_iterator __last)
{
- if (std::is_constant_evaluated())
- return iterator(_Base::erase(__first.base(), __last.base()),
- this);
-
__glibcxx_check_erase_range(__first, __last);
if (__first.base() != __last.base())
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index d06e9e4c2f8..368128cc5a8 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -1063,7 +1063,7 @@ namespace __gnu_debug
{
typedef typename std::__debug::list<_Tp, _Alloc>::iterator _It;
- static typename _Distance_traits<_It>::__type
+ static _GLIBCXX20_CONSTEXPR typename _Distance_traits<_It>::__type
_S_size(const std::__debug::list<_Tp, _Alloc>& __seq)
{
return __seq.empty()
diff --git a/libstdc++-v3/include/debug/macros.h
b/libstdc++-v3/include/debug/macros.h
index 84ad6d3fe9b..5d0961dfae4 100644
--- a/libstdc++-v3/include/debug/macros.h
+++ b/libstdc++-v3/include/debug/macros.h
@@ -38,10 +38,22 @@
* the user error and where the error is reported.
*
*/
+namespace __gnu_debug
+{
+ __attribute__((__always_inline__, __visibility__("default")))
+ inline void
+ __glibcxx_fail()
+ { }
+}
#define _GLIBCXX_DEBUG_VERIFY_AT_F(_Cond,_ErrMsg,_File,_Line,_Func) \
do { \
- if (__builtin_expect(!bool(_Cond), false)) \
+ if (std::__is_constant_evaluated())
\
+ {
\
+ if (!bool(_Cond)) \
+ __gnu_debug::__glibcxx_fail(); \
+ }
\
+ else if (__builtin_expect(!bool(_Cond), false)) \
__gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)
\
._ErrMsg._M_error(); \
} while (false)
diff --git a/libstdc++-v3/include/debug/safe_base.h
b/libstdc++-v3/include/debug/safe_base.h
index 25ac7a4e836..e7fd41cbb0c 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -83,37 +83,27 @@ namespace __gnu_debug
{ }
/** Initialize the iterator to reference the sequence pointed to
- * by @p __seq. @p __constant is true when we are initializing a
- * constant iterator, and false if it is a mutable iterator. Note
- * that @p __seq may be NULL, in which case the iterator will be
- * singular. Otherwise, the iterator will reference @p __seq and
- * be nonsingular.
- */
+ * by @p __seq. @p __constant is true when we are initializing a
+ * constant iterator, and false if it is a mutable iterator. Note
+ * that @p __seq may be NULL, in which case the iterator will be
+ * singular. Otherwise, the iterator will reference @p __seq and
+ * be nonsingular. */
_GLIBCXX20_CONSTEXPR
_Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant)
: _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
- {
- if (!std::__is_constant_evaluated())
- this->_M_attach(__seq, __constant);
- }
+ { _M_attach_to(__seq, __constant); }
/** Initializes the iterator to reference the same sequence that
- @p __x does. @p __constant is true if this is a constant
- iterator, and false if it is mutable. */
+ * @p __x does. @p __constant is true if this is a constant
+ * iterator, and false if it is mutable. */
_GLIBCXX20_CONSTEXPR
_Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant)
: _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
- {
- if (!std::__is_constant_evaluated())
- this->_M_attach(__x._M_sequence, __constant);
- }
+ { _M_attach_to(__x._M_sequence, __constant); }
_GLIBCXX20_CONSTEXPR
~_Safe_iterator_base()
- {
- if (!std::__is_constant_evaluated())
- this->_M_detach();
- }
+ { _M_detach_sequence(); }
/** For use in _Safe_iterator. */
__gnu_cxx::__mutex&
@@ -122,10 +112,9 @@ namespace __gnu_debug
/** Attaches this iterator to the given sequence, detaching it
* from whatever sequence it was attached to originally. If the
* new sequence is the NULL pointer, the iterator is left
- * unattached.
- */
- void
- _M_attach(const _Safe_sequence_base* __seq, bool __constant);
+ * unattached. */
+ _GLIBCXX20_CONSTEXPR void
+ _M_attach_to(const _Safe_sequence_base* __seq, bool __constant);
/** Likewise, but not thread-safe. */
void
@@ -133,22 +122,40 @@ namespace __gnu_debug
bool __constant) _GLIBCXX_USE_NOEXCEPT;
/** Detach the iterator for whatever sequence it is attached to,
- * if any.
- */
+ * if any. */
+ _GLIBCXX20_CONSTEXPR void
+ _M_detach_sequence()
+ {
+ if (std::__is_constant_evaluated())
+ _M_sequence = 0;
+ else
+ _M_detach();
+ }
+
+ private:
+ void
+ _M_attach(const _Safe_sequence_base* __seq, bool __constant);
+
void
_M_detach();
#if !_GLIBCXX_INLINE_VERSION
- private:
- /***************************************************************/
/** Not-const method preserved for abi backward compatibility. */
void
_M_attach(_Safe_sequence_base* __seq, bool __constant);
+ /** Not-const method preserved for abi backward compatibility. */
void
_M_attach_single(_Safe_sequence_base* __seq,
bool __constant) _GLIBCXX_USE_NOEXCEPT;
- /***************************************************************/
+
+ /* Not-constexpr method preserved for abi backward compatibility. */
+ _GLIBCXX_PURE bool
+ _M_singular() const _GLIBCXX_NOEXCEPT;
+
+ /* Not-constexpr method preserved for abi backward compatibility. */
+ _GLIBCXX_PURE bool
+ _M_can_compare(const _Safe_iterator_base& __x) const _GLIBCXX_USE_NOEXCEPT;
#endif
public:
@@ -157,22 +164,23 @@ namespace __gnu_debug
_M_detach_single() _GLIBCXX_USE_NOEXCEPT;
/** Determines if we are attached to the given sequence. */
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_attached_to(const _Safe_sequence_base* __seq) const
{ return _M_sequence == __seq; }
/** Is this iterator singular? */
- _GLIBCXX_PURE bool
- _M_singular() const _GLIBCXX_USE_NOEXCEPT;
+ _GLIBCXX20_CONSTEXPR bool
+ _M_is_singular() const _GLIBCXX_USE_NOEXCEPT;
/** Can we compare this iterator to the given iterator @p __x?
- Returns true if both iterators are nonsingular and reference
- the same sequence. */
- _GLIBCXX_PURE bool
- _M_can_compare(const _Safe_iterator_base& __x) const _GLIBCXX_USE_NOEXCEPT;
+ * Returns true if both iterators are nonsingular and reference
+ * the same sequence. */
+ _GLIBCXX20_CONSTEXPR bool
+ _M_is_comparable(const _Safe_iterator_base& __x) const
_GLIBCXX_USE_NOEXCEPT
+ { return _M_sequence == __x._M_sequence; }
/** Invalidate the iterator, making it singular. */
- void
+ _GLIBCXX20_CONSTEXPR void
_M_invalidate()
{ _M_version = 0; }
@@ -194,9 +202,9 @@ namespace __gnu_debug
/** Iterators that derive from _Safe_iterator_base can be determined singular
* or non-singular.
**/
- inline bool
+ inline _GLIBCXX20_CONSTEXPR bool
__check_singular_aux(const _Safe_iterator_base* __x)
- { return __x->_M_singular(); }
+ { return __x->_M_is_singular(); }
/**
* @brief Base class that supports tracking of iterators that
@@ -352,6 +360,25 @@ namespace __gnu_debug
void
_M_detach_single(_Safe_iterator_base* __it) const _GLIBCXX_USE_NOEXCEPT;
};
+
+ inline _GLIBCXX20_CONSTEXPR void
+ _Safe_iterator_base::_M_attach_to(const _Safe_sequence_base* __seq,
+ bool __constant)
+ {
+ if (std::__is_constant_evaluated())
+ {
+ _M_sequence = __seq;
+ _M_version = _M_sequence->_M_version;
+ }
+ else
+ _M_attach(__seq, __constant);
+ }
+
+ inline _GLIBCXX20_CONSTEXPR bool
+ _Safe_iterator_base::
+ _M_is_singular() const _GLIBCXX_USE_NOEXCEPT
+ { return !_M_sequence || _M_version != _M_sequence->_M_version; }
+
} // namespace __gnu_debug
#endif
diff --git a/libstdc++-v3/include/debug/safe_container.h
b/libstdc++-v3/include/debug/safe_container.h
index 32159ba2176..4353f457691 100644
--- a/libstdc++-v3/include/debug/safe_container.h
+++ b/libstdc++-v3/include/debug/safe_container.h
@@ -58,7 +58,10 @@ namespace __gnu_debug
_GLIBCXX20_CONSTEXPR
void
_M_swap_base(const _Safe_container& __x) const noexcept
- { _Base::_M_swap(__x); }
+ {
+ if (!std::__is_constant_evaluated())
+ _Base::_M_swap(__x);
+ }
_GLIBCXX20_CONSTEXPR
_Safe_container(_Safe_container&& __x, const _Alloc&, std::true_type)
@@ -69,13 +72,10 @@ namespace __gnu_debug
_Safe_container(_Safe_container&& __x, const _Alloc& __a,
std::false_type)
: _Safe_container()
{
- if (!std::__is_constant_evaluated())
- {
- if (__x._M_cont().get_allocator() == __a)
- _M_swap_base(__x);
- else
- __x._M_invalidate_all();
- }
+ if (__x._M_cont().get_allocator() == __a)
+ _M_swap_base(__x);
+ else
+ __x._M_invalidate_all();
}
protected:
@@ -106,9 +106,6 @@ namespace __gnu_debug
_Safe_container&
operator=(_Safe_container&& __x) noexcept
{
- if (std::__is_constant_evaluated())
- return *this;
-
if (std::__addressof(__x) == this)
{
// Standard containers have a valid but unspecified value after
diff --git a/libstdc++-v3/include/debug/safe_iterator.h
b/libstdc++-v3/include/debug/safe_iterator.h
index 4da3d2bb3d4..56baf6103f2 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -40,7 +40,6 @@
#endif
#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \
- if (!std::__is_constant_evaluated()) { \
_GLIBCXX_DEBUG_VERIFY((!_Lhs._M_singular() && !_Rhs._M_singular()) \
|| (_Lhs._M_value_initialized() \
&& _Rhs._M_value_initialized()), \
@@ -50,8 +49,7 @@
_GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
_M_message(_DiffMsgId) \
._M_iterator(_Lhs, #_Lhs) \
- ._M_iterator(_Rhs, #_Rhs)); \
- }
+ ._M_iterator(_Rhs, #_Rhs));
#define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \
_GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \
@@ -88,12 +86,12 @@ namespace __gnu_debug
struct _BeforeBeginHelper
{
template<typename _Iterator, typename _Category>
- static bool
+ static _GLIBCXX20_CONSTEXPR bool
_S_Is(const _Safe_iterator<_Iterator, _Sequence, _Category>&)
{ return false; }
template<typename _Iterator, typename _Category>
- static bool
+ static _GLIBCXX20_CONSTEXPR bool
_S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence, _Category>&
__it)
{ return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
};
@@ -104,7 +102,7 @@ namespace __gnu_debug
{
typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
- static typename _DistTraits::__type
+ static _GLIBCXX20_CONSTEXPR typename _DistTraits::__type
_S_size(const _Sequence& __seq)
{ return std::make_pair(__seq.size(), __dp_exact); }
};
@@ -131,9 +129,6 @@ namespace __gnu_debug
: private _Iterator,
public _Safe_iterator_base
{
- typedef _Iterator _Iter_base;
- typedef _Safe_iterator_base _Safe_base;
-
typedef std::iterator_traits<_Iterator> _Traits;
protected:
@@ -149,11 +144,8 @@ namespace __gnu_debug
_GLIBCXX20_CONSTEXPR
_Safe_iterator(const _Safe_iterator& __x, _Unchecked) _GLIBCXX_NOEXCEPT
- : _Iter_base(__x.base()), _Safe_base()
- {
- if (!std::__is_constant_evaluated())
- _M_attach(__x._M_sequence);
- }
+ : _Iterator(__x.base()), _Safe_iterator_base()
+ { _M_attach(__x._M_sequence); }
public:
typedef _Iterator iterator_type;
@@ -169,7 +161,7 @@ namespace __gnu_debug
/// @post the iterator is singular and unattached
_GLIBCXX20_CONSTEXPR
- _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { }
+ _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iterator() { }
/**
* @brief Safe iterator construction from an unsafe iterator and
@@ -181,7 +173,7 @@ namespace __gnu_debug
_GLIBCXX20_CONSTEXPR
_Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
_GLIBCXX_NOEXCEPT
- : _Iter_base(__i), _Safe_base(__seq, _S_constant())
+ : _Iterator(__i), _Safe_iterator_base(__seq, _S_constant())
{ }
/**
@@ -189,11 +181,8 @@ namespace __gnu_debug
*/
_GLIBCXX20_CONSTEXPR
_Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
- : _Iter_base(__x.base()), _Safe_base()
+ : _Iterator(__x.base()), _Safe_iterator_base()
{
- if (std::__is_constant_evaluated())
- return;
-
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
@@ -211,14 +200,8 @@ namespace __gnu_debug
*/
_GLIBCXX20_CONSTEXPR
_Safe_iterator(_Safe_iterator&& __x) noexcept
- : _Iter_base()
+ : _Iterator()
{
- if (std::__is_constant_evaluated())
- {
- base() = __x.base();
- return;
- }
-
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x._M_value_initialized(),
_M_message(__msg_init_copy_singular)
@@ -243,11 +226,8 @@ namespace __gnu_debug
std::__are_same<_MutableIterator, _OtherIterator>::__value,
_Category>::__type>& __x)
_GLIBCXX_NOEXCEPT
- : _Iter_base(__x.base())
+ : _Iterator(__x.base())
{
- if (std::__is_constant_evaluated())
- return;
-
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
@@ -265,12 +245,6 @@ namespace __gnu_debug
_Safe_iterator&
operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
{
- if (std::__is_constant_evaluated())
- {
- base() = __x.base();
- return *this;
- }
-
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
@@ -279,7 +253,8 @@ namespace __gnu_debug
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
- if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
+ if (!std::__is_constant_evaluated()
+ && this->_M_sequence && this->_M_sequence == __x._M_sequence)
_GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
base() = __x.base();
@@ -304,12 +279,6 @@ namespace __gnu_debug
_Safe_iterator&
operator=(_Safe_iterator&& __x) noexcept
{
- if (std::__is_constant_evaluated())
- {
- base() = __x.base();
- return *this;
- }
-
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x._M_value_initialized(),
_M_message(__msg_copy_singular)
@@ -319,7 +288,8 @@ namespace __gnu_debug
if (std::__addressof(__x) == this)
return *this;
- if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
+ if (!std::__is_constant_evaluated()
+ && this->_M_sequence && this->_M_sequence == __x._M_sequence)
_GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
base() = __x.base();
@@ -347,12 +317,9 @@ namespace __gnu_debug
reference
operator*() const _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
- _M_message(__msg_bad_deref)
- ._M_iterator(*this, "this"));
- }
+ _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+ _M_message(__msg_bad_deref)
+ ._M_iterator(*this, "this"));
return *base();
}
@@ -365,12 +332,9 @@ namespace __gnu_debug
pointer
operator->() const _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
- _M_message(__msg_bad_deref)
- ._M_iterator(*this, "this"));
- }
+ _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+ _M_message(__msg_bad_deref)
+ ._M_iterator(*this, "this"));
return base().operator->();
}
@@ -383,19 +347,18 @@ namespace __gnu_debug
_Safe_iterator&
operator++() _GLIBCXX_NOEXCEPT
{
- if (std::__is_constant_evaluated())
- {
- ++base();
- return *this;
- }
-
- _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+ _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
_M_message(__msg_bad_inc)
._M_iterator(*this, "this"));
- _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ if (std::__is_constant_evaluated())
++base();
- } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ else
+ {
+ _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ ++base();
+ } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ }
return *this;
}
@@ -407,12 +370,9 @@ namespace __gnu_debug
_Safe_iterator
operator++(int) _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
- _M_message(__msg_bad_inc)
- ._M_iterator(*this, "this"));
- }
+ _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
+ _M_message(__msg_bad_inc)
+ ._M_iterator(*this, "this"));
_Safe_iterator __ret(*this, _Unchecked());
++*this;
return __ret;
@@ -443,26 +403,40 @@ namespace __gnu_debug
_GLIBCXX20_CONSTEXPR
operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; }
+ /** Is this iterator singular? */
+ _GLIBCXX20_CONSTEXPR bool
+ _M_singular() const _GLIBCXX_USE_NOEXCEPT
+ { return this->_M_is_singular(); }
+
+ _GLIBCXX20_CONSTEXPR bool
+ _M_can_compare(const _Safe_iterator_base& __x) const
_GLIBCXX_USE_NOEXCEPT
+ { return this->_M_is_comparable(__x); }
+
/** Attach iterator to the given sequence. */
- void
+ _GLIBCXX20_CONSTEXPR void
_M_attach(const _Safe_sequence_base* __seq)
- { _Safe_base::_M_attach(__seq, _S_constant()); }
+ { this->_M_attach_to(__seq, _S_constant()); }
/** Likewise, but not thread-safe. */
void
_M_attach_single(const _Safe_sequence_base* __seq)
- { _Safe_base::_M_attach_single(__seq, _S_constant()); }
+ { this->_M_attach_single(__seq, _S_constant()); }
+
+ /** Detach iterator from the sequence. */
+ _GLIBCXX20_CONSTEXPR void
+ _M_detach()
+ { this->_M_detach_sequence(); }
/// Is the iterator dereferenceable?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_dereferenceable() const
- { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
+ { return !_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
/// Is the iterator before a dereferenceable one?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_before_dereferenceable() const
{
- if (this->_M_incrementable())
+ if (_M_incrementable())
{
_Iterator __base = base();
return ++__base != _M_get_sequence()->_M_base().end();
@@ -471,17 +445,17 @@ namespace __gnu_debug
}
/// Is the iterator incrementable?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_incrementable() const
- { return !this->_M_singular() && !_M_is_end(); }
+ { return !_M_singular() && !_M_is_end(); }
/// Is the iterator value-initialized?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_value_initialized() const
- { return _M_version == 0 && base() == _Iter_base(); }
+ { return _M_version == 0 && base() == _Iterator(); }
// Can we advance the iterator @p __n steps (@p __n may be negative)
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_can_advance(difference_type __n, bool __strict = false) const;
// Can we advance the iterator using @p __dist in @p __way direction.
@@ -491,13 +465,13 @@ namespace __gnu_debug
int __way) const;
// Is the iterator range [*this, __rhs) valid?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_valid_range(const _Safe_iterator& __rhs,
std::pair<difference_type, _Distance_precision>& __dist,
bool __check_dereferenceable = true) const;
// The sequence this iterator references.
- typename __gnu_cxx::__conditional_type<
+ _GLIBCXX20_CONSTEXPR typename __gnu_cxx::__conditional_type<
_IsConstant::__value, const _Sequence*, _Sequence*>::__type
_M_get_sequence() const
{
@@ -513,11 +487,11 @@ namespace __gnu_debug
_M_get_distance_to(const _Safe_iterator& __rhs) const;
// Get distance from sequence begin up to *this.
- typename _Distance_traits<_Iterator>::__type
+ _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
_M_get_distance_from_begin() const;
// Get distance from *this to sequence end.
- typename _Distance_traits<_Iterator>::__type
+ _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
_M_get_distance_to_end() const;
/// Is this iterator equal to the sequence's begin() iterator?
@@ -527,19 +501,19 @@ namespace __gnu_debug
{ return base() == _M_get_sequence()->_M_base().begin(); }
/// Is this iterator equal to the sequence's end() iterator?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_is_end() const
{ return base() == _M_get_sequence()->_M_base().end(); }
/// Is this iterator equal to the sequence's before_begin() iterator if
/// any?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_is_before_begin() const
{ return _BeforeBeginHelper<_Sequence>::_S_Is(*this); }
/// Is this iterator equal to the sequence's before_begin() iterator if
/// any or begin() otherwise?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_is_beginnest() const
{ return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
@@ -690,6 +664,7 @@ namespace __gnu_debug
* @brief Iterator postincrement
* @pre iterator is incrementable
*/
+ _GLIBCXX20_CONSTEXPR
_Safe_iterator
operator++(int) _GLIBCXX_NOEXCEPT
{
@@ -710,19 +685,20 @@ namespace __gnu_debug
_Safe_iterator&
operator--() _GLIBCXX_NOEXCEPT
{
- if (std::__is_constant_evaluated())
- {
- --this->base();
- return *this;
- }
-
_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
_M_message(__msg_bad_dec)
._M_iterator(*this, "this"));
- _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+
+ if (std::__is_constant_evaluated())
--this->base();
- } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ else
+ {
+ _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ --this->base();
+ } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ }
+
return *this;
}
@@ -730,6 +706,7 @@ namespace __gnu_debug
* @brief Iterator postdecrement
* @pre iterator is decrementable
*/
+ _GLIBCXX20_CONSTEXPR
_Safe_iterator
operator--(int) _GLIBCXX_NOEXCEPT
{
@@ -744,7 +721,7 @@ namespace __gnu_debug
// ------ Utilities ------
// Is the iterator decrementable?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_decrementable() const
{ return !this->_M_singular() && !this->_M_is_begin(); }
};
@@ -838,7 +815,7 @@ namespace __gnu_debug
#endif
// Is the iterator range [*this, __rhs) valid?
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_valid_range(const _Safe_iterator& __rhs,
std::pair<difference_type,
_Distance_precision>& __dist) const;
@@ -864,12 +841,9 @@ namespace __gnu_debug
_Safe_iterator
operator++(int) _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
- _M_message(__msg_bad_inc)
- ._M_iterator(*this, "this"));
- }
+ _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+ _M_message(__msg_bad_inc)
+ ._M_iterator(*this, "this"));
_Safe_iterator __ret(*this, _Unchecked());
++*this;
return __ret;
@@ -896,12 +870,9 @@ namespace __gnu_debug
_Safe_iterator
operator--(int) _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
- _M_message(__msg_bad_dec)
- ._M_iterator(*this, "this"));
- }
+ _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
+ _M_message(__msg_bad_dec)
+ ._M_iterator(*this, "this"));
_Safe_iterator __ret(*this, _Unchecked());
--*this;
return __ret;
@@ -913,13 +884,10 @@ namespace __gnu_debug
reference
operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
- && this->_M_can_advance(__n + 1),
- _M_message(__msg_iter_subscript_oob)
- ._M_iterator(*this)._M_integer(__n));
- }
+ _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
+ && this->_M_can_advance(__n + 1),
+ _M_message(__msg_iter_subscript_oob)
+ ._M_iterator(*this)._M_integer(__n));
return this->base()[__n];
}
@@ -927,19 +895,18 @@ namespace __gnu_debug
_Safe_iterator&
operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
{
- if (std::__is_constant_evaluated())
- {
- this->base() += __n;
- return *this;
- }
-
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
_M_message(__msg_advance_oob)
._M_iterator(*this)._M_integer(__n));
- _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ if (std::__is_constant_evaluated())
this->base() += __n;
- } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ else
+ {
+ _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ this->base() += __n;
+ } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ }
return *this;
}
@@ -947,19 +914,18 @@ namespace __gnu_debug
_Safe_iterator&
operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
{
- if (std::__is_constant_evaluated())
- {
- this->base() -= __n;
- return *this;
- }
-
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
_M_message(__msg_retreat_oob)
._M_iterator(*this)._M_integer(__n));
- _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ if (std::__is_constant_evaluated())
this->base() -= __n;
- } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ else
+ {
+ _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ this->base() -= __n;
+ } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+ }
return *this;
}
@@ -983,6 +949,7 @@ namespace __gnu_debug
}
#else
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator<(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -991,6 +958,7 @@ namespace __gnu_debug
}
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator<(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -999,6 +967,7 @@ namespace __gnu_debug
}
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator<=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -1007,6 +976,7 @@ namespace __gnu_debug
}
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator<=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -1015,6 +985,7 @@ namespace __gnu_debug
}
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator>(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -1023,6 +994,7 @@ namespace __gnu_debug
}
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator>(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -1031,6 +1003,7 @@ namespace __gnu_debug
}
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator>=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -1039,6 +1012,7 @@ namespace __gnu_debug
}
_GLIBCXX_NODISCARD
+ _GLIBCXX20_CONSTEXPR
friend bool
operator>=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -1074,12 +1048,9 @@ namespace __gnu_debug
friend _Self
operator+(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
- _M_message(__msg_advance_oob)
- ._M_iterator(__x)._M_integer(__n));
- }
+ _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
+ _M_message(__msg_advance_oob)
+ ._M_iterator(__x)._M_integer(__n));
return _Safe_iterator(__x.base() + __n, __x._M_sequence);
}
@@ -1088,12 +1059,9 @@ namespace __gnu_debug
friend _Self
operator+(difference_type __n, const _Self& __x) _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
- _M_message(__msg_advance_oob)
- ._M_iterator(__x)._M_integer(__n));
- }
+ _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
+ _M_message(__msg_advance_oob)
+ ._M_iterator(__x)._M_integer(__n));
return _Safe_iterator(__n + __x.base(), __x._M_sequence);
}
@@ -1102,12 +1070,9 @@ namespace __gnu_debug
friend _Self
operator-(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
- _M_message(__msg_retreat_oob)
- ._M_iterator(__x)._M_integer(__n));
- }
+ _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
+ _M_message(__msg_retreat_oob)
+ ._M_iterator(__x)._M_integer(__n));
return _Safe_iterator(__x.base() - __n, __x._M_sequence);
}
};
@@ -1121,12 +1086,7 @@ namespace __gnu_debug
const _Safe_iterator<_Iterator, _Sequence,
_Category>& __last,
typename _Distance_traits<_Iterator>::__type& __dist)
- {
- if (std::__is_constant_evaluated())
- return true;
-
- return __first._M_valid_range(__last, __dist);
- }
+ { return __first._M_valid_range(__last, __dist); }
template<typename _Iterator, typename _Sequence, typename _Category>
_GLIBCXX20_CONSTEXPR
@@ -1136,9 +1096,6 @@ namespace __gnu_debug
const _Safe_iterator<_Iterator, _Sequence,
_Category>& __last)
{
- if (std::__is_constant_evaluated())
- return true;
-
typename _Distance_traits<_Iterator>::__type __dist;
return __first._M_valid_range(__last, __dist);
}
@@ -1149,12 +1106,7 @@ namespace __gnu_debug
inline bool
__can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
_Size __n)
- {
- if (std::__is_constant_evaluated())
- return true;
-
- return __it._M_can_advance(__n);
- }
+ { return __it._M_can_advance(__n); }
template<typename _Iterator, typename _Sequence, typename _Category,
typename _Diff>
@@ -1163,12 +1115,7 @@ namespace __gnu_debug
__can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
const std::pair<_Diff, _Distance_precision>& __dist,
int __way)
- {
- if (std::__is_constant_evaluated())
- return true;
-
- return __it._M_can_advance(__dist, __way);
- }
+ { return __it._M_can_advance(__dist, __way); }
template<typename _Iterator, typename _Sequence>
_GLIBCXX20_CONSTEXPR _Iterator
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc
b/libstdc++-v3/include/debug/safe_iterator.tcc
index 715eceb92f3..11cde2a2a5e 100644
--- a/libstdc++-v3/include/debug/safe_iterator.tcc
+++ b/libstdc++-v3/include/debug/safe_iterator.tcc
@@ -34,7 +34,7 @@
namespace __gnu_debug
{
template<typename _Iterator, typename _Sequence, typename _Category>
- typename _Distance_traits<_Iterator>::__type
+ _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
_Safe_iterator<_Iterator, _Sequence, _Category>::
_M_get_distance_from_begin() const
{
@@ -58,7 +58,7 @@ namespace __gnu_debug
}
template<typename _Iterator, typename _Sequence, typename _Category>
- typename _Distance_traits<_Iterator>::__type
+ _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
_Safe_iterator<_Iterator, _Sequence, _Category>::
_M_get_distance_to_end() const
{
@@ -82,7 +82,7 @@ namespace __gnu_debug
}
template<typename _Iterator, typename _Sequence, typename _Category>
- bool
+ _GLIBCXX20_CONSTEXPR bool
_Safe_iterator<_Iterator, _Sequence, _Category>::
_M_can_advance(difference_type __n, bool __strict) const
{
@@ -191,7 +191,7 @@ namespace __gnu_debug
}
template<typename _Iterator, typename _Sequence, typename _Category>
- bool
+ _GLIBCXX20_CONSTEXPR bool
_Safe_iterator<_Iterator, _Sequence, _Category>::
_M_valid_range(const _Safe_iterator& __rhs,
std::pair<difference_type, _Distance_precision>& __dist,
@@ -221,7 +221,7 @@ namespace __gnu_debug
}
template<typename _Iterator, typename _Sequence>
- bool
+ _GLIBCXX20_CONSTEXPR bool
_Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>::
_M_valid_range(const _Safe_iterator& __rhs,
std::pair<difference_type,
diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h
b/libstdc++-v3/include/debug/safe_local_iterator.h
index d37168a040b..391ddb5cde1 100644
--- a/libstdc++-v3/include/debug/safe_local_iterator.h
+++ b/libstdc++-v3/include/debug/safe_local_iterator.h
@@ -65,9 +65,6 @@ namespace __gnu_debug
: private _Iterator
, public _Safe_local_iterator_base
{
- typedef _Iterator _Iter_base;
- typedef _Safe_local_iterator_base _Safe_base;
-
typedef typename _UContainer::size_type size_type;
typedef std::iterator_traits<_Iterator> _Traits;
@@ -87,7 +84,7 @@ namespace __gnu_debug
_Safe_local_iterator(const _Safe_local_iterator& __x,
_Unchecked) noexcept
- : _Iter_base(__x.base())
+ : _Iterator(__x.base())
{ _M_attach(__x._M_safe_container()); }
public:
@@ -99,7 +96,7 @@ namespace __gnu_debug
typedef typename _Traits::pointer pointer;
/// @post the iterator is singular and unattached
- _Safe_local_iterator() noexcept : _Iter_base() { }
+ _Safe_local_iterator() noexcept : _Iterator() { }
/**
* @brief Safe iterator construction from an unsafe iterator and
@@ -110,14 +107,14 @@ namespace __gnu_debug
*/
_Safe_local_iterator(_Iterator __i,
const _Safe_unordered_container_base* __cont)
- : _Iter_base(__i), _Safe_base(__cont, _S_constant())
+ : _Iterator(__i), _Safe_local_iterator_base(__cont, _S_constant())
{ }
/**
* @brief Copy construction.
*/
_Safe_local_iterator(const _Safe_local_iterator& __x) noexcept
- : _Iter_base(__x.base())
+ : _Iterator(__x.base())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
@@ -134,7 +131,7 @@ namespace __gnu_debug
* @post __x is singular and unattached
*/
_Safe_local_iterator(_Safe_local_iterator&& __x) noexcept
- : _Iter_base()
+ : _Iterator()
{
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x._M_value_initialized(),
@@ -157,7 +154,7 @@ namespace __gnu_debug
typename __gnu_cxx::__enable_if<_IsConstant::__value &&
std::__are_same<_MutableIterator, _OtherIterator>::__value,
_UContainer>::__type>& __x) noexcept
- : _Iter_base(__x.base())
+ : _Iterator(__x.base())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
@@ -240,7 +237,7 @@ namespace __gnu_debug
reference
operator*() const
{
- _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+ _GLIBCXX_DEBUG_VERIFY(_M_dereferenceable(),
_M_message(__msg_bad_deref)
._M_iterator(*this, "this"));
return *base();
@@ -253,7 +250,7 @@ namespace __gnu_debug
pointer
operator->() const
{
- _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+ _GLIBCXX_DEBUG_VERIFY(_M_dereferenceable(),
_M_message(__msg_bad_deref)
._M_iterator(*this, "this"));
return base().operator->();
@@ -267,7 +264,7 @@ namespace __gnu_debug
_Safe_local_iterator&
operator++()
{
- _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+ _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
_M_message(__msg_bad_inc)
._M_iterator(*this, "this"));
__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
@@ -282,7 +279,7 @@ namespace __gnu_debug
_Safe_local_iterator
operator++(int)
{
- _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+ _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
_M_message(__msg_bad_inc)
._M_iterator(*this, "this"));
_Safe_local_iterator __ret(*this, _Unchecked{});
@@ -318,30 +315,39 @@ namespace __gnu_debug
*/
operator _Iterator() const { return *this; }
+ /** Is this iterator singular? */
+ _GLIBCXX20_CONSTEXPR bool
+ _M_singular() const noexcept
+ { return this->_M_is_singular(); }
+
+ _GLIBCXX20_CONSTEXPR bool
+ _M_can_compare(const _Safe_iterator_base& __x) const noexcept
+ { return this->_M_is_comparable(__x); }
+
/** Attach iterator to the given unordered container. */
- void
+ _GLIBCXX20_CONSTEXPR void
_M_attach(const _Safe_unordered_container_base* __cont)
- { _Safe_base::_M_attach(__cont, _S_constant()); }
+ { _Safe_local_iterator_base::_M_attach(__cont, _S_constant()); }
/** Likewise, but not thread-safe. */
void
_M_attach_single(const _Safe_unordered_container_base* __cont)
- { _Safe_base::_M_attach_single(__cont, _S_constant()); }
+ { _Safe_local_iterator_base::_M_attach_single(__cont, _S_constant()); }
/// Is the iterator dereferenceable?
bool
_M_dereferenceable() const
- { return !this->_M_singular() && !_M_is_end(); }
+ { return !_M_singular() && !_M_is_end(); }
/// Is the iterator incrementable?
bool
_M_incrementable() const
- { return !this->_M_singular() && !_M_is_end(); }
+ { return !_M_singular() && !_M_is_end(); }
/// Is the iterator value-initialized?
bool
_M_value_initialized() const
- { return _M_version == 0 && base() == _Iter_base{}; }
+ { return _M_version == 0 && base() == _Iterator{}; }
// Is the iterator range [*this, __rhs) valid?
bool
diff --git a/libstdc++-v3/include/debug/safe_sequence.h
b/libstdc++-v3/include/debug/safe_sequence.h
index e7658bb26a7..4415f689c9f 100644
--- a/libstdc++-v3/include/debug/safe_sequence.h
+++ b/libstdc++-v3/include/debug/safe_sequence.h
@@ -110,6 +110,10 @@ namespace __gnu_debug
template<typename _Sequence>
class _Safe_sequence : public _Safe_sequence_base
{
+ template<typename _Predicate>
+ void
+ _M_invalidate_if_impl(_Predicate __pred) const;
+
public:
/** Invalidates all iterators @c x that reference this sequence,
are not singular, and for which @c __pred(x) returns @c
@@ -117,7 +121,13 @@ namespace __gnu_debug
in the safe ones. */
template<typename _Predicate>
_GLIBCXX20_CONSTEXPR void
- _M_invalidate_if(_Predicate __pred) const;
+ _M_invalidate_if(_Predicate __pred) const
+ {
+ if (std::__is_constant_evaluated())
+ return;
+
+ _M_invalidate_if_impl(__pred);
+ }
/** Transfers all iterators @c x that reference @c from sequence,
are not singular, and for which @c __pred(x) returns @c
diff --git a/libstdc++-v3/include/debug/safe_sequence.tcc
b/libstdc++-v3/include/debug/safe_sequence.tcc
index 884478fad9d..f55767258be 100644
--- a/libstdc++-v3/include/debug/safe_sequence.tcc
+++ b/libstdc++-v3/include/debug/safe_sequence.tcc
@@ -33,13 +33,10 @@ namespace __gnu_debug
{
template<typename _Sequence>
template<typename _Predicate>
- _GLIBCXX20_CONSTEXPR void
+ void
_Safe_sequence<_Sequence>::
- _M_invalidate_if(_Predicate __pred) const
+ _M_invalidate_if_impl(_Predicate __pred) const
{
- if (std::__is_constant_evaluated())
- return;
-
typedef typename _Sequence::iterator iterator;
typedef typename _Sequence::const_iterator const_iterator;
diff --git a/libstdc++-v3/include/debug/safe_unordered_base.h
b/libstdc++-v3/include/debug/safe_unordered_base.h
index 603ceff9a86..427067aaf4e 100644
--- a/libstdc++-v3/include/debug/safe_unordered_base.h
+++ b/libstdc++-v3/include/debug/safe_unordered_base.h
@@ -74,9 +74,9 @@ namespace __gnu_debug
iterator, and false if it is mutable. */
_Safe_local_iterator_base(const _Safe_local_iterator_base& __x,
bool __constant)
- { this->_M_attach(__x._M_safe_container(), __constant); }
+ { _M_attach(__x._M_safe_container(), __constant); }
- ~_Safe_local_iterator_base() { this->_M_detach(); }
+ ~_Safe_local_iterator_base() { _M_detach(); }
/** Attaches this iterator to the given container, detaching it
* from whatever container it was attached to originally. If the
diff --git a/libstdc++-v3/include/debug/vector
b/libstdc++-v3/include/debug/vector
index 61e5ff78a7a..ca9c9169226 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -103,7 +103,7 @@ namespace __gnu_debug
size_type _M_guaranteed_capacity;
- bool
+ _GLIBCXX20_CONSTEXPR bool
_M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
{ return __elements > _M_seq().capacity(); }
@@ -213,8 +213,8 @@ namespace __debug
_GLIBCXX20_CONSTEXPR
vector(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
- : _Base(__gnu_debug::__base(std::__is_constant_evaluated() ? __first
- : __glibcxx_check_valid_constructor_range(__first, __last)),
+ : _Base(__gnu_debug::__base(
+ __glibcxx_check_valid_constructor_range(__first, __last)),
__gnu_debug::__base(__last), __a) { }
#if __cplusplus < 201103L
@@ -277,11 +277,8 @@ namespace __debug
operator=(initializer_list<value_type> __l)
{
_Base::operator=(__l);
- if (!std::__is_constant_evaluated())
- {
- this->_M_invalidate_all();
- this->_M_update_guaranteed_capacity();
- }
+ this->_M_invalidate_all();
+ this->_M_update_guaranteed_capacity();
return *this;
}
#endif
@@ -296,10 +293,6 @@ namespace __debug
void
assign(_InputIterator __first, _InputIterator __last)
{
- if (std::__is_constant_evaluated())
- return _Base::assign(__gnu_debug::__unsafe(__first),
- __gnu_debug::__unsafe(__last));
-
typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
__glibcxx_check_valid_range2(__first, __last, __dist);
@@ -318,11 +311,8 @@ namespace __debug
assign(size_type __n, const _Tp& __u)
{
_Base::assign(__n, __u);
- if (!std::__is_constant_evaluated())
- {
- this->_M_invalidate_all();
- this->_M_update_guaranteed_capacity();
- }
+ this->_M_invalidate_all();
+ this->_M_update_guaranteed_capacity();
}
#if __cplusplus >= 201103L
@@ -331,11 +321,8 @@ namespace __debug
assign(initializer_list<value_type> __l)
{
_Base::assign(__l);
- if (!std::__is_constant_evaluated())
- {
- this->_M_invalidate_all();
- this->_M_update_guaranteed_capacity();
- }
+ this->_M_invalidate_all();
+ this->_M_update_guaranteed_capacity();
}
#endif
@@ -425,9 +412,6 @@ namespace __debug
void
resize(size_type __sz)
{
- if (std::__is_constant_evaluated())
- return _Base::resize(__sz);
-
bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size())
this->_M_invalidate_after_nth(__sz);
@@ -441,9 +425,6 @@ namespace __debug
void
resize(size_type __sz, const _Tp& __c)
{
- if (std::__is_constant_evaluated())
- return _Base::resize(__sz, __c);
-
bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size())
this->_M_invalidate_after_nth(__sz);
@@ -471,9 +452,6 @@ namespace __debug
void
shrink_to_fit()
{
- if (std::__is_constant_evaluated())
- return _Base::shrink_to_fit();
-
if (_Base::_M_shrink_to_fit())
{
this->_M_guaranteed_capacity = _Base::capacity();
@@ -487,9 +465,6 @@ namespace __debug
size_type
capacity() const _GLIBCXX_NOEXCEPT
{
- if (std::__is_constant_evaluated())
- return _Base::capacity();
-
#ifdef _GLIBCXX_DEBUG_PEDANTIC
return this->_M_guaranteed_capacity;
#else
@@ -503,9 +478,6 @@ namespace __debug
void
reserve(size_type __n)
{
- if (std::__is_constant_evaluated())
- return _Base::reserve(__n);
-
bool __realloc = this->_M_requires_reallocation(__n);
_Base::reserve(__n);
if (__n > this->_M_guaranteed_capacity)
@@ -580,9 +552,6 @@ namespace __debug
void
push_back(const _Tp& __x)
{
- if (std::__is_constant_evaluated())
- return _Base::push_back(__x);
-
bool __realloc = this->_M_requires_reallocation(this->size() + 1);
_Base::push_back(__x);
if (__realloc)
@@ -607,9 +576,6 @@ namespace __debug
#endif
emplace_back(_Args&&... __args)
{
- if (std::__is_constant_evaluated())
- return _Base::emplace_back(std::forward<_Args>(__args)...);
-
bool __realloc = this->_M_requires_reallocation(this->size() + 1);
_Base::emplace_back(std::forward<_Args>(__args)...);
if (__realloc)
@@ -625,11 +591,8 @@ namespace __debug
void
pop_back() _GLIBCXX_NOEXCEPT
{
- if (!std::__is_constant_evaluated())
- {
- __glibcxx_check_nonempty();
- this->_M_invalidate_if(_Equal(--_Base::end()));
- }
+ __glibcxx_check_nonempty();
+ this->_M_invalidate_if(_Equal(--_Base::end()));
_Base::pop_back();
}
@@ -639,11 +602,6 @@ namespace __debug
iterator
emplace(const_iterator __position, _Args&&... __args)
{
- if (std::__is_constant_evaluated())
- return iterator(_Base::emplace(__position.base(),
- std::forward<_Args>(__args)...),
- this);
-
__glibcxx_check_insert(__position);
bool __realloc = this->_M_requires_reallocation(this->size() + 1);
difference_type __offset = __position.base() - _Base::cbegin();
@@ -666,9 +624,6 @@ namespace __debug
insert(iterator __position, const _Tp& __x)
#endif
{
- if (std::__is_constant_evaluated())
- return iterator(_Base::insert(__position.base(), __x), this);
-
__glibcxx_check_insert(__position);
bool __realloc = this->_M_requires_reallocation(this->size() + 1);
difference_type __offset = __position.base() - _Base::begin();
@@ -700,9 +655,6 @@ namespace __debug
iterator
insert(const_iterator __position, size_type __n, const _Tp& __x)
{
- if (std::__is_constant_evaluated())
- return iterator(_Base::insert(__position.base(), __n, __x), this);
-
__glibcxx_check_insert(__position);
bool __realloc = this->_M_requires_reallocation(this->size() + __n);
difference_type __offset = __position.base() - _Base::cbegin();
@@ -738,11 +690,6 @@ namespace __debug
insert(const_iterator __position,
_InputIterator __first, _InputIterator __last)
{
- if (std::__is_constant_evaluated())
- return iterator(_Base::insert(__position.base(),
- __gnu_debug::__unsafe(__first),
- __gnu_debug::__unsafe(__last)), this);
-
typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
__glibcxx_check_insert_range(__position, __first, __last, __dist);
@@ -802,9 +749,6 @@ namespace __debug
erase(iterator __position)
#endif
{
- if (std::__is_constant_evaluated())
- return iterator(_Base::erase(__position.base()), this);
-
__glibcxx_check_erase(__position);
difference_type __offset = __position.base() - _Base::begin();
_Base_iterator __res = _Base::erase(__position.base());
@@ -820,9 +764,6 @@ namespace __debug
erase(iterator __first, iterator __last)
#endif
{
- if (std::__is_constant_evaluated())
- return iterator(_Base::erase(__first.base(), __last.base()), this);
-
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
@@ -848,8 +789,7 @@ namespace __debug
swap(vector& __x)
_GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
{
- if (!std::__is_constant_evaluated())
- _Safe::_M_swap(__x);
+ _Safe::_M_swap(__x);
_Base::swap(__x);
std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
}
@@ -859,8 +799,7 @@ namespace __debug
clear() _GLIBCXX_NOEXCEPT
{
_Base::clear();
- if (!std::__is_constant_evaluated())
- this->_M_invalidate_all();
+ this->_M_invalidate_all();
}
_GLIBCXX20_CONSTEXPR
@@ -879,14 +818,11 @@ namespace __debug
auto __old_capacity = _Base::capacity();
auto __old_size = _Base::size();
_Base::assign_range(__rg);
- if (!std::__is_constant_evaluated())
- {
- if (_Base::capacity() != __old_capacity)
- this->_M_invalidate_all();
- else if (_Base::size() < __old_size)
- this->_M_invalidate_after_nth(_Base::size());
- this->_M_update_guaranteed_capacity();
- }
+ if (_Base::capacity() != __old_capacity)
+ this->_M_invalidate_all();
+ else if (_Base::size() < __old_size)
+ this->_M_invalidate_after_nth(_Base::size());
+ this->_M_update_guaranteed_capacity();
}
template<__detail::__container_compatible_range<_Tp> _Rg>
@@ -895,12 +831,9 @@ namespace __debug
{
auto __old_capacity = _Base::capacity();
auto __res = _Base::insert_range(__pos.base(), __rg);
- if (!std::__is_constant_evaluated())
- {
- if (_Base::capacity() != __old_capacity)
- this->_M_invalidate_all();
- this->_M_update_guaranteed_capacity();
- }
+ if (_Base::capacity() != __old_capacity)
+ this->_M_invalidate_all();
+ this->_M_update_guaranteed_capacity();
return iterator(__res, this);
}
@@ -910,17 +843,14 @@ namespace __debug
{
auto __old_capacity = _Base::capacity();
_Base::append_range(__rg);
- if (!std::__is_constant_evaluated())
- {
- if (_Base::capacity() != __old_capacity)
- this->_M_invalidate_all();
- this->_M_update_guaranteed_capacity();
- }
+ if (_Base::capacity() != __old_capacity)
+ this->_M_invalidate_all();
+ this->_M_update_guaranteed_capacity();
}
#endif
private:
- void
+ _GLIBCXX20_CONSTEXPR void
_M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
{
typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 3e6f286bc0a..a79dab9497d 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -346,7 +346,7 @@ namespace __gnu_debug
{
_Safe_iterator_base* __old = __iter;
__iter = __iter->_M_next;
- if (__old->_M_singular())
+ if (__old->_M_is_singular())
__old->_M_detach_single();
}
@@ -354,7 +354,7 @@ namespace __gnu_debug
{
_Safe_iterator_base* __old = __iter2;
__iter2 = __iter2->_M_next;
- if (__old->_M_singular())
+ if (__old->_M_is_singular())
__old->_M_detach_single();
}
}
@@ -462,7 +462,7 @@ namespace __gnu_debug
__it->_M_unlink();
if (_M_const_iterators == __it)
_M_const_iterators = __it->_M_next;
- if (_M_iterators == __it)
+ else if (_M_iterators == __it)
_M_iterators = __it->_M_next;
}
@@ -541,15 +541,17 @@ namespace __gnu_debug
_M_next = 0;
}
+#if !_GLIBCXX_INLINE_VERSION
bool
_Safe_iterator_base::
_M_singular() const noexcept
- { return !_M_sequence || _M_version != _M_sequence->_M_version; }
+ { return _M_is_singular(); }
bool
_Safe_iterator_base::
_M_can_compare(const _Safe_iterator_base& __x) const noexcept
- { return _M_sequence == __x._M_sequence; }
+ { return _M_is_comparable(__x); }
+#endif
__gnu_cxx::__mutex&
_Safe_iterator_base::
@@ -711,7 +713,7 @@ namespace __gnu_debug
__it->_M_unlink();
if (_M_const_local_iterators == __it)
_M_const_local_iterators = __it->_M_next;
- if (_M_local_iterators == __it)
+ else if (_M_local_iterators == __it)
_M_local_iterators = __it->_M_next;
}