[PATCH][_GLIBCXX_DEBUG][__cplusplus >= 201103L] Remove useless workaround
François Dumont
frs.dumont@gmail.com
Mon Mar 2 18:53:13 GMT 2026
libstdc++: [_GLIBCXX_DEBUG][__cplusplus >= 201103L] Remove useless
workaround
Starting with C++11 we leverage on template parameter requirement
to prevent
instantiation of methods taking iterators with invalid types.
So the _GLIBCXX_DEBUG mode do not need to check for potential
ambiguity between
integer type and iterator type anymore.
libstdc++-v3/ChangeLog:
* include/debug/functions.h [__cplusplus >= 201103L]
(__foreign_iterator_aux): Remove.
(__foreign_iterator): Adapt to use __foreign_iterator_aux2.
* include/debug/helper_functions.h [__cplusplus >= 201103L]:
Remove include bits/cpp_type_traits.h.
(_Distance_traits<_Integral, std::__true_type>): Remove.
(__valid_range_aux(_Integral, _Integral, std::__true_type)):
Remove.
(__valid_range_aux(_Iterator, _Iterator,
std::__false_type)): Remove.
(__valid_range_aux(_Integral, _Integral,
_Distance_traits<_Integral>::__type&,
std::__true_type)): Remove.
(__valid_range_aux(_Iterator, _Iterator,
_Distance_traits<_Iterator>::__type&,
std::__false_type)): Remove.
(__valid_range(_Iterator, _Iterator)): Adapt.
(__valid_range(_Iterator, _Iterator,
_Distance_traits<_Iterator>::__type&)): Adapt.
On 3/2/26 11:55, Jonathan Wakely wrote:
> On Mon, 02 Mar 2026 at 07:00 +0100, François Dumont wrote:
>> Hi
>>
>> libstdc++: [_GLIBCXX_DEBUG][__cplusplus >= 201103L] Remove
>> useless workaround
>>
>> Starting with C++11 we leverage on template parameter requirement
>> to prevent
>> instantiation of methods taking iterators with invalid types.
>> So the _GLIBCXX_DEBUG mode do not need to check for potential
>> ambiguity between
>> integer type and iterator type anymore.
>>
>> libstdc++-v3/ChangeLog:
>>
>> * include/debug/functions.h
>> [__cplusplus >= 201103L](__foreign_iterator_aux): Remove.
>> [__cplusplus >= 201103L](__foreign_iterator): Adapt to
>> use __foreign_iterator_aux2.
>
> You can just name the [condition] once per file when it applies to all
> changes, e.g.
>
> * include/debug/functions.h [__cplusplus >= 201103L]
> (__foreign_iterator_aux): Remove.
> (__foreign_iterator): Adapt to use __foreign_iterator_aux2.
>
>
>
>> * include/debug/helper_functions.h
>> [__cplusplus >= 201103L]: Remove include
>> bits/cpp_type_traits.h.
>> [__cplusplus >= 201103L](_Distance_traits<_Integral,
>> std::__true_type>): Remove.
>> [__cplusplus >= 201103L](__valid_range_aux(_Integral,
>> _Integral, std::__true_type)):
>> Remove.
>> [__cplusplus >= 201103L](__valid_range_aux(_Iterator,
>> _Iterator, std::__false_type)):
>> Remove.
>> [__cplusplus >= 201103L]
>> (__valid_range_aux(_Integral, _Integral,
>> _Distance_traits<_Integral>::__type&,
>> std::__true_type)): Remove.
>> [__cplusplus >= 201103L]
>> (__valid_range_aux(_Iterator, _Iterator,
>> _Distance_traits<_Iterator>::__type&,
>> std::__false_type)): Remove.
>> [__cplusplus >= 201103L](__valid_range(_Iterator,
>> _Iterator)): Adapt.
>> [__cplusplus >= 201103L]
>> (__valid_range(_Iterator, _Iterator,
>> _Distance_traits<_Iterator>::__type&)): Adapt.
>>
>> Tested under Linux x64 _GLIBCXX_DEBUG mode.
>>
>> Ok to commit ?
>
> Some questions below ...
>
>> François
>>
>
>> diff --git a/libstdc++-v3/include/debug/functions.h
>> b/libstdc++-v3/include/debug/functions.h
>> index 99a0c41758d..d2acba34ef2 100644
>> --- a/libstdc++-v3/include/debug/functions.h
>> +++ b/libstdc++-v3/include/debug/functions.h
>> @@ -168,6 +168,7 @@ namespace __gnu_debug
>> return __foreign_iterator_aux3(__it, __other, __other_end,
>> __tag());
>> }
>>
>> +#if __cplusplus < 201103L
>> /* Handle the case where we aren't really inserting a range after
>> all */
>> template<typename _Iterator, typename _Sequence, typename _Category,
>> typename _Integral>
>> @@ -185,12 +186,21 @@ namespace __gnu_debug
>> const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
>> _InputIterator __other, _InputIterator __other_end,
>> std::__false_type)
>> +#else
>> + template<typename _Iterator, typename _Sequence, typename _Category,
>> + typename _InputIterator>
>> + inline bool
>> + __foreign_iterator(
>> + const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
>> + _InputIterator __other, _InputIterator __other_end)
>> +#endif
>> {
>> return _Insert_range_from_self_is_safe<_Sequence>::__value
>> || __foreign_iterator_aux2(__it, std::__miter_base(__other),
>> std::__miter_base(__other_end));
>> }
>>
>> +#if __cplusplus < 201103L
>> template<typename _Iterator, typename _Sequence, typename _Category,
>> typename _InputIterator>
>> inline bool
>> @@ -201,6 +211,7 @@ namespace __gnu_debug
>> typedef typename std::__is_integer<_InputIterator>::__type
>> _Integral;
>> return __foreign_iterator_aux(__it, __other, __other_end,
>> _Integral());
>> }
>> +#endif
>>
>> // Can't check if an input iterator sequence is sorted, because we
>> // can't step through the sequence.
>> diff --git a/libstdc++-v3/include/debug/helper_functions.h
>> b/libstdc++-v3/include/debug/helper_functions.h
>> index 8ef21684650..43072874590 100644
>> --- a/libstdc++-v3/include/debug/helper_functions.h
>> +++ b/libstdc++-v3/include/debug/helper_functions.h
>> @@ -32,7 +32,9 @@
>> #include <bits/move.h> // for __addressof
>> #include <bits/stl_iterator_base_types.h> // for iterator_traits,
>> // categories and _Iter_base
>> -#include <bits/cpp_type_traits.h> // for __is_integer
>> +#if __cplusplus < 201103L
>> +# include <bits/cpp_type_traits.h> // for __is_integer
>> +#endif
>>
>> #include <bits/stl_pair.h> // for pair
>>
>> @@ -58,8 +60,12 @@ namespace __gnu_debug
>> __dp_exact //< Can determine distance precisely
>> };
>>
>> +#if __cplusplus >= 201103L
>> + template<typename _Iterator>
>> +#else
>> template<typename _Iterator,
>> typename = typename std::__is_integer<_Iterator>::__type>
>> +#endif
>> struct _Distance_traits
>> {
>> private:
>> @@ -80,9 +86,11 @@ namespace __gnu_debug
>> typedef std::pair<_DiffType, _Distance_precision> __type;
>> };
>>
>> +#if __cplusplus < 201103L
>> template<typename _Integral>
>> struct _Distance_traits<_Integral, std::__true_type>
>> { typedef std::pair<std::ptrdiff_t, _Distance_precision> __type; };
>> +#endif
>>
>> /** Determine the distance between two iterators with some known
>> * precision.
>> @@ -141,18 +149,16 @@ namespace __gnu_debug
>> __check_singular(_Tp* const& __ptr)
>> { return __ptr == 0; }
>>
>> +#if __cplusplus < 201103L
>> /** We say that integral types for a valid range, and defer to other
>
> Is this meant to say "form a valid range"?
I did not reconsider those comments. No idea what it was supposed to
say. I guess it was meant to cover the different functions following it.
I've simplified it.
>
>> * routines to realize what to do with integral types instead of
>> - * iterators.
>> - */
>> + * iterators. */
>
> Was this change an accident? We usually end the doxygen comment on a
> separate line.
I thought both forms were fine but the only similar form I can find are
mine so reverted.
>
>> template<typename _Integral>
>> - _GLIBCXX_CONSTEXPR
>> inline bool
>> __valid_range_aux(_Integral, _Integral, std::__true_type)
>> { return true; }
>>
>> template<typename _Integral>
>> - _GLIBCXX20_CONSTEXPR
>> inline bool
>> __valid_range_aux(_Integral, _Integral,
>> typename _Distance_traits<_Integral>::__type& __dist,
>> @@ -161,6 +167,7 @@ namespace __gnu_debug
>> __dist = std::make_pair(0, __dp_none);
>> return true;
>> }
>> +#endif
>>
>> template<typename _InputIterator>
>> _GLIBCXX_CONSTEXPR
>> @@ -189,25 +196,36 @@ namespace __gnu_debug
>> && __first <= __last;
>> }
>>
>> +#if __cplusplus >= 201103L
>> + template<typename _InputIterator>
>> + constexpr bool
>
> It looks like this changes the function from being
> _GLIBCXX14_CONSTEXPR to always constexpr in C++11. I think that's OK.
I hadn't noticed it ! I just reflected what was on __valid_range_aux
below, we had a _GLIBCXX14_CONSTEXPR function invoking only function
overloads qualified as _GLIBCXX_CONSTEXPR. So indeed defining it as
constexpr directly is fine.
>
>> + __valid_range(_InputIterator __first, _InputIterator __last)
>> +#else
>> /** We have iterators, so figure out what kind of iterators they are
>> - * to see if we can check the range ahead of time.
>> - */
>> + * to see if we can check the range ahead of time. */
>
> Same question about the comment as above.
>
>> template<typename _InputIterator>
>> - _GLIBCXX_CONSTEXPR
>> inline bool
>> __valid_range_aux(_InputIterator __first, _InputIterator __last,
>> std::__false_type)
>> +#endif
>> {
>> return __gnu_debug::__valid_range_aux(__first, __last,
>> std::__iterator_category(__first));
>> }
>>
>> +#if __cplusplus >= 201103L
>> template<typename _InputIterator>
>> _GLIBCXX20_CONSTEXPR
>> + inline bool
>> + __valid_range(_InputIterator __first, _InputIterator __last,
>> + typename _Distance_traits<_InputIterator>::__type& __dist)
>> +#else
>> + template<typename _InputIterator>
>> inline bool
>> __valid_range_aux(_InputIterator __first, _InputIterator __last,
>> typename _Distance_traits<_InputIterator>::__type& __dist,
>> std::__false_type)
>> +#endif
>> {
>> if (!__gnu_debug::__valid_range_aux(__first, __last,
>> std::input_iterator_tag()))
>> @@ -232,13 +250,12 @@ namespace __gnu_debug
>> return true;
>> }
>>
>> +#if __cplusplus < 201103L
>> /** Don't know what these iterators are, or if they are even
>> * iterators (we may get an integral type for InputIterator), so
>> * see if they are integral and pass them on to the next phase
>> - * otherwise.
>> - */
>> + * otherwise. */
>
> OK, it's not looking like an accident now :-)
> These changes are not following our usual convention.
Yes, reverted.
>
>> template<typename _InputIterator>
>> - _GLIBCXX20_CONSTEXPR
>> inline bool
>> __valid_range(_InputIterator __first, _InputIterator __last,
>> typename _Distance_traits<_InputIterator>::__type& __dist)
>> @@ -247,6 +264,7 @@ namespace __gnu_debug
>> return __gnu_debug::__valid_range_aux(__first, __last, __dist,
>> _Integral());
>> }
>> +#endif
>>
>> template<typename _Iterator, typename _Sequence, typename _Category>
>> _GLIBCXX20_CONSTEXPR bool
>> @@ -262,14 +280,15 @@ namespace __gnu_debug
>> typename _Distance_traits<_Iterator>::__type&);
>> #endif
>>
>> +#if __cplusplus < 201103L
>> template<typename _InputIterator>
>> - _GLIBCXX14_CONSTEXPR
>> inline bool
>> __valid_range(_InputIterator __first, _InputIterator __last)
>> {
>> typedef typename std::__is_integer<_InputIterator>::__type
>> _Integral;
>> return __gnu_debug::__valid_range_aux(__first, __last,
>> _Integral());
>> }
>> +#endif
>>
>> template<typename _Iterator, typename _Sequence, typename _Category>
>> _GLIBCXX20_CONSTEXPR bool
>
Ok to commit ?
François
-------------- next part --------------
diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index 99a0c41758d..d2acba34ef2 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -168,6 +168,7 @@ namespace __gnu_debug
return __foreign_iterator_aux3(__it, __other, __other_end, __tag());
}
+#if __cplusplus < 201103L
/* Handle the case where we aren't really inserting a range after all */
template<typename _Iterator, typename _Sequence, typename _Category,
typename _Integral>
@@ -185,12 +186,21 @@ namespace __gnu_debug
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
_InputIterator __other, _InputIterator __other_end,
std::__false_type)
+#else
+ template<typename _Iterator, typename _Sequence, typename _Category,
+ typename _InputIterator>
+ inline bool
+ __foreign_iterator(
+ const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
+ _InputIterator __other, _InputIterator __other_end)
+#endif
{
return _Insert_range_from_self_is_safe<_Sequence>::__value
|| __foreign_iterator_aux2(__it, std::__miter_base(__other),
std::__miter_base(__other_end));
}
+#if __cplusplus < 201103L
template<typename _Iterator, typename _Sequence, typename _Category,
typename _InputIterator>
inline bool
@@ -201,6 +211,7 @@ namespace __gnu_debug
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
}
+#endif
// Can't check if an input iterator sequence is sorted, because we
// can't step through the sequence.
diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h
index 8ef21684650..0bd5a1cbdf4 100644
--- a/libstdc++-v3/include/debug/helper_functions.h
+++ b/libstdc++-v3/include/debug/helper_functions.h
@@ -32,7 +32,9 @@
#include <bits/move.h> // for __addressof
#include <bits/stl_iterator_base_types.h> // for iterator_traits,
// categories and _Iter_base
-#include <bits/cpp_type_traits.h> // for __is_integer
+#if __cplusplus < 201103L
+# include <bits/cpp_type_traits.h> // for __is_integer
+#endif
#include <bits/stl_pair.h> // for pair
@@ -58,8 +60,12 @@ namespace __gnu_debug
__dp_exact //< Can determine distance precisely
};
+#if __cplusplus >= 201103L
+ template<typename _Iterator>
+#else
template<typename _Iterator,
typename = typename std::__is_integer<_Iterator>::__type>
+#endif
struct _Distance_traits
{
private:
@@ -80,9 +86,11 @@ namespace __gnu_debug
typedef std::pair<_DiffType, _Distance_precision> __type;
};
+#if __cplusplus < 201103L
template<typename _Integral>
struct _Distance_traits<_Integral, std::__true_type>
{ typedef std::pair<std::ptrdiff_t, _Distance_precision> __type; };
+#endif
/** Determine the distance between two iterators with some known
* precision.
@@ -141,18 +149,14 @@ namespace __gnu_debug
__check_singular(_Tp* const& __ptr)
{ return __ptr == 0; }
- /** We say that integral types for a valid range, and defer to other
- * routines to realize what to do with integral types instead of
- * iterators.
- */
+#if __cplusplus < 201103L
+ // In case of integral type no assertions.
template<typename _Integral>
- _GLIBCXX_CONSTEXPR
inline bool
__valid_range_aux(_Integral, _Integral, std::__true_type)
{ return true; }
template<typename _Integral>
- _GLIBCXX20_CONSTEXPR
inline bool
__valid_range_aux(_Integral, _Integral,
typename _Distance_traits<_Integral>::__type& __dist,
@@ -161,6 +165,7 @@ namespace __gnu_debug
__dist = std::make_pair(0, __dp_none);
return true;
}
+#endif
template<typename _InputIterator>
_GLIBCXX_CONSTEXPR
@@ -189,25 +194,37 @@ namespace __gnu_debug
&& __first <= __last;
}
+#if __cplusplus >= 201103L
+ template<typename _InputIterator>
+ constexpr bool
+ __valid_range(_InputIterator __first, _InputIterator __last)
+#else
/** We have iterators, so figure out what kind of iterators they are
* to see if we can check the range ahead of time.
*/
template<typename _InputIterator>
- _GLIBCXX_CONSTEXPR
inline bool
__valid_range_aux(_InputIterator __first, _InputIterator __last,
std::__false_type)
+#endif
{
return __gnu_debug::__valid_range_aux(__first, __last,
std::__iterator_category(__first));
}
+#if __cplusplus >= 201103L
template<typename _InputIterator>
_GLIBCXX20_CONSTEXPR
+ inline bool
+ __valid_range(_InputIterator __first, _InputIterator __last,
+ typename _Distance_traits<_InputIterator>::__type& __dist)
+#else
+ template<typename _InputIterator>
inline bool
__valid_range_aux(_InputIterator __first, _InputIterator __last,
typename _Distance_traits<_InputIterator>::__type& __dist,
std::__false_type)
+#endif
{
if (!__gnu_debug::__valid_range_aux(__first, __last,
std::input_iterator_tag()))
@@ -232,13 +249,13 @@ namespace __gnu_debug
return true;
}
+#if __cplusplus < 201103L
/** Don't know what these iterators are, or if they are even
* iterators (we may get an integral type for InputIterator), so
* see if they are integral and pass them on to the next phase
* otherwise.
*/
template<typename _InputIterator>
- _GLIBCXX20_CONSTEXPR
inline bool
__valid_range(_InputIterator __first, _InputIterator __last,
typename _Distance_traits<_InputIterator>::__type& __dist)
@@ -247,6 +264,7 @@ namespace __gnu_debug
return __gnu_debug::__valid_range_aux(__first, __last, __dist,
_Integral());
}
+#endif
template<typename _Iterator, typename _Sequence, typename _Category>
_GLIBCXX20_CONSTEXPR bool
@@ -262,14 +280,15 @@ namespace __gnu_debug
typename _Distance_traits<_Iterator>::__type&);
#endif
+#if __cplusplus < 201103L
template<typename _InputIterator>
- _GLIBCXX14_CONSTEXPR
inline bool
__valid_range(_InputIterator __first, _InputIterator __last)
{
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
return __gnu_debug::__valid_range_aux(__first, __last, _Integral());
}
+#endif
template<typename _Iterator, typename _Sequence, typename _Category>
_GLIBCXX20_CONSTEXPR bool
More information about the Libstdc++
mailing list