[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