This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Reorganize and clean debug headers


Hi

While working on new debug checks I came up with reorganizing existing ones to limit as much as possible useless includes.

    Tested under linux x86_64.

From the latest mails I saw on this mailing list I guess I must wait, right ?

2015-01-20  FranÃois Dumont  <fdumont@gcc.gnu.org>

    * include/debug/debug.h ([_GLIBCXX_DEBUG_ASSERT,
    _GLIBCXX_DEBUG_PEDASSERT, _GLIBCXX_DEBUG_ONLY]): Move definition...
    * include/debug/assertions.h: ...here, new.
    * include/debug/functions.h (__foreign_iterator): Move definition...
    * include/debug/functions.tcc: ...here, new.
    * include/Makefile.am: Add new above debug files.
    * include/Makefile.in: Regenerate.
    * include/debug/formatter.h: Include typeinfo only if rtti enabled.
    [_GLIBCXX_TYPEID]: New, use it throughout the file.
    * include/debug/safe_iterator.h: Replace debug.h include with
    assertions.h.
    (__check_dereferenceable, __valid_range): Move here overload for
    _Safe_iterator.
    (struct __is_safe_random_iterator): Move here partial specialization
    for _Safe_iterator.
    (__check_singular_aux): Move...
    * include/debug/safe_base.h (__check_singular_aux): ... here.
    * include/debug/safe_local_iterator.h (__check_dereferenceable)
    (__valid_range): Move here overload for _Safe_local_iterator.
    * include/debug/safe_sequence.h
    * include/debug/safe_unordered_container.h
    * include/debug/array: Replace safe_sequence.h include with
    formatter.h and macros.h.
    * include/debug/deque: Include functions.tcc.
    * include/debug/forward_list: Likewise.
    * include/debug/list: Likewise.
    * include/debug/string: Likewise.
    * include/debug/vector: Likewise.
    * include/bits/unique_ptr.h: Replace debug.h include with new
    assertions.h.
    * include/bits/stl_iterator_base_funcs.h: Likewise.
    * testsuite/23_containers/array/tuple_interface/get_debug_neg.cc:
    Adjust dg-error line number.
    * testsuite/23_containers/array/tuple_interface/
    tuple_element_debug_neg.cc: Likewise.

FranÃois

Index: include/Makefile.am
===================================================================
--- include/Makefile.am	(revision 219856)
+++ include/Makefile.am	(working copy)
@@ -733,6 +733,7 @@
 debug_builddir = ./debug
 debug_headers = \
 	${debug_srcdir}/array \
+	${debug_srcdir}/assertions.h \
 	${debug_srcdir}/bitset \
 	${debug_srcdir}/debug.h \
 	${debug_srcdir}/deque \
@@ -739,6 +740,7 @@
 	${debug_srcdir}/formatter.h \
 	${debug_srcdir}/forward_list \
 	${debug_srcdir}/functions.h \
+	${debug_srcdir}/functions.tcc \
 	${debug_srcdir}/list \
 	${debug_srcdir}/map \
 	${debug_srcdir}/macros.h \
Index: include/Makefile.in
===================================================================
--- include/Makefile.in	(revision 219856)
+++ include/Makefile.in	(working copy)
@@ -995,6 +995,7 @@
 debug_builddir = ./debug
 debug_headers = \
 	${debug_srcdir}/array \
+	${debug_srcdir}/assertions.h \
 	${debug_srcdir}/bitset \
 	${debug_srcdir}/debug.h \
 	${debug_srcdir}/deque \
@@ -1001,6 +1002,7 @@
 	${debug_srcdir}/formatter.h \
 	${debug_srcdir}/forward_list \
 	${debug_srcdir}/functions.h \
+	${debug_srcdir}/functions.tcc \
 	${debug_srcdir}/list \
 	${debug_srcdir}/map \
 	${debug_srcdir}/macros.h \
Index: include/bits/stl_iterator_base_funcs.h
===================================================================
--- include/bits/stl_iterator_base_funcs.h	(revision 219856)
+++ include/bits/stl_iterator_base_funcs.h	(working copy)
@@ -62,7 +62,7 @@
 #pragma GCC system_header
 
 #include <bits/concept_check.h>
-#include <debug/debug.h>
+#include <debug/assertions.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
Index: include/bits/unique_ptr.h
===================================================================
--- include/bits/unique_ptr.h	(revision 219856)
+++ include/bits/unique_ptr.h	(working copy)
@@ -31,7 +31,7 @@
 #define _UNIQUE_PTR_H 1
 
 #include <bits/c++config.h>
-#include <debug/debug.h>
+#include <debug/assertions.h>
 #include <type_traits>
 #include <utility>
 #include <tuple>
Index: include/debug/array
===================================================================
--- include/debug/array	(revision 219856)
+++ include/debug/array	(working copy)
@@ -31,7 +31,8 @@
 
 #pragma GCC system_header
 
-#include <debug/safe_sequence.h>
+#include <debug/formatter.h>
+#include <debug/macros.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
Index: include/debug/assertions.h
===================================================================
--- include/debug/assertions.h	(revision 0)
+++ include/debug/assertions.h	(working copy)
@@ -0,0 +1,52 @@
+// Debugging support implementation -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file debug/assertions.h
+ *  This file is a GNU debug extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_DEBUG_ASSERTIONS_H
+#define _GLIBCXX_DEBUG_ASSERTIONS_H 1
+
+#ifndef _GLIBCXX_DEBUG
+
+# define _GLIBCXX_DEBUG_ASSERT(_Condition)
+# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
+# define _GLIBCXX_DEBUG_ONLY(_Statement) ;
+
+#else
+
+#define _GLIBCXX_DEBUG_ASSERT(_Condition) __glibcxx_assert(_Condition)
+
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition)
+#else
+# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
+#endif
+
+# define _GLIBCXX_DEBUG_ONLY(_Statement) _Statement
+
+#endif
+
+#endif // _GLIBCXX_DEBUG_ASSERTIONS
Index: include/debug/debug.h
===================================================================
--- include/debug/debug.h	(revision 219856)
+++ include/debug/debug.h	(working copy)
@@ -37,6 +37,8 @@
  *  the standard library algorithms.
 */
 
+#include <debug/assertions.h>
+
 // Debug mode namespaces.
 
 /**
@@ -58,9 +60,6 @@
 
 #ifndef _GLIBCXX_DEBUG
 
-# define _GLIBCXX_DEBUG_ASSERT(_Condition)
-# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
-# define _GLIBCXX_DEBUG_ONLY(_Statement) ;
 # define __glibcxx_requires_cond(_Cond,_Msg)
 # define __glibcxx_requires_valid_range(_First,_Last)
 # define __glibcxx_requires_non_empty_range(_First,_Last)
@@ -83,16 +82,6 @@
 
 # include <debug/macros.h>
 
-#define _GLIBCXX_DEBUG_ASSERT(_Condition) __glibcxx_assert(_Condition)
-
-#ifdef _GLIBCXX_DEBUG_PEDANTIC
-# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition)
-#else
-# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
-#endif
-
-# define _GLIBCXX_DEBUG_ONLY(_Statement) _Statement
-
 # define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg)
 # define __glibcxx_requires_valid_range(_First,_Last) \
      __glibcxx_check_valid_range(_First,_Last)
Index: include/debug/deque
===================================================================
--- include/debug/deque	(revision 219856)
+++ include/debug/deque	(working copy)
@@ -636,4 +636,6 @@
 } // namespace __debug
 } // namespace std
 
+#include <debug/functions.tcc>
+
 #endif
Index: include/debug/formatter.h
===================================================================
--- include/debug/formatter.h	(revision 219856)
+++ include/debug/formatter.h	(working copy)
@@ -31,8 +31,18 @@
 
 #include <bits/c++config.h>
 #include <bits/cpp_type_traits.h>
-#include <typeinfo>
 
+#if __cpp_rtti
+# include <typeinfo>
+# define _GLIBCXX_TYPEID(_Type) &typeid(_Type)
+#else
+namespace std
+{
+  class type_info;
+}
+# define _GLIBCXX_TYPEID(_Type) 0
+#endif
+
 namespace __gnu_debug
 {
   using std::type_info;
@@ -218,21 +228,13 @@
         {
 	  _M_variant._M_iterator._M_name = __name;
 	  _M_variant._M_iterator._M_address = &__it;
-#if __cpp_rtti
-	  _M_variant._M_iterator._M_type = &typeid(__it);
-#else
-	  _M_variant._M_iterator._M_type = 0;
-#endif
+	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness =
 	    std::__are_same<_Safe_iterator<_Iterator, _Sequence>,
 	                    typename _Sequence::iterator>::
 	      __value ? __mutable_iterator : __const_iterator;
 	  _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
-#if __cpp_rtti
-	  _M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
-#else
-	  _M_variant._M_iterator._M_seq_type = 0;
-#endif
+	  _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
 
 	  if (__it._M_singular())
 	    _M_variant._M_iterator._M_state = __singular;
@@ -256,21 +258,13 @@
 	{
 	  _M_variant._M_iterator._M_name = __name;
 	  _M_variant._M_iterator._M_address = &__it;
-#if __cpp_rtti
-	  _M_variant._M_iterator._M_type = &typeid(__it);
-#else
-	  _M_variant._M_iterator._M_type = 0;
-#endif
+	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness =
 	    std::__are_same<_Safe_local_iterator<_Iterator, _Sequence>,
 	                    typename _Sequence::local_iterator>::
 	      __value ? __mutable_iterator : __const_iterator;
 	  _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
-#if __cpp_rtti
-	  _M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
-#else
-	  _M_variant._M_iterator._M_seq_type = 0;
-#endif
+	  _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
 
 	  if (__it._M_singular())
 	    _M_variant._M_iterator._M_state = __singular;
@@ -291,11 +285,7 @@
         {
 	  _M_variant._M_iterator._M_name = __name;
 	  _M_variant._M_iterator._M_address = &__it;
-#if __cpp_rtti
-	  _M_variant._M_iterator._M_type = &typeid(__it);
-#else
-	  _M_variant._M_iterator._M_type = 0;
-#endif
+	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness = __mutable_iterator;
 	  _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
 	  _M_variant._M_iterator._M_sequence = 0;
@@ -308,11 +298,7 @@
         {
 	  _M_variant._M_iterator._M_name = __name;
 	  _M_variant._M_iterator._M_address = &__it;
-#if __cpp_rtti
-	  _M_variant._M_iterator._M_type = &typeid(__it);
-#else
-	  _M_variant._M_iterator._M_type = 0;
-#endif
+	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness = __const_iterator;
 	  _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
 	  _M_variant._M_iterator._M_sequence = 0;
@@ -325,11 +311,7 @@
         {
 	  _M_variant._M_iterator._M_name = __name;
 	  _M_variant._M_iterator._M_address = &__it;
-#if __cpp_rtti
-	  _M_variant._M_iterator._M_type = &typeid(__it);
-#else
-	  _M_variant._M_iterator._M_type = 0;
-#endif
+	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
 	  _M_variant._M_iterator._M_constness = __unknown_constness;
 	  _M_variant._M_iterator._M_state =
 	    __gnu_debug::__check_singular(__it)? __singular : __unknown_state;
@@ -345,11 +327,7 @@
 	  _M_variant._M_sequence._M_name = __name;
 	  _M_variant._M_sequence._M_address =
 	    static_cast<const _Sequence*>(&__seq);
-#if __cpp_rtti
-	  _M_variant._M_sequence._M_type = &typeid(_Sequence);
-#else
-	  _M_variant._M_sequence._M_type = 0;
-#endif
+	  _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
 	}
 
       template<typename _Sequence>
@@ -358,11 +336,7 @@
         {
 	  _M_variant._M_sequence._M_name = __name;
 	  _M_variant._M_sequence._M_address = &__seq;
-#if __cpp_rtti
-	  _M_variant._M_sequence._M_type = &typeid(_Sequence);
-#else
-	  _M_variant._M_sequence._M_type = 0;
-#endif
+	  _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
 	}
 
       void
@@ -443,16 +417,16 @@
 
     enum { __max_parameters = 9 };
 
-    const char*         _M_file;
-    std::size_t         _M_line;
-    mutable _Parameter  _M_parameters[__max_parameters];
-    mutable std::size_t _M_num_parameters;
-    mutable const char* _M_text;
-    mutable std::size_t _M_max_length;
+    const char*		_M_file;
+    std::size_t		_M_line;
+    mutable _Parameter	_M_parameters[__max_parameters];
+    mutable std::size_t	_M_num_parameters;
+    mutable const char*	_M_text;
+    mutable std::size_t	_M_max_length;
     enum { _M_indent = 4 } ;
-    mutable std::size_t _M_column;
-    mutable bool        _M_first_line;
-    mutable bool        _M_wordwrap;
+    mutable std::size_t	_M_column;
+    mutable bool	_M_first_line;
+    mutable bool	_M_wordwrap;
 
   public:
     static _Error_formatter
@@ -461,4 +435,6 @@
   };
 } // namespace __gnu_debug
 
+#undef _GLIBCXX_TYPEID
+
 #endif
Index: include/debug/forward_list
===================================================================
--- include/debug/forward_list	(revision 219856)
+++ include/debug/forward_list	(working copy)
@@ -824,4 +824,6 @@
 #endif
 }
 
+#include <debug/functions.tcc>
+
 #endif
Index: include/debug/functions.h
===================================================================
--- include/debug/functions.h	(revision 219856)
+++ include/debug/functions.h	(working copy)
@@ -33,11 +33,7 @@
 #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and
 					  // _Iter_base
 #include <bits/cpp_type_traits.h>	  // for __is_integer
-#include <bits/move.h>                    // for __addressof and addressof
-#include <bits/stl_function.h>		  // for less
-#if __cplusplus >= 201103L
-# include <type_traits>			  // for is_lvalue_reference and __and_
-#endif
+
 #include <debug/formatter.h>
 
 namespace __gnu_debug
@@ -45,9 +41,6 @@
   template<typename _Iterator, typename _Sequence>
     class _Safe_iterator;
 
-  template<typename _Iterator, typename _Sequence>
-    class _Safe_local_iterator;
-
   template<typename _Sequence>
     struct _Insert_range_from_self_is_safe
     { enum { __value = 0 }; };
@@ -85,19 +78,6 @@
     __check_dereferenceable(const _Tp* __ptr)
     { return __ptr; }
 
-  /** Safe iterators know if they are dereferenceable. */
-  template<typename _Iterator, typename _Sequence>
-    inline bool
-    __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
-    { return __x._M_dereferenceable(); }
-
-  /** Safe local iterators know if they are dereferenceable. */
-  template<typename _Iterator, typename _Sequence>
-    inline bool
-    __check_dereferenceable(const _Safe_local_iterator<_Iterator,
-						       _Sequence>& __x)
-    { return __x._M_dereferenceable(); }
-
   /** If the distance between two random access iterators is
    *  nonnegative, assume the range is valid.
   */
@@ -150,20 +130,6 @@
       return __valid_range_aux(__first, __last, _Integral());
     }
 
-  /** Safe iterators know how to check if they form a valid range. */
-  template<typename _Iterator, typename _Sequence>
-    inline bool
-    __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
-		  const _Safe_iterator<_Iterator, _Sequence>& __last)
-    { return __first._M_valid_range(__last); }
-
-  /** Safe local iterators know how to check if they form a valid range. */
-  template<typename _Iterator, typename _Sequence>
-    inline bool
-    __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first,
-		  const _Safe_local_iterator<_Iterator, _Sequence>& __last)
-    { return __first._M_valid_range(__last); }
-
   /* Checks that [first, last) is a valid range, and then returns
    * __first. This routine is useful when we can't use a separate
    * assertion statement because, e.g., we are in a constructor.
@@ -178,121 +144,11 @@
       return __first;
     }
 
-  /* Handle the case where __other is a pointer to _Sequence::value_type. */
-  template<typename _Iterator, typename _Sequence>
-    inline bool
-    __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it,
-			    const typename _Sequence::value_type* __other)
-    {
-      typedef const typename _Sequence::value_type* _PointerType;
-      typedef std::less<_PointerType> _Less;
-#if __cplusplus >= 201103L
-      constexpr _Less __l{};
-#else
-      const _Less __l = _Less();
-#endif
-      const _Sequence* __seq = __it._M_get_sequence();
-      const _PointerType __begin = std::__addressof(*__seq->_M_base().begin());
-      const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1));
-
-      // Check whether __other points within the contiguous storage.
-      return __l(__other, __begin) || __l(__end, __other);
-    }
-
-  /* Fallback overload for when we can't tell, assume it is valid. */
-  template<typename _Iterator, typename _Sequence>
-    inline bool
-    __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&, ...)
-    { return true; }
-
-  /* Handle sequences with contiguous storage */
-  template<typename _Iterator, typename _Sequence, typename _InputIterator>
-    inline bool
-    __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
-			    const _InputIterator& __other,
-			    const _InputIterator& __other_end,
-			    std::__true_type)
-    {
-      if (__other == __other_end)
-	return true;  // inserting nothing is safe even if not foreign iters
-      if (__it._M_get_sequence()->begin() == __it._M_get_sequence()->end())
-	return true;  // can't be self-inserting if self is empty
-      return __foreign_iterator_aux4(__it, std::__addressof(*__other));
-    }
-
-  /* Handle non-contiguous containers, assume it is valid. */
-  template<typename _Iterator, typename _Sequence, typename _InputIterator>
-    inline bool
-    __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>&,
-			    const _InputIterator&, const _InputIterator&,
-			    std::__false_type)
-    { return true; }
-
-  /** Handle debug iterators from the same type of container. */
-  template<typename _Iterator, typename _Sequence, typename _OtherIterator>
-    inline bool
-    __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
-		const _Safe_iterator<_OtherIterator, _Sequence>& __other,
-		const _Safe_iterator<_OtherIterator, _Sequence>&)
-    { return __it._M_get_sequence() != __other._M_get_sequence(); }
-
-  /** Handle debug iterators from different types of container. */
-  template<typename _Iterator, typename _Sequence, typename _OtherIterator,
-	   typename _OtherSequence>
-    inline bool
-    __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
-		const _Safe_iterator<_OtherIterator, _OtherSequence>&,
-		const _Safe_iterator<_OtherIterator, _OtherSequence>&)
-    { return true; }
-
-  /* Handle non-debug iterators. */
-  template<typename _Iterator, typename _Sequence, typename _InputIterator>
-    inline bool
-    __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
-			    const _InputIterator& __other,
-			    const _InputIterator& __other_end)
-    {
-#if __cplusplus < 201103L
-      typedef _Is_contiguous_sequence<_Sequence> __tag;
-#else
-      using __lvalref = std::is_lvalue_reference<
-	typename std::iterator_traits<_InputIterator>::reference>;
-      using __contiguous = _Is_contiguous_sequence<_Sequence>;
-      using __tag = typename std::conditional<__lvalref::value, __contiguous,
-					      std::__false_type>::type;
-#endif
-      return __foreign_iterator_aux3(__it, __other, __other_end, __tag());
-    }
-
-  /* Handle the case where we aren't really inserting a range after all */
-  template<typename _Iterator, typename _Sequence, typename _Integral>
-    inline bool
-    __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>&,
-			   _Integral, _Integral,
-			   std::__true_type)
-    { return true; }
-
-  /* Handle all iterators. */
   template<typename _Iterator, typename _Sequence,
 	   typename _InputIterator>
-    inline bool
-    __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it,
-			   _InputIterator __other, _InputIterator __other_end,
-			   std::__false_type)
-    {
-      return _Insert_range_from_self_is_safe<_Sequence>::__value
-	     || __foreign_iterator_aux2(__it, __other, __other_end);
-    }
-
-  template<typename _Iterator, typename _Sequence,
-	   typename _InputIterator>
-    inline bool
+    bool
     __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it,
-		       _InputIterator __other, _InputIterator __other_end)
-    {
-      typedef typename std::__is_integer<_InputIterator>::__type _Integral;
-      return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
-    }
+		       _InputIterator __other, _InputIterator __other_end);
 
   /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
   template<typename _CharT, typename _Integer>
@@ -535,13 +391,6 @@
       typedef std::__false_type __type;
     };
 
-  template<typename _Iterator, typename _Sequence>
-    struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
-    : std::__are_same<std::random_access_iterator_tag,
-                      typename std::iterator_traits<_Iterator>::
-		      iterator_category>
-    { };
-
   template<typename _Iterator>
     struct _Siter_base
     : std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value>
Index: include/debug/functions.tcc
===================================================================
--- include/debug/functions.tcc	(revision 0)
+++ include/debug/functions.tcc	(working copy)
@@ -0,0 +1,159 @@
+// Debugging support implementation -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file debug/functions.tcc
+ *  This file is a GNU debug extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_DEBUG_FUNCTIONS_TCC
+#define _GLIBCXX_DEBUG_FUNCTIONS_TCC 1
+
+#include <bits/move.h>			// for __addressof and addressof
+#include <bits/stl_function.h>		// for less
+#if __cplusplus >= 201103L
+# include <type_traits>			// for is_lvalue_reference
+					// conditional.
+#endif
+
+namespace __gnu_debug
+{
+  /* Handle the case where __other is a pointer to _Sequence::value_type. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it,
+			    const typename _Sequence::value_type* __other)
+    {
+      typedef const typename _Sequence::value_type* _PointerType;
+      typedef std::less<_PointerType> _Less;
+#if __cplusplus >= 201103L
+      constexpr _Less __l{};
+#else
+      const _Less __l = _Less();
+#endif
+      const _Sequence* __seq = __it._M_get_sequence();
+      const _PointerType __begin = std::__addressof(*__seq->_M_base().begin());
+      const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1));
+
+      // Check whether __other points within the contiguous storage.
+      return __l(__other, __begin) || __l(__end, __other);
+    }
+
+  /* Fallback overload for when we can't tell, assume it is valid. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&, ...)
+    { return true; }
+
+  /* Handle sequences with contiguous storage */
+  template<typename _Iterator, typename _Sequence, typename _InputIterator>
+    inline bool
+    __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
+			    const _InputIterator& __other,
+			    const _InputIterator& __other_end,
+			    std::__true_type)
+    {
+      if (__other == __other_end)
+	return true;  // inserting nothing is safe even if not foreign iters
+      if (__it._M_get_sequence()->begin() == __it._M_get_sequence()->end())
+	return true;  // can't be self-inserting if self is empty
+      return __foreign_iterator_aux4(__it, std::__addressof(*__other));
+    }
+
+  /* Handle non-contiguous containers, assume it is valid. */
+  template<typename _Iterator, typename _Sequence, typename _InputIterator>
+    inline bool
+    __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>&,
+			    const _InputIterator&, const _InputIterator&,
+			    std::__false_type)
+    { return true; }
+
+  /** Handle debug iterators from the same type of container. */
+  template<typename _Iterator, typename _Sequence, typename _OtherIterator>
+    inline bool
+    __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
+		const _Safe_iterator<_OtherIterator, _Sequence>& __other,
+		const _Safe_iterator<_OtherIterator, _Sequence>&)
+    { return __it._M_get_sequence() != __other._M_get_sequence(); }
+
+  /** Handle debug iterators from different types of container. */
+  template<typename _Iterator, typename _Sequence, typename _OtherIterator,
+	   typename _OtherSequence>
+    inline bool
+    __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
+		const _Safe_iterator<_OtherIterator, _OtherSequence>&,
+		const _Safe_iterator<_OtherIterator, _OtherSequence>&)
+    { return true; }
+
+  /* Handle non-debug iterators. */
+  template<typename _Iterator, typename _Sequence, typename _InputIterator>
+    inline bool
+    __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
+			    const _InputIterator& __other,
+			    const _InputIterator& __other_end)
+    {
+#if __cplusplus < 201103L
+      typedef _Is_contiguous_sequence<_Sequence> __tag;
+#else
+      using __lvalref = std::is_lvalue_reference<
+	typename std::iterator_traits<_InputIterator>::reference>;
+      using __contiguous = _Is_contiguous_sequence<_Sequence>;
+      using __tag = typename std::conditional<__lvalref::value, __contiguous,
+					      std::__false_type>::type;
+#endif
+      return __foreign_iterator_aux3(__it, __other, __other_end, __tag());
+    }
+
+  /* Handle the case where we aren't really inserting a range after all */
+  template<typename _Iterator, typename _Sequence, typename _Integral>
+    inline bool
+    __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>&,
+			   _Integral, _Integral,
+			   std::__true_type)
+    { return true; }
+
+  /* Handle all iterators. */
+  template<typename _Iterator, typename _Sequence,
+	   typename _InputIterator>
+    inline bool
+    __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it,
+			   _InputIterator __other, _InputIterator __other_end,
+			   std::__false_type)
+    {
+      return _Insert_range_from_self_is_safe<_Sequence>::__value
+	     || __foreign_iterator_aux2(__it, __other, __other_end);
+    }
+
+  template<typename _Iterator, typename _Sequence,
+	   typename _InputIterator>
+    inline bool
+    __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it,
+		       _InputIterator __other, _InputIterator __other_end)
+    {
+      typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+      return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
+    }
+
+} // namespace __gnu_debug
+
+#endif
Index: include/debug/list
===================================================================
--- include/debug/list	(revision 219856)
+++ include/debug/list	(working copy)
@@ -797,4 +797,6 @@
 }
 #endif
 
+#include <debug/functions.tcc>
+
 #endif
Index: include/debug/safe_base.h
===================================================================
--- include/debug/safe_base.h	(revision 219856)
+++ include/debug/safe_base.h	(working copy)
@@ -159,6 +159,13 @@
     }
   };
 
+  /** Iterators that derive from _Safe_iterator_base can be determined singular
+   *  or non-singular.
+   **/
+  inline bool
+  __check_singular_aux(const _Safe_iterator_base* __x)
+  { return __x->_M_singular(); }
+
   /**
    * @brief Base class that supports tracking of iterators that
    * reference a sequence.
Index: include/debug/safe_iterator.h
===================================================================
--- include/debug/safe_iterator.h	(revision 219856)
+++ include/debug/safe_iterator.h	(working copy)
@@ -29,7 +29,7 @@
 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
 
-#include <debug/debug.h>
+#include <debug/assertions.h>
 #include <debug/macros.h>
 #include <debug/functions.h>
 #include <debug/safe_base.h>
@@ -55,13 +55,6 @@
 	{ return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
     };
 
-  /** Iterators that derive from _Safe_iterator_base can be determined singular
-   *  or non-singular.
-   **/
-  inline bool
-  __check_singular_aux(const _Safe_iterator_base* __x)
-  { return __x->_M_singular(); }
-
   /** The precision to which we can calculate the distance between
    *  two iterators.
    */
@@ -93,11 +86,7 @@
     inline std::pair<typename std::iterator_traits<_Iterator>::difference_type,
 		     _Distance_precision>
     __get_distance(const _Iterator& __lhs, const _Iterator& __rhs)
-    {
-      typedef typename std::iterator_traits<_Iterator>::iterator_category
-	  _Category;
-      return __get_distance(__lhs, __rhs, _Category());
-    }
+    { return __get_distance(__lhs, __rhs, std::__iterator_category(__lhs)); }
 
   /** \brief Safe iterator wrapper.
    *
@@ -768,6 +757,27 @@
     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
 	      const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
     { return __i + __n; }
+
+  /** Safe iterators know if they are dereferenceable. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
+    { return __x._M_dereferenceable(); }
+
+  /** Safe iterators know how to check if they form a valid range. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
+		  const _Safe_iterator<_Iterator, _Sequence>& __last)
+    { return __first._M_valid_range(__last); }
+
+  template<typename _Iterator, typename _Sequence>
+    struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
+    : std::__are_same<std::random_access_iterator_tag,
+                      typename std::iterator_traits<_Iterator>::
+		      iterator_category>
+    { };
+
 } // namespace __gnu_debug
 
 #include <debug/safe_iterator.tcc>
Index: include/debug/safe_local_iterator.h
===================================================================
--- include/debug/safe_local_iterator.h	(revision 219856)
+++ include/debug/safe_local_iterator.h	(working copy)
@@ -29,11 +29,7 @@
 #ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H
 #define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 1
 
-#include <debug/debug.h>
-#include <debug/macros.h>
-#include <debug/functions.h>
 #include <debug/safe_unordered_base.h>
-#include <ext/type_traits.h>
 
 namespace __gnu_debug
 {
@@ -432,6 +428,20 @@
 			    ._M_iterator(__rhs, "rhs"));
       return __lhs.base() != __rhs.base();
     }
+
+  /** Safe local iterators know if they are dereferenceable. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __check_dereferenceable(const _Safe_local_iterator<_Iterator,
+						       _Sequence>& __x)
+    { return __x._M_dereferenceable(); }
+
+  /** Safe local iterators know how to check if they form a valid range. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first,
+		  const _Safe_local_iterator<_Iterator, _Sequence>& __last)
+    { return __first._M_valid_range(__last); }
 } // namespace __gnu_debug
 
 #include <debug/safe_local_iterator.tcc>
Index: include/debug/safe_sequence.h
===================================================================
--- include/debug/safe_sequence.h	(revision 219856)
+++ include/debug/safe_sequence.h	(working copy)
@@ -29,7 +29,7 @@
 #ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H
 #define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1
 
-#include <debug/debug.h>
+#include <debug/assertions.h>
 #include <debug/macros.h>
 #include <debug/functions.h>
 #include <debug/safe_base.h>
@@ -36,9 +36,6 @@
 
 namespace __gnu_debug
 {
-  template<typename _Iterator, typename _Sequence>
-    class _Safe_iterator;
-
   /** A simple function object that returns true if the passed-in
    *  value is not equal to the stored value. It saves typing over
    *  using both bind1st and not_equal.
Index: include/debug/safe_unordered_container.h
===================================================================
--- include/debug/safe_unordered_container.h	(revision 219856)
+++ include/debug/safe_unordered_container.h	(working copy)
@@ -29,7 +29,7 @@
 #ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H
 #define _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H 1
 
-#include <debug/debug.h>
+#include <debug/assertions.h>
 #include <debug/macros.h>
 #include <debug/functions.h>
 #include <debug/safe_unordered_base.h>
Index: include/debug/string
===================================================================
--- include/debug/string	(revision 219856)
+++ include/debug/string	(working copy)
@@ -1158,4 +1158,6 @@
 
 } // namespace __gnu_debug
 
+#include <debug/functions.tcc>
+
 #endif
Index: include/debug/vector
===================================================================
--- include/debug/vector	(revision 219856)
+++ include/debug/vector	(working copy)
@@ -738,8 +738,7 @@
     {
       size_t
       operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
-      { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
-	  (__b._M_base()); }
+      { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); }
     };
 #endif
 
@@ -758,4 +757,6 @@
     { };
 }
 
+#include <debug/functions.tcc>
+
 #endif
Index: testsuite/23_containers/array/tuple_interface/get_debug_neg.cc
===================================================================
--- testsuite/23_containers/array/tuple_interface/get_debug_neg.cc	(revision 219856)
+++ testsuite/23_containers/array/tuple_interface/get_debug_neg.cc	(working copy)
@@ -28,6 +28,6 @@
 int n2 = std::get<1>(std::move(a));
 int n3 = std::get<1>(ca);
 
-// { dg-error "static assertion failed" "" { target *-*-* } 271 }
-// { dg-error "static assertion failed" "" { target *-*-* } 280 }
-// { dg-error "static assertion failed" "" { target *-*-* } 288 }
+// { dg-error "static assertion failed" "" { target *-*-* } 272 }
+// { dg-error "static assertion failed" "" { target *-*-* } 281 }
+// { dg-error "static assertion failed" "" { target *-*-* } 289 }
Index: testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc
===================================================================
--- testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc	(revision 219856)
+++ testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc	(working copy)
@@ -23,4 +23,4 @@
 
 typedef std::tuple_element<1, std::array<int, 1>>::type type;
 
-// { dg-error "static assertion failed" "" { target *-*-* } 305 }
+// { dg-error "static assertion failed" "" { target *-*-* } 306 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]