This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

The patch for std::list.


Same thing for std::list<>. The clear() issue.

The new test case has code written in a better fashion, so that new
containers can be added easily. I need some help in the test case where
the container's name needs to be determined from the template argument.


-- 
	-Dhruv Matani.
http://www.geocities.com/dhruvbird/


Attachment: changelog_13022004.dhruv
Description: Text document

Common subdirectories: ./cvs_libstdc++/include/bits/CVS and ./modified_cvs_libstdc++/include/bits/CVS
diff -Ncp ./cvs_libstdc++/include/bits/list.tcc ./modified_cvs_libstdc++/include/bits/list.tcc
*** ./cvs_libstdc++/include/bits/list.tcc	2004-02-09 18:23:06.000000000 +0530
--- ./modified_cvs_libstdc++/include/bits/list.tcc	2004-02-13 19:19:16.000000000 +0530
*************** namespace __gnu_norm
*** 69,76 ****
      _M_clear()
      {
        typedef _List_node<_Tp>  _Node;
!       _Node* __cur = static_cast<_Node*>(this->_M_node._M_next);
!       while (__cur != &this->_M_node)
        {
          _Node* __tmp = __cur;
          __cur = static_cast<_Node*>(__cur->_M_next);
--- 69,76 ----
      _M_clear()
      {
        typedef _List_node<_Tp>  _Node;
!       _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next);
!       while (__cur != &this->_M_impl._M_node)
        {
          _Node* __tmp = __cur;
          __cur = static_cast<_Node*>(__cur->_M_next);
*************** namespace __gnu_norm
*** 237,244 ****
      sort()
      {
        // Do nothing if the list has length 0 or 1.
!       if (this->_M_node._M_next != &this->_M_node
! 	  && this->_M_node._M_next->_M_next != &this->_M_node)
        {
          list __carry;
          list __tmp[64];
--- 237,244 ----
      sort()
      {
        // Do nothing if the list has length 0 or 1.
!       if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
! 	  && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
        {
          list __carry;
          list __tmp[64];
*************** namespace __gnu_norm
*** 341,348 ****
        sort(_StrictWeakOrdering __comp)
        {
  	// Do nothing if the list has length 0 or 1.
! 	if (this->_M_node._M_next != &this->_M_node
! 	    && this->_M_node._M_next->_M_next != &this->_M_node)
  	  {
  	    list __carry;
  	    list __tmp[64];
--- 341,348 ----
        sort(_StrictWeakOrdering __comp)
        {
  	// Do nothing if the list has length 0 or 1.
! 	if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
! 	    && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  	  {
  	    list __carry;
  	    list __tmp[64];
diff -Ncp ./cvs_libstdc++/include/bits/stl_list.h ./modified_cvs_libstdc++/include/bits/stl_list.h
*** ./cvs_libstdc++/include/bits/stl_list.h	2004-02-09 18:23:09.000000000 +0530
--- ./modified_cvs_libstdc++/include/bits/stl_list.h	2004-02-13 19:18:36.000000000 +0530
*************** namespace __gnu_norm
*** 275,281 ****
    */
    template<typename _Tp, typename _Alloc>
      class _List_base
-     : public _Alloc::template rebind<_List_node<_Tp> >::other
      {
      protected:
        // NOTA BENE
--- 275,280 ----
*************** namespace __gnu_norm
*** 295,319 ****
  
        _Node_Alloc_type;
  
!       _List_node_base _M_node;
  
        _List_node<_Tp>*
        _M_get_node()
!       { return _Node_Alloc_type::allocate(1); }
! 
        void
        _M_put_node(_List_node<_Tp>* __p)
!       { _Node_Alloc_type::deallocate(__p, 1); }
! 
    public:
        typedef _Alloc allocator_type;
  
        allocator_type
        get_allocator() const
!       { return allocator_type(*static_cast<const _Node_Alloc_type*>(this)); }
  
        _List_base(const allocator_type& __a)
!       : _Node_Alloc_type(__a)
        { _M_init(); }
  
        // This is what actually destroys the list.
--- 294,324 ----
  
        _Node_Alloc_type;
  
!       struct _List_impl : public _Node_Alloc_type {
! 	_List_node_base _M_node;
! 	_List_impl (const _Node_Alloc_type& __a)
! 	  : _Node_Alloc_type(__a) { }
!       };
! 
!       _List_impl _M_impl;
  
        _List_node<_Tp>*
        _M_get_node()
!       { return _M_impl._Node_Alloc_type::allocate(1); }
!       
        void
        _M_put_node(_List_node<_Tp>* __p)
!       { _M_impl._Node_Alloc_type::deallocate(__p, 1); }
!       
    public:
        typedef _Alloc allocator_type;
  
        allocator_type
        get_allocator() const
!       { return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); }
  
        _List_base(const allocator_type& __a)
! 	: _M_impl(__a)
        { _M_init(); }
  
        // This is what actually destroys the list.
*************** namespace __gnu_norm
*** 326,333 ****
        void
        _M_init()
        {
!         this->_M_node._M_next = &this->_M_node;
!         this->_M_node._M_prev = &this->_M_node;
        }
      };
  
--- 331,338 ----
        void
        _M_init()
        {
!         this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
!         this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
        }
      };
  
*************** namespace __gnu_norm
*** 409,415 ****
         *  will also be included, accumulated from the topmost parent.
         *  @endif
         */
!       using _Base::_M_node;
        using _Base::_M_put_node;
        using _Base::_M_get_node;
  
--- 414,420 ----
         *  will also be included, accumulated from the topmost parent.
         *  @endif
         */
!       using _Base::_M_impl;
        using _Base::_M_put_node;
        using _Base::_M_get_node;
  
*************** namespace __gnu_norm
*** 588,594 ****
         */
        iterator
        begin()
!       { return this->_M_node._M_next; }
  
        /**
         *  Returns a read-only (constant) iterator that points to the
--- 593,599 ----
         */
        iterator
        begin()
!       { return this->_M_impl._M_node._M_next; }
  
        /**
         *  Returns a read-only (constant) iterator that points to the
*************** namespace __gnu_norm
*** 597,603 ****
         */
        const_iterator
        begin() const
!       { return this->_M_node._M_next; }
  
        /**
         *  Returns a read/write iterator that points one past the last
--- 602,608 ----
         */
        const_iterator
        begin() const
!       { return this->_M_impl._M_node._M_next; }
  
        /**
         *  Returns a read/write iterator that points one past the last
*************** namespace __gnu_norm
*** 605,611 ****
         *  order.
         */
        iterator
!       end() { return &this->_M_node; }
  
        /**
         *  Returns a read-only (constant) iterator that points one past
--- 610,616 ----
         *  order.
         */
        iterator
!       end() { return &this->_M_impl._M_node; }
  
        /**
         *  Returns a read-only (constant) iterator that points one past
*************** namespace __gnu_norm
*** 614,620 ****
         */
        const_iterator
        end() const
!       { return &this->_M_node; }
  
        /**
         *  Returns a read/write reverse iterator that points to the last
--- 619,625 ----
         */
        const_iterator
        end() const
!       { return &this->_M_impl._M_node; }
  
        /**
         *  Returns a read/write reverse iterator that points to the last
*************** namespace __gnu_norm
*** 659,665 ****
         */
        bool
        empty() const
!       { return this->_M_node._M_next == &this->_M_node; }
  
        /**  Returns the number of elements in the %list.  */
        size_type
--- 664,670 ----
         */
        bool
        empty() const
!       { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; }
  
        /**  Returns the number of elements in the %list.  */
        size_type
*************** namespace __gnu_norm
*** 788,794 ****
         */
        void
        pop_back()
!       { this->_M_erase(this->_M_node._M_prev); }
  
        /**
         *  @brief  Inserts given value into %list before specified iterator.
--- 793,799 ----
         */
        void
        pop_back()
!       { this->_M_erase(this->_M_impl._M_node._M_prev); }
  
        /**
         *  @brief  Inserts given value into %list before specified iterator.
*************** namespace __gnu_norm
*** 901,907 ****
         */
        void
        swap(list& __x)
!       { _List_node_base::swap(this->_M_node,__x._M_node); }
  
        /**
         *  Erases all the elements.  Note that this function only erases
--- 906,912 ----
         */
        void
        swap(list& __x)
!       { _List_node_base::swap(this->_M_impl._M_node,__x._M_impl._M_node); }
  
        /**
         *  Erases all the elements.  Note that this function only erases
*************** namespace __gnu_norm
*** 1064,1070 ****
         */
        void
        reverse()
!       { this->_M_node.reverse(); }
  
        /**
         *  @brief  Sort the elements.
--- 1069,1075 ----
         */
        void
        reverse()
!       { this->_M_impl._M_node.reverse(); }
  
        /**
         *  @brief  Sort the elements.
#include <vector>
#include <deque>
#include <list>
#include <algorithm>
#include <iostream>
#include <ext/new_allocator.h>
using namespace std;
using __gnu_cxx::new_allocator;

#define SHOW_DEBUG_MSG
#define CHECK_VECTOR
#define CHECK_DEQUE
#define CHECK_LIST

template <typename T>
class Whacky_Alloc : public new_allocator<T> {
  Whacky_Alloc& operator= (Whacky_Alloc const&);

public:

  template <typename T1>
  struct rebind {
    typedef Whacky_Alloc<T1> other;
  };

  virtual void clear ()
  {
#if defined SHOW_DEBUG_MSG
    cout<<"In Whacky_Alloc::clear()"<<endl;
#endif
  }

  Whacky_Alloc ()
  {
#if defined SHOW_DEBUG_MSG
    cout<<"In ctor"<<endl;
#endif
  }

  Whacky_Alloc (Whacky_Alloc const& _wa)
  {
#if defined SHOW_DEBUG_MSG
    cout<<"In copy ctor"<<endl;
#endif
  }

  template <typename T1>
  Whacky_Alloc (Whacky_Alloc<T1> const& _wa)
  {
#if defined SHOW_DEBUG_MSG
    cout<<"In templated copy ctor"<<endl;
#endif
  }

  virtual ~Whacky_Alloc ()
  {
#if defined SHOW_DEBUG_MSG
    cout<<"Calling My Clear -> Next Line Should be Whacky_Alloc::clear()"<<endl;
#endif
    this->clear();
  }

  T *allocate (typename new_allocator<T>::size_type n, const void *hint = 0)
  {
#if defined SHOW_DEBUG_MSG
    cout<<"Call Clear Now! Next Line should be blank which is wrong behaviour."<<endl;
#endif
    this->clear();
#if defined SHOW_DEBUG_MSG
    cout<<"\nAfter Clear"<<endl;
#endif
    return new_allocator<T>::allocate(n, hint);
  }

  void deallocate (T *ptr, typename new_allocator<T>::size_type n)
  {
#if defined SHOW_DEBUG_MSG
    cout<<"Call Clear Now! Next Line should be blank which is wrong behaviour."<<endl;
#endif
    this->clear();
#if defined SHOW_DEBUG_MSG
    cout<<"\nAfter Clear"<<endl;
#endif
    new_allocator<T>::deallocate (ptr, n);
  }
};

template <typename Container>
void Check_Container ()
{
  Container *pic = new Container;
  int x = 230;
  
  while (x--)
    {
      pic->push_back (x);
#if defined SHOW_DEBUG_MSG
      cout<<"Size of ABI_MAGIC_HERE is: "<<pic->size()<<endl;
#endif
    }

  pic->get_allocator();

  //The following should lead to Inifinite mutual function calling in
  //the current (older) implementation.
#if defined SHOW_DEBUG_MSG
  cout<<"CALLING CLEAR!"<<endl;
#endif

  pic->clear();
#if defined SHOW_DEBUG_MSG
  cout<<"CLEAR CALLED!"<<endl;
#endif
  delete pic;
}


int main()
{
#if defined CHECK_VECTOR 
  Check_Container<std::vector<int, Whacky_Alloc<int> > >();
#endif

#if defined CHECK_DEQUE
  Check_Container<std::deque<int, Whacky_Alloc<int> > >();
#endif

#if defined CHECK_LIST
  Check_Container<std::list<int, Whacky_Alloc<int> > >();
#endif
}

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