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]

[Patch] PR11504: -Wcast-qual and general constness issues with stl_tree.h


Please find attached a patch which will solve PR11504 as well as fix other constness issues with stl_tree.h. I have also gotten rid of C-style casts and replaced them with the appropriate C++-style casts.

There is only one const_cast required. This is because the const and non-const iterators both inherit from _Rb_tree_base_iterator which has a non-const data member (_M_node). Still, this is much better than before since the old C-style casts were often casting away constness.

Still there are two things I'm not too happy about - maybe someone can help out:

  1. I do not like the lack of symmetry with the casts for const vs.
     non-const functions.
     Non-const versions often require a reinterpret_cast whereas const
     versions can use static_cast.
  2. The "const" typedefs.
     Why do I have to define "const" versions of the typedefs?
     If I have "typedef _Rb_tree_node* _Link_type;" then why can't I
     use "const _Link_type" instead of having to define an explicit
     const typedef like "typedef const _Rb_tree_node* _const_Link_type;"?

Anyway, this patch has been tested on i686-pc-linux-gnu with std::set, std::multiset, std::map and std::multimap including the debug __rb_verify() function.

Cheers,


Gawain


--
Gawain Bolton
Coignieres, France
PGP Info: Key server: http://wwwkeys.pgp.net
         Key id: 6EBEDEA6
         Fingerprint: 65C0 0030 21D1 7A01 546A  E7DB D60F 47E0 6EBE DEA6

Index: stl_tree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/stl_tree.h,v
retrieving revision 1.27
diff -u -r1.27 stl_tree.h
--- stl_tree.h	14 Jul 2003 02:52:04 -0000	1.27
+++ stl_tree.h	24 Jul 2003 19:28:43 -0000
@@ -95,6 +95,7 @@
   struct _Rb_tree_node_base
   {
     typedef _Rb_tree_node_base* _Base_ptr;
+    typedef const _Rb_tree_node_base* _const_Base_ptr;
     
     _Rb_tree_color 	_M_color; 
     _Base_ptr 		_M_parent;
@@ -108,12 +109,26 @@
       return __x;
     }
 
+    static _const_Base_ptr
+    _S_minimum(_const_Base_ptr __x)
+    {
+      while (__x->_M_left != 0) __x = __x->_M_left;
+      return __x;
+    }
+
     static _Base_ptr 
     _S_maximum(_Base_ptr __x)
     {
       while (__x->_M_right != 0) __x = __x->_M_right;
       return __x;
     }
+
+    static _const_Base_ptr
+    _S_maximum(_const_Base_ptr __x)
+    {
+      while (__x->_M_right != 0) __x = __x->_M_right;
+      return __x;
+    }
   };
 
   template<typename _Val>
@@ -149,13 +164,15 @@
       const_iterator;
       typedef _Rb_tree_iterator<_Val, _Ref, _Ptr> _Self;
       typedef _Rb_tree_node<_Val>* _Link_type;
+      typedef const _Rb_tree_node<_Val>* _const_Link_type;
       
       _Rb_tree_iterator() {}
-      _Rb_tree_iterator(_Rb_tree_node_base* __x) { _M_node = __x; }
+      _Rb_tree_iterator(_Link_type __x) { _M_node = __x; }
+      _Rb_tree_iterator(_const_Link_type __x) { _M_node = const_cast<_Link_type>(__x); }
       _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; }
 
       reference 
-      operator*() const { return _Link_type(_M_node)->_M_value_field; }
+      operator*() const { return static_cast<_Link_type>(_M_node)->_M_value_field; }
 
       pointer 
       operator->() const { return &(operator*()); }
@@ -312,6 +329,7 @@
       
     protected:
       typedef _Rb_tree_node_base* _Base_ptr;
+      typedef const _Rb_tree_node_base* _const_Base_ptr;
       typedef _Rb_tree_node<_Val> _Rb_tree_node;
       
     public:
@@ -322,6 +340,7 @@
       typedef value_type& reference;
       typedef const value_type& const_reference;
       typedef _Rb_tree_node* _Link_type;
+      typedef const _Rb_tree_node* _const_Link_type;
       typedef size_t size_type;
       typedef ptrdiff_t difference_type;
       
@@ -348,7 +367,7 @@
       }
       
       _Link_type 
-      _M_clone_node(_Link_type __x)
+      _M_clone_node(_const_Link_type __x)
       {
 	_Link_type __tmp = _M_create_node(__x->_M_value_field);
 	__tmp->_M_color = __x->_M_color;
@@ -368,57 +387,92 @@
       _Compare _M_key_compare;
 
       _Link_type& 
-      _M_root() const { return (_Link_type&) this->_M_header._M_parent; }
+      _M_root() { return reinterpret_cast<_Link_type&>(this->_M_header._M_parent); }
+
+      _const_Link_type
+      _M_root() const { return static_cast<_const_Link_type>(this->_M_header._M_parent); }
 
       _Link_type& 
-      _M_leftmost() const { return (_Link_type&) this->_M_header._M_left; }
+      _M_leftmost() { return reinterpret_cast<_Link_type&>(this->_M_header._M_left); }
+
+      _const_Link_type
+      _M_leftmost() const { return static_cast<_const_Link_type>(this->_M_header._M_left); }
 
       _Link_type& 
-      _M_rightmost() const { return (_Link_type&) this->_M_header._M_right; }
+      _M_rightmost() { return reinterpret_cast<_Link_type&>(this->_M_header._M_right); }
 
-      _Link_type
-      _M_end() const { return (_Link_type) &this->_M_header; }
+      _const_Link_type
+      _M_rightmost() const { return static_cast<_const_Link_type>(this->_M_header._M_right); }
+
+      _const_Link_type
+      _M_end() const { return static_cast<_const_Link_type>(&this->_M_header); }
       
-      static _Link_type& 
-      _S_left(_Link_type __x) { return (_Link_type&)(__x->_M_left); }
+      _Link_type
+      _M_end() { return static_cast<_Link_type>(&this->_M_header); }
+
+      static _Link_type&
+      _S_left(_Link_type __x) { return reinterpret_cast<_Link_type&>(__x->_M_left); }
+
+      static _const_Link_type
+      _S_left(_const_Link_type __x) { return static_cast<_const_Link_type>(__x->_M_left); }
 
       static _Link_type& 
-      _S_right(_Link_type __x) { return (_Link_type&)(__x->_M_right); }
+      _S_right(_Link_type __x) { return reinterpret_cast<_Link_type&>(__x->_M_right); }
+
+      static _const_Link_type
+      _S_right(_const_Link_type __x) { return static_cast<_const_Link_type>(__x->_M_right); }
 
       static _Link_type& 
-      _S_parent(_Link_type __x) { return (_Link_type&)(__x->_M_parent); }
+      _S_parent(_Link_type __x) { return reinterpret_cast<_Link_type&>(__x->_M_parent); }
 
       static reference 
       _S_value(_Link_type __x) { return __x->_M_value_field; }
 
+      static const_reference 
+      _S_value(_const_Link_type __x) { return __x->_M_value_field; }
+
       static const _Key& 
       _S_key(_Link_type __x) { return _KeyOfValue()(_S_value(__x)); }
 
+      static const _Key& 
+      _S_key(_const_Link_type __x) { return _KeyOfValue()(_S_value(__x)); }
+
       static _Link_type& 
-      _S_left(_Base_ptr __x) { return (_Link_type&)(__x->_M_left); }
+      _S_left(_Base_ptr __x) { return reinterpret_cast<_Link_type&>(__x->_M_left); }
 
       static _Link_type& 
-      _S_right(_Base_ptr __x) { return (_Link_type&)(__x->_M_right); }
+      _S_right(_Base_ptr __x) { return reinterpret_cast<_Link_type&>(__x->_M_right); }
 
       static _Link_type& 
-      _S_parent(_Base_ptr __x) { return (_Link_type&)(__x->_M_parent); }
+      _S_parent(_Base_ptr __x) { return reinterpret_cast<_Link_type&>(__x->_M_parent); }
 
       static reference 
-      _S_value(_Base_ptr __x) { return ((_Link_type)__x)->_M_value_field; }
+      _S_value(_Base_ptr __x) { return static_cast<_Link_type>(__x)->_M_value_field; }
 
       static const _Key& 
       _S_key(_Base_ptr __x) { return _KeyOfValue()(_S_value(_Link_type(__x)));} 
 
+      static const _Key& 
+      _S_key(_const_Base_ptr __x) { return _KeyOfValue()(_S_value(_const_Link_type(__x)));} 
+
       static _Rb_tree_color&
       _S_color(_Base_ptr __x) { return __x->_M_color; }
 
       static _Link_type 
       _S_minimum(_Link_type __x) 
-      { return (_Link_type)  _Rb_tree_node_base::_S_minimum(__x); }
+      { return static_cast<_Link_type>(_Rb_tree_node_base::_S_minimum(__x)); }
+
+      static _const_Link_type 
+      _S_minimum(_const_Link_type __x)
+      { return static_cast<_const_Link_type>(_Rb_tree_node_base::_S_minimum(__x)); }
 
       static _Link_type 
       _S_maximum(_Link_type __x)
-      { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); }
+      { return static_cast<_Link_type>(_Rb_tree_node_base::_S_maximum(__x)); }
+
+      static _const_Link_type 
+      _S_maximum(_const_Link_type __x)
+      { return static_cast<_const_Link_type>(_Rb_tree_node_base::_S_maximum(__x)); }
 
     public:
       typedef _Rb_tree_iterator<value_type, reference, pointer> iterator;
@@ -433,7 +487,7 @@
       _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
 
       _Link_type 
-      _M_copy(_Link_type __x, _Link_type __p);
+      _M_copy(_const_Link_type __x, _Link_type __p);
 
       void 
       _M_erase(_Link_type __x);
@@ -495,10 +549,10 @@
       begin() const { return _M_leftmost(); }
 
       iterator 
-      end() { return &this->_M_header; }
+      end() { return static_cast<_Link_type>(&this->_M_header); }
 
       const_iterator
-      end() const { return const_cast<_Base_ptr>(&this->_M_header); }
+      end() const { return static_cast<_const_Link_type>(&this->_M_header); }
 
       reverse_iterator 
       rbegin() { return reverse_iterator(end()); }
@@ -693,8 +747,8 @@
     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
     _M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Val& __v)
     {
-      _Link_type __x = (_Link_type) __x_;
-      _Link_type __y = (_Link_type) __y_;
+      _Link_type __x = static_cast<_Link_type>(__x_);
+      _Link_type __y = static_cast<_Link_type>(__y_);
       _Link_type __z;
       
       if (__y == &this->_M_header || __x != 0 || 
@@ -930,8 +984,8 @@
     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position)
     {
       _Link_type __y = 
-	(_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node,
-						  this->_M_header);
+	static_cast<_Link_type>(_Rb_tree_rebalance_for_erase(__position._M_node,
+							     this->_M_header));
       destroy_node(__y);
       --_M_node_count;
     }
@@ -951,7 +1005,7 @@
            typename _Compare, typename _Alloc>
     typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type 
     _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>::
-    _M_copy(_Link_type __x, _Link_type __p)
+    _M_copy(_const_Link_type __x, _Link_type __p)
     {
       // Structural copy.  __x and __p must be non-null.
       _Link_type __top = _M_clone_node(__x);
@@ -1045,8 +1099,8 @@
     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
     find(const _Key& __k) const
     {
-      _Link_type __y = _M_end(); // Last node which is not less than __k. 
-      _Link_type __x = _M_root(); // Current node. 
+      _const_Link_type __y = _M_end(); // Last node which is not less than __k. 
+      _const_Link_type __x = _M_root(); // Current node. 
  
      while (__x != 0) 
        {
@@ -1095,8 +1149,8 @@
     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
     lower_bound(const _Key& __k) const
     {
-      _Link_type __y = _M_end(); // Last node which is not less than __k.
-      _Link_type __x = _M_root(); // Current node.
+      _const_Link_type __y = _M_end(); // Last node which is not less than __k.
+      _const_Link_type __x = _M_root(); // Current node.
       
       while (__x != 0) 
 	if (!_M_key_compare(_S_key(__x), __k))
@@ -1131,8 +1185,8 @@
     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
     upper_bound(const _Key& __k) const
     {
-      _Link_type __y = _M_end(); // Last node which is greater than __k.
-      _Link_type __x = _M_root(); // Current node.
+      _const_Link_type __y = _M_end(); // Last node which is greater than __k.
+      _const_Link_type __x = _M_root(); // Current node.
       
       while (__x != 0) 
 	if (_M_key_compare(__k, _S_key(__x)))
@@ -1165,7 +1219,8 @@
   }
 
   inline int
-  __black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root)
+  __black_count(const _Rb_tree_node_base* __node,
+                const _Rb_tree_node_base* __root)
   {
     if (__node == 0)
       return 0;
@@ -1195,9 +1250,9 @@
     int __len = __black_count(_M_leftmost(), _M_root());
     for (const_iterator __it = begin(); __it != end(); ++__it) 
       {
-	_Link_type __x = (_Link_type) __it._M_node;
-	_Link_type __L = _S_left(__x);
-	_Link_type __R = _S_right(__x);
+	_const_Link_type __x = static_cast<_Link_type>(__it._M_node);
+	_const_Link_type __L = _S_left(__x);
+	_const_Link_type __R = _S_right(__x);
 	
 	if (__x->_M_color == _S_red)
 	  if ((__L && __L->_M_color == _S_red) 

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