高性能的LIST

我们经常要用到std::list,大多数情况下,它也够好用了。可是如果你对性能很吝求,很在乎它在每次加入节点时分配点内存,那我推荐你用下面的类。


单向的LIST

/*********************************************************************
** Copyright (C) 2003 Terabit Pty Ltd.  All rights reserved.
**
** This file is part of the POSIX-Proactor module.
**
**  
**   
**
**
**
** @author Alexander Libman <libman@terabit.com.au>
**
**********************************************************************/

#ifndef TERABIT_SINGLE_LIST_T_H
#define TERABIT_SINGLE_LIST_T_H

# pragma once

#include <functional>
#include <algorithm>

template <typename X> class LinkS_T;
template <typename X> class LinkD_T;

template <typename X, typename F> class Single_List_T;
template <typename X, typename F> class Single_Queue_T;
template <typename X, typename F> class Double_List_T;

//============================================================
//
//
//============================================================
template <typename X> 
class LinkS_T
{
private:
 
    template <typename > friend class LinkD_T;
    template <typename , typename > friend class Single_List_T;
    template <typename , typename > friend class Single_Queue_T;
    template <typename , typename > friend class Double_List_T;

public:
   
    static X * end ();
    
    ~LinkS_T () {}
    LinkS_T () : ptr_ (0) {}

    X * get() const { return ptr_;}
    X * operator-> () const { return ptr_;}

    bool is_free () const { return ptr_ == 0; }
    bool is_end () const  { return ptr_ == end (); }


private:
    void set (X * x)   
    { 
         //assert (x != 0);
         ptr_ = x;
    }

    void set_free ()   { ptr_ = 0; }
    void set_end  ()   { ptr_ = end ();} 



    LinkS_T (X * x) : ptr_ (x) {}

    X * ptr_;
};

template <typename X> 
inline X * 
LinkS_T<X>::end () 
{ 
    return (X*) (-1L);
}

//------------------------------------------------------------
// class that converts X reference to LinkS_T<X> reference
//------------------------------------------------------------

template <class X> 
class LinkS_Functor_T :  public std::unary_function < X, LinkS_T <X> > 
{
public :
    LinkS_T <X> *  operator ()( const X * x )  const 
    {
        return  const_cast < X* > (x);
    }
};

//============================================================
//
//
//============================================================

template < class X, class F = LinkS_Functor_T <X> >
class Single_List_T 
{
public: 
    typedef Single_List_T<X,F> List;
    typedef LinkS_T<X>         Link;

    class iterator 
    {
        friend class  Single_List_T<X,F>;

        iterator(X * x) : x_ (x)  {;}
        iterator(const Link & link) : x_ (link.get())  {;}
 
    public:
        ~iterator () {}

        iterator () : x_ (0) {;}

        iterator(const iterator & other ) 
        : x_ (other.x_)
        {;}


        iterator & operator = (const iterator & other )
        {
            x_ = other.x_;
            return *this;
        }

        bool operator == (const iterator & other )const
        {
            return (x_ == other.x_ );
        }

        bool operator != (const iterator & other )const
        {
            return (x_ != other.x_ );
        }

        iterator & operator ++ ();
        iterator operator ++ (int);

        operator X *   () const { return x_; }
        X * operator * () const { return x_; }

   
    private:
   
        X *    x_;
    };

    Single_List_T () : head_ (Link::end())
    {}

    bool empty () const  { return head_.is_end(); }
    size_t size() const;

    void push_front (X * x);
    void push_back  (X * x);

    X * pop_front ();
    X * pop_back  ();

    X * front ();
    X * back  ();

    X * find (X *x);
    X * remove (X *x);


    iterator begin() const { return iterator (head_);}
    iterator end ()  const { return iterator (Link::end());}

    void swap   (Single_List_T<X, F>  & other);

    template < class Other_List_T >
    void splice (Other_List_T  & other);

private:
    friend class iterator;
            
    /// Protect from copy and assignment
    Single_List_T  (const Single_List_T<X, F>  & other);
    Single_List_T & operator= (const Single_List_T <X, F> & other);

    // functor that converts object pointer to link pointer
    // does it make sense to have non-static converter ??
    static Link * get_link (const X * x);

    static X *    get_next (const X * x);


    Link          head_;
};

//-----------------------------------------------------
//   Single_List_T::iterator
//-----------------------------------------------------
template <class X, class F>
inline typename Single_List_T<X,F>::iterator &
Single_List_T<X,F>::iterator::operator ++()
{
    // behavior unpredictable if iterator not valid
    this->x_ =  Single_List_T<X,F>::get_next (this->x_);
    return *this;
}
   
template <class X, class F>
inline typename Single_List_T<X,F>::iterator 
Single_List_T<X,F>::iterator::operator ++(int)
{
    // behavior unpredictable if iterator not valid
    iterator itr (*this);
    ++(*this);
    return itr;
}
 
//-----------------------------------------------------
//    Single_List_T
//-----------------------------------------------------

template <class X, class F>
inline typename Single_List_T<X,F>::Link * 
Single_List_T<X,F>::get_link (const X * x)
{
    assert (x != 0 &&  x != Link::end() );
    static F funcObj2Link;
    return funcObj2Link (x);
}

template <class X, class F>
inline X * 
Single_List_T<X,F>::get_next (const X * x)
{
    return get_link (x)->get ();
}


template <class X, class F>
inline void
Single_List_T<X,F>::push_front (X * x)
{
    //assert (x != 0 && x != Link::end() && head_.get() != 0);

    Link * link = get_link (x);
    assert (link->is_free());

    link->set (head_.get());
    head_.set (x);
}

template <class X, class F>
inline void
Single_List_T<X,F>::push_back (X * x) 
{
    //assert (x != 0 && x != Link::end() && head_.get() != 0);

    Link * link = get_link (x);
    assert (link->is_free());

    Link * linkLast = &head_;

    while (!linkLast->is_end())
    {
        linkLast = get_link (linkLast->get());
    }

    linkLast->set (x);
    link->set_end ();
}

template <class X, class F>
inline X *
Single_List_T<X,F>::front ()
{
    X * x = head_.get();

    if (x != Link::end())
    {
        return x;
    }
    return  0;
}

template <class X, class F>
inline X *
Single_List_T<X,F>::back ()
{
    X * x = 0;
    
    iterator it1 = begin();
    iterator it2 = end();

    for (; it1 !=it2 ; ++it1)
    {
        x = *it1;
    }
    return x;
}

template <class X, class F>
inline size_t
Single_List_T<X,F>::size () const
{
    size_t count =0;
    iterator it1 = begin();
    iterator it2 = end();

    for (; it1 !=it2 ; ++count, ++it1)
    {
    }

    return count;
}

template <class X, class F>
inline X *
Single_List_T<X,F>::pop_front ()
{
    X * x = head_.get();

    if (x == Link::end ())
    {
        return 0;
    }

    //assert (x != 0 );
    //assert (this->get_next (x) != 0);

    head_.set (this->get_next(x));
    this->get_link(x)->set_free();

    assert (head_.get() != 0);
    return x;
}

template <class X, class F>
inline X *
Single_List_T<X,F>::pop_back ()
{
    X * x = 0;
    Link * prevLink = &head_;
    if (prevLink->is_end ())
    {
        return x;
    }

    for (;;)
    {
        x = prevLink->get ();
        Link * nextLink = this->get_link (x);
        if (nextLink->is_end ())
        {
            break;
        }
        prevLink = nextLink;
    }
    prevLink->set_end ();
    get_link(x)->set_free();

    //assert (x != 0 && x != Link::end() && head_.get() != 0);
    return x;
}

template <class X, class F>
inline void
Single_List_T<X,F>::swap (Single_List_T<X,F>  & other)
{
    if (&other == this)
        return;

    std::swap (head_, other.head_);
}

template <class X, class F>
inline X *
Single_List_T<X,F>::find (X *x)
{
  if (x == 0)
    return 0;
  
  iterator it1 = begin();
  iterator it2 = end();

  for (; it1 != it2 ; ++it1)
    {
      if (x == *it1)
        return x;
    }

    return 0;
}

template <class X, class F>
inline X *
Single_List_T<X,F>::remove (X *x)
{
  if (x == 0)
    return 0;
  
  Link * link_x = get_link (x);
  Link * link_cur = &this->head_;

  for (;;)
    {
      X *next = link_cur->get ();

      if (next == Link::end())
        break; // not found

      if (next == x)
        {
          link_cur->set (link_x->get ());
          link_x->set_free ();
          return x;
        }
      link_cur = get_link (next);
    }
  return 0;
}

template < class X, class F >
template < class Other_List_T >
inline void
Single_List_T<X,F>::splice (Other_List_T & other)
{
    X * x = other.front ();
    if (x == 0)
        return;

    Link * linkLast = &head_;

    if (linkLast->get() == x)
    {
        return; // the same
    }

    while(!linkLast->is_end())
    {
        linkLast = get_link (linkLast->get());
    }

    linkLast->set (x);

    Other_List_T tmp;
    tmp.swap (other);

    //other.head_.set_end();
}


//============================================================
//
//
//============================================================

template <class X, class F = LinkS_Functor_T <X> >
class Single_Queue_T 
{
public: 
    typedef Single_Queue_T<X,F> Queue;
    typedef LinkS_T<X>          Link;

    class iterator 
    {
        friend class Single_Queue_T<X,F>;

        iterator(X * x) : x_ (x)  {;}
        iterator(const Link & link) : x_ (link.get())  {;}
 
    public:
        ~iterator () {}

        iterator () : x_ (0) {;}

        iterator(const iterator & other ) 
        : x_ (other.x_)
        {;}


        iterator & operator = (const iterator & other )
        {
            x_ = other.x_;
            return *this;
        }

        bool operator == (const iterator & other )const
        {
            return (x_ == other.x_ );
        }

        bool operator != (const iterator & other )const
        {
            return (x_ != other.x_ );
        }

        iterator & operator ++ ();
        iterator operator ++ (int);

        operator X *   () const { return x_; }
        X * operator * () const { return x_; }

   
    private:
   
        X *    x_;
    };

    Single_Queue_T () 
        : head_ (Link::end())
        , tail_ (Link::end())
        , size_ (0)
    {}

    bool empty () const  { return (size_ == 0); }
    size_t size() const  { return size_;}

    void push_front (X * x);
    void push_back  (X * x);

    X * pop_front ();
    X * pop_back  ();

    X * front ();
    X * back  ();

    X * find (X *x);
    X * remove (X *x);

    void swap   (Single_Queue_T<X, F>  & other);

    template < class Other_List_T >
    void splice (Other_List_T  & other);

    iterator begin() const { return iterator (head_);}
    iterator end ()  const { return iterator (Link::end());}

private:
    friend class iterator;
            
    /// Protect from copy and assignment
    Single_Queue_T  (const Single_Queue_T<X, F>  & other);
    Single_Queue_T & operator= (const Single_Queue_T <X, F> & other);

    // functor that converts object pointer to link pointer
    // does it make sense to have non-static converter ??
    static Link * get_link (const X * x);

    static X *    get_next (const X * x);


    Link    head_;
    Link    tail_; 
    size_t  size_;
};

//-----------------------------------------------------
//   Single_Queue_T::iterator
//-----------------------------------------------------
template <class X, class F>
inline typename Single_Queue_T<X,F>::iterator &
Single_Queue_T<X,F>::iterator::operator ++()
{
    // behavior unpredictable if iterator not valid
    x_ =  Single_Queue_T<X,F>::get_next (x_);
    return *this;
}
   
template <class X, class F>
inline typename Single_Queue_T<X,F>::iterator 
Single_Queue_T<X,F>::iterator::operator ++(int)
{
    // behavior unpredictable if iterator not valid
    iterator itr (*this);
    ++(*this);
    return itr;
}
 
//-----------------------------------------------------
//    Single_Queue_T
//-----------------------------------------------------

template <class X, class F>
inline typename Single_Queue_T<X,F>::Link * 
Single_Queue_T<X,F>::get_link (const X * x)
{
    assert (x != 0 &&  x != Link::end() );
    static F funcObj2Link;
    return funcObj2Link (x);
}

template <class X, class F>
inline X * 
Single_Queue_T<X,F>::get_next (const X * x)
{
    return get_link (x)->get ();
}


template <class X, class F>
inline void
Single_Queue_T<X,F>::push_front (X * x)
{
    //assert (x != 0 && x != Link::end() && head_.get() != 0);

    Link * link = get_link (x);
    assert (link->is_free());

    link->set (head_.get());
    head_.set (x);
    if (size_ == 0)
    {
        tail_ = head_;
    }
    ++size_;
}

template <class X, class F>
inline void
Single_Queue_T<X,F>::push_back (X * x) 
{
    //assert (x != 0 && x != Link::end() && head_.get() != 0);

    Link * link = get_link (x);
    assert (link->is_free());

    link->set (Link::end());

    if (size_ == 0)
    {
        head_.set (x);
    }
    else
    {
        get_link(tail_.get())->set (x);
    }
    tail_.set (x);
    ++size_;
}

template <class X, class F>
inline X *
Single_Queue_T<X,F>::front ()
{
    if (size_ == 0)
    {
        return 0;
    }
    return head_.get();
}

template <class X, class F>
inline X *
Single_Queue_T<X,F>::back ()
{
    if (size_ == 0)
    {
        return 0;
    }
    return tail_.get();
}

template <class X, class F>
inline X *
Single_Queue_T<X,F>::pop_front ()
{
    X * x = head_.get();

    if (x == Link::end ())
    {
        return 0;
    }

    head_.set (this->get_next(x));
    if (--size_ == 0)
    {
        tail_ = head_;
    }
        
    get_link(x)->set_free();
    return x;
}

template <class X, class F>
inline X *
Single_Queue_T<X,F>::pop_back ()
{
    if (size_ <= 1)
    {
        return pop_front ();
    }

    iterator it1 (head_);
    iterator it2 (tail_);

    X * xprev = *it1;
    X * xlast = *it2;

    for (; it1 != it2 ; ++it1)
    {
        xprev = *it1;
    }

    --size_;
    tail_.set (xprev);

    get_link(xprev)->set_end();
    get_link(xlast)->set (0);
    return xlast;
}

template <class X, class F>
inline void
Single_Queue_T<X,F>::swap (Single_Queue_T<X,F>  & other)
{
    if (&other == this)
        return;

    std::swap (head_, other.head_);
    std::swap (tail_, other.tail_);
    std::swap (size_, other.size_);
}

template <class X, class F>
inline X *
Single_Queue_T<X,F>::find (X *x)
{
  if (x == 0)
    return 0;
  
  iterator it1 = begin();
  iterator it2 = end();

  for (; it1 != it2 ; ++it1)
    {
      if (x == *it1)
        return x;
    }

    return 0;
}

template <class X, class F>
inline X *
Single_Queue_T<X,F>::remove (X *x)
{
  if (x == 0)
    return 0;

  if (head_.get () == x)
    return pop_front ();

  if (tail_.get () == x)
    return pop_back ();

  
  Link * link_x = get_link (x);
  Link * link_cur = &this->head_;

  for (;;)
    {
      X *next = link_cur->get ();

      if (next == Link::end())
        break; // not found

      if (next == x)
        {
          link_cur->set (link_x->get ());
          link_x->set_free ();

          assert (this->tail_.get () != x);
          
          --this->size_;
          return x;
        }
      link_cur = get_link (next);
    }
  return 0;
}

template <class X, class F >
template < class Other_List_T >
inline void
Single_Queue_T<X,F>::splice (Other_List_T  & other)
{
    if (other.empty())
        return;

    X * x0 = this->front ();
    X * x1 = this->back ();
    X * x2 = other.front();

    if (x0 == x2) // the same
        return;

    if (x1 == 0)
    {
        head_.set (x2);
    }
    else
    {
        get_link(x1)->set (x2);
    }

    this->tail_.set (other.back());  // it is valid back()!!!
    this->size_ += other.size ();

    Other_List_T tmp;
    tmp.swap (other);

//    other.head_.set_end();
//    other.tail_.set_end();
//    other.size_ = 0;
}

#endif /* TERABIT_SINGLE_LIST_T_H */


双向的LIST
/*********************************************************************
** Copyright (C) 2003 Terabit Pty Ltd.  All rights reserved.
**
** This file is part of the POSIX-Proactor module.
**
**  
**   
**
**
**
**
** @author Alexander Libman <libman@terabit.com.au>
**
**********************************************************************/

#ifndef TERABIT_DOUBLE_LIST_T_H
#define TERABIT_DOUBLE_LIST_T_H

# pragma once

#include "Single_List_T.h"

template <typename X, typename F> class Double_List_T;

//=================================================================
//
//
//=================================================================

template <typename X> 
class LinkD_T
{

    template <typename , typename > friend class Double_List_T;

    typedef  LinkS_T <X> LinkS;

public:
    
    LinkD_T () : next_ (0), prev_ (0) {}

    ~LinkD_T () {}

    bool is_free () const 
    {
        return (next_.is_free() && prev_.is_free());
    }

    bool is_last () const { return next_.is_end (); }
    bool is_first() const { return prev_.is_end (); }

    X * next() const { return next_.get ();}
    X * prev() const { return prev_.get ();}

private:
    void set_next (X * x)  
    { 
         //assert (x != 0); 
         next_.set (x);
    }
    
    void set_prev (X * x)  
    { 
        //assert (x != 0); 
        prev_.set (x);
    }

    void set_free () 
    { 
        next_.set_free (); 
        prev_.set_free ();
    }

    LinkS  next_;
    LinkS  prev_;
};


// =================================================================
// default convertor object reference X& to link reference LinkD_T<X> &
// this implementation suitable for case 
// when X is derived from LinkD_T<X> (99% of using  intrusive lists).
// If X has to be included in multiple intrusive lists simultaneosly,
// it must contain mulitiple links and
// inheritance should be replaced by aggregation
// and the user defined functor must be applied.
// ===================================================================
template <typename X> 
class LinkD_Functor_T :  public std::unary_function < X, LinkD_T <X> > 
{
public :
    LinkD_T <X> *  operator ()( const X * x )  const 
    {
        return  const_cast < X* > (x);
    }
};

template <typename X, typename F = LinkD_Functor_T <X> >
class Double_List_T 
{
public: 
    typedef Double_List_T<X,F> List;
    typedef LinkD_T<X>         LinkD;
    typedef LinkS_T<X>         LinkS;
    

            
    class iterator 
    {
        friend class Double_List_T<X,F>;
    public:
        ~iterator () {}

        iterator ()
        : x_   (0)
        , list_(0)
        {}

        iterator(const iterator & other ) 
        : x_   (other.x_)
        , list_(other.list_)
        {}


        iterator & operator = (const iterator & other )
        {
            x_ = other.x_;
            list_ = other.list_;
            return *this;
        }

        bool operator == (const iterator & other )const
        {
            return (x_ == other.x_ && list_ == other.list_);
        }

        bool operator != (const iterator & other )const
        {
            return (x_ != other.x_ || list_ != other.list_);
        }

        iterator & operator ++ ();

        iterator operator ++ (int);
 
        iterator & operator -- ();

        iterator operator -- (int);

        X * remove ()
        {
            if (list_ == 0)
                return 0;

            return list_->remove ((*this)++);
        }

        operator X *   () const { return x_; }
        X * operator * () const { return x_; }

   
    private:
        iterator(X * x, List & list) 
            : x_    (x) 
            , list_ (&list)
        {}

        X *   x_;
        Double_List_T<X, F>  * list_;
    };

    friend class  iterator;


    Double_List_T ()
        : head_ (LinkS::end())
        , tail_ (LinkS::end())
        , size_ (0)
    {}

    bool   empty () const  { return (size_ == 0); }
    size_t size  () const  { return size_; }

    iterator begin() { return iterator(head_.get(), *this); }
    iterator end ()  { return iterator(LinkS::end(), *this); }

    iterator push_front (X * x);
    iterator push_back  (X * x);
    

    X * pop_front ();
    X * pop_back  ();

    X * front () ; 
    X * back  () ; 

    iterator insert  (X * what, iterator where);
  
    X * remove (iterator itr);

    void swap   (Double_List_T<X, F>  & other);
    void splice (Double_List_T<X, F>  & other);



private:
    /// Protect from copy and assignment
    Double_List_T  (const Double_List_T<X, F>  & other);
    Double_List_T & operator= (const Double_List_T <X, F> & other);


    // functor that converts object pointer to link pointer
    // does it make sense to have non-static converter ??
    static LinkD * get_link (const X * x);

    static X *    get_next (const X * x);
    static X *    get_prev (const X * x);

    static bool is_end (const X * x) 
    {
        return x == LinkS::end ();
    }

    iterator insert_impl (X *x, X * x2);
    X *  remove_impl (X * x);

    LinkS    head_;
    LinkS    tail_;
    size_t   size_;
};

//-----------------------------------------------------
//   Double_List_T::iterator
//-----------------------------------------------------
template <class X, class F>
inline typename Double_List_T<X,F>::iterator &
Double_List_T<X,F>::iterator::operator ++()
{
    // behavior unpredictable if iterator not valid
    if (!Double_List_T<X,F>::is_end(x_))
    {
        x_ = Double_List_T<X,F>::get_next (x_);
    }
    return *this;
}
   
template <class X, class F>
inline typename Double_List_T<X,F>::iterator 
Double_List_T<X,F>::iterator::operator ++(int)
{
    // behavior unpredictable if iterator not valid
    iterator itr (*this);
    ++(*this);
    return itr;
}

template <class X, class F>
inline typename Double_List_T<X,F>::iterator &
Double_List_T<X,F>::iterator::operator --()
{
    // behavior unpredictable if iterator not valid
    if (Double_List_T<X,F>::is_end(x_))
    {
        x_ = list_->tail_.get();
    }
    else
    {
        x_ = Double_List_T<X,F>::get_prev (x_);
    }
    return *this;
}
   
template <class X, class F>
inline typename Double_List_T<X,F>::iterator 
Double_List_T<X,F>::iterator::operator --(int)
{
    // behavior unpredictable if iterator not valid
    iterator itr (*this);
    --(*this);
    return itr;
}
//-----------------------------------------------------
//   Double_List_T
//-----------------------------------------------------
template <class X, class F>
inline typename Double_List_T<X,F>::LinkD * 
Double_List_T<X,F>::get_link (const X * x)
{
    assert (x != 0 && !is_end(x));
    static F funcObj2Link;
    return funcObj2Link (x);
}

template <class X, class F>
inline X * 
Double_List_T<X,F>::get_next (const X * x)
{
    return get_link (x)->next ();
}

template <class X, class F>
inline X * 
Double_List_T<X,F>::get_prev (const X * x)
{
    return get_link (x)->prev ();
}

template <typename X, typename F>
inline X *
Double_List_T<X,F>::remove_impl (X * x)
{
    if (x == 0 || this->is_end(x))
        return 0;

    LinkD * link = get_link (x);
 
    X * x1 = link->prev ();
    X * x2 = link->next ();

    link->set_free ();
    
    if (!is_end(x1))
       get_link(x1)->set_next(x2);
    else
       head_.set (x2);

    if (!is_end(x2))
       get_link(x2)->set_prev(x1);
    else
       tail_.set (x1);
    
    --size_;
    assert (head_.get() != 0 && tail_.get() != 0);
    return x;
}


template <typename X, typename F>
inline typename Double_List_T<X,F>::iterator
Double_List_T<X,F>::insert_impl (X * x, X * x2)
{
    // insert node x before node x2
    //assert (x != 0 && x2 != 0);

    LinkD * link = get_link (x);
    assert (link->is_free());
    
    LinkD * link2 = is_end(x2) ? 0 : get_link(x2);

    X *     x1    = link2 ? link2->prev () : tail_.get();
    
    LinkD * link1 = is_end(x1) ? 0 : get_link(x1);
    
    link->set_next (x2);
    link->set_prev (x1);
 
    if (link1)
        link1->set_next (x);
    else
        head_.set(x);
    
    if (link2)
        link2->set_prev (x);
    else
        tail_.set (x);
    
    ++size_;

    return iterator (x, *this);
}

template <class X, class F>
inline X *
Double_List_T<X,F>::front ()
{
    if (size_ == 0)
    {
        return 0;
    }
    return head_.get();
}

template <class X, class F>
inline X *
Double_List_T<X,F>::back ()
{
    if (size_ == 0)
    {
        return 0;
    }
    return tail_.get();
}

template <typename X, typename F>
inline typename Double_List_T<X,F>::iterator
Double_List_T<X,F>::push_front (X * x)
{
    //assert (x != 0);
    return insert_impl (x, head_.get());
}

template <typename X, typename F>
inline typename Double_List_T<X,F>::iterator
Double_List_T<X,F>::push_back (X * x) 
{
    //assert (x != 0);
    return insert_impl (x, LinkS::end());
}

template <typename X, typename F>
inline typename Double_List_T<X,F>::iterator
Double_List_T<X,F>::insert (X *x, iterator where)
{
    //assert (x != 0);

    if (where.list_ != this)
        return iterator ();

    return insert_impl (x, where.x_);
}

template <typename X, typename F>
inline X *
Double_List_T<X,F>::pop_front ()
{
    return remove_impl (head_.get());
}

template <typename X, typename F>
inline X *
Double_List_T<X,F>::pop_back ()
{
    return remove_impl (tail_.get());
}

template <typename X, typename F>
inline X *
Double_List_T<X,F>::remove (iterator itr)
{
    if (itr.list_ != this)
        return 0;
    return remove_impl (*itr);
}

template <class X, class F>
inline void
Double_List_T<X,F>::swap (Double_List_T<X,F>  & other)
{
    if (&other == this)
        return;

    std::swap (head_, other.head_);
    std::swap (tail_, other.tail_);
    std::swap (size_, other.size_);
}

template <class X, class F>
inline void
Double_List_T<X,F>::splice (Double_List_T<X,F>  & other)
{
    if (&other == this)
        return;

    if (other.empty())
        return;

    if (this->empty())
    {
        this->swap (other);
        return;
    }

    X * x1 = this->back ();
    X * x2 = other.front();

    get_link(x1)->set_next (x2);
    get_link(x2)->set_prev (x1);

    this->tail_  = other.tail_;
    this->size_ += other.size_;

    other.head_.set_end();
    other.tail_.set_end();
    other.size_ = 0;
}

#endif /* TERABIT_DOUBLE_LIST_T_H */

用的时候基本和std::list差不多

先定义节点类如:class Session : public LinkD_T<Session>

再定义LIST类如:typedef Double_List_T<Session> SessionList;

要注意的是每个Session对象只能加入到一个SessionList对象,否则DEBUG下会出断言错误,RELEASE就会出错了。

因为它的节点对象本身就包含了指向前或后一个节点的指针,所以加到LIST时不需要再分配,这是与std::list不同的地方。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值