// -*- C++ -*-
/***************************************************************************
 *
 * <list> - definition of the C++ Standard Library list class template
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 1994-2005 Rogue Wave Software.
 * 
 ***************************************************************************
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 **************************************************************************/

#ifndef _RWSTD_LIST_INCLUDED
#define _RWSTD_LIST_INCLUDED


#include <memory>

#include <rw/_algobase.h>
#include <rw/_iterator.h>
#include <rw/_select.h>
#include <rw/_defs.h>
#include <rw/_error.h>


_RWSTD_NAMESPACE (std) { 

template <class _TypeT>
struct __rw_list_node
{
    __rw_list_node*  _C_next;   // pointer to next node
    __rw_list_node*  _C_prev;   // pointer to previous node
    _TypeT           _C_data;   // client data
}; 



template <class _TypeT, class _DiffT, class _Pointer, class _Reference>
class __rw_list_iter
    : public iterator <bidirectional_iterator_tag,
                       _TypeT, _DiffT, _Pointer, _Reference>
{
    typedef iterator <bidirectional_iterator_tag,
                     _TypeT, _DiffT, _Pointer, _Reference>
              _C_iter_base;

public:

    typedef typename _C_iter_base::value_type      value_type;
    typedef typename _C_iter_base::difference_type difference_type;
    typedef typename _C_iter_base::pointer         pointer;
    typedef typename _C_iter_base::reference       reference;

    // const_pointer and const_reference must be explicity typedef'ed to
    // const value_type* and const value_type& since we don't know if
    // _Pointer and _Reference are const types (they aren't if this isn't
    // a const iterator)
    typedef const value_type*                       const_pointer; 
    typedef const value_type&                       const_reference; 

    typedef bidirectional_iterator_tag              iterator_category;

    typedef __rw_list_iter <value_type, difference_type,
                            value_type*, value_type&>      _C_mutable_iter;

    typedef  __rw_list_node<value_type>*                   _C_link_type;
    
    __rw_list_iter () { }

    __rw_list_iter (const _C_link_type& __rhs)
        : _C_node (__rhs) { }

    // no copy ctor other than the one below defined; will use
    // a compiler generated one if __rw_list_iter != _C_mutable_iter
    __rw_list_iter (const _C_mutable_iter &__rhs)
        : _C_node (__rhs._C_node) { }

    __rw_list_iter& operator++ () {
        _C_node = (_C_link_type)((*_C_node)._C_next); 
        return *this;
    }
    
    __rw_list_iter& operator-- () {
        _C_node = (_C_link_type)((*_C_node)._C_prev);
        return *this;
    }
    
    __rw_list_iter operator++ (int) {
        __rw_list_iter __tmp = *this;
        return ++*this, __tmp;
    }
    
    __rw_list_iter operator-- (int) {
        __rw_list_iter __tmp = *this;
        return --*this, __tmp;
    }
    
    reference operator* () const {
        return (*_C_node)._C_data;
    }

    _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
    
    difference_type operator- (const __rw_list_iter&) const {
        return 0;
    }

    bool operator== (const __rw_list_iter& __iter) const {
        return _C_node == __iter._C_node;
    }

    bool operator!= (const __rw_list_iter& __iter) const {
        return !(*this == __iter);
    }

// private:

    _C_link_type _C_node;
};


#undef _ITER_NODE
#define _ITER_NODE(it)   (_ITER_BASE (it)._C_node)

        
template <class _TypeT, class _DiffT, class _Ptr1, class _Ref1,
                                      class _Ptr2, class _Ref2>
inline bool
operator== (const __rw_list_iter<_TypeT, _DiffT, _Ptr1, _Ref1> &__x,
            const __rw_list_iter<_TypeT, _DiffT, _Ptr2, _Ref2> &__y)

{
    return __x._C_node == __y._C_node;
}


template <class _TypeT, class _DiffT, class _Ptr1, class _Ref1,
                                      class _Ptr2, class _Ref2>
inline bool
operator!= (const __rw_list_iter<_TypeT, _DiffT, _Ptr1, _Ref1> &__x,
            const __rw_list_iter<_TypeT, _DiffT, _Ptr2, _Ref2> &__y)
{
    return !(__x == __y);
}


_EXPORT
template <class _TypeT, class _Allocator = allocator<_TypeT> >
class list : private _Allocator
{
public:

    typedef _TypeT                                    value_type;
    typedef _Allocator                                allocator_type;
    typedef typename allocator_type::reference       reference;
    typedef typename allocator_type::const_reference const_reference;
    typedef typename allocator_type::size_type       size_type;
    typedef typename allocator_type::difference_type difference_type;
    typedef typename allocator_type::pointer         pointer;
    typedef typename allocator_type::const_pointer   const_pointer;
    typedef __rw_list_node<value_type>                _C_list_node;
    typedef _C_list_node*                             _C_link_type;

    typedef _RWSTD_REBIND (allocator_type, _C_list_node)   _C_node_alloc_type;
    typedef _RWSTD_ALLOC_TYPE (allocator_type, value_type) _C_value_alloc_type;


    typedef __rw_list_iter<value_type, difference_type, pointer, reference>
    _C_list_iter; 

    typedef __rw_list_iter<value_type, difference_type, const_pointer,
                           const_reference>
    _C_list_citer;


#ifndef _RWSTD_NO_DEBUG_ITER

    typedef _RW::__rw_debug_iter <list,_C_list_iter, _C_list_iter>
    iterator;
    
    typedef _RW::__rw_debug_iter <list,_C_list_citer, _C_list_iter>
    const_iterator;
    

    iterator _C_make_iter (const _C_link_type &__node) {
        return iterator (*this, _C_list_iter (__node));
    }

    const_iterator _C_make_iter (const _C_link_type &__node) const {
        return const_iterator (*this, _C_list_citer (__node));
    }

#else   // if defined (_RWSTD_NO_DEBUG_ITER)

    typedef _C_list_iter         iterator;
    typedef _C_list_citer        const_iterator;

    iterator _C_make_iter (const _C_link_type &__node) {
        return iterator (__node);
    }

    const_iterator _C_make_iter (const _C_link_type &__node) const {
        return const_iterator (__node);
    }

#endif   // _RWSTD_NO_DEBUG_ITER


#if !defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) 

    typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
    typedef _STD::reverse_iterator<iterator>       reverse_iterator;

#else   // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)

  typedef std::reverse_iterator<const_iterator, 
        bidirectional_iterator_tag, value_type, 
        const_reference, const_pointer, difference_type>
    const_reverse_iterator;

    typedef std::reverse_iterator<iterator, 
        bidirectional_iterator_tag, value_type, 
        reference, pointer, difference_type>
    reverse_iterator;

#endif   // _RWSTD_NO_CLASS_PARTIAL_SPEC

protected:

#ifndef _RWSTD_NO_LIST_NODE_BUFFER

    // Node buffer data structure
    struct _C_nodebuf {
        typedef _RWSTD_REBIND (allocator_type, _C_nodebuf) _C_alloc_type;
        typedef typename _C_alloc_type::pointer           _C_pointer;

        _C_pointer   _C_next_buf;
        size_type    _C_bufsize;
        _C_link_type _C_buffer;
    };

    typedef typename _C_nodebuf::_C_alloc_type _C_buf_alloc_type;
    typedef typename _C_nodebuf::_C_pointer    _C_buf_pointer;

    void _C_add_buffer (bool);
    void _C_free_buffers ();

    _C_buf_pointer _C_buflist;
    _C_link_type   _C_free_list;

#endif   // _RWSTD_USE_LIST_NODE_BUFFER


    _C_link_type        _C_next_avail;
    _C_link_type        _C_last;
    _C_link_type        _C_node;
    size_type           _C_length;



// Macros used later in node buffer management
#if !defined (_RWSTD_NO_LIST_NODE_BUFFER)

#  define _RWSTD_NODE_BUFFER_INIT(blist,flist)                   \
        _C_buflist (blist), _C_free_list (flist),

#  define _RWSTD_NODE_LIST_FREE()                                \
        _C_free_buffers ()

#  define _RWSTD_NODE_LIST_SWAP(other)                           \
        _STD::swap (_C_buflist, other._C_buflist);               \
        _STD::swap (_C_free_list, other._C_free_list)              

#  define _RWSTD_LIST_INSERT_RANGE(b,e,v)                        \
        _TRY {                                                   \
            insert (b, e, v);                                    \
        } _CATCH (...) {                                         \
            _RWSTD_NODE_LIST_FREE();                             \
            _RETHROW;                                            \
        } typedef void __dummy_t

    _C_link_type _C_get_node (bool __empty_list = false) {
        if (_C_free_list) {
            _C_link_type __tmp = _C_free_list;
            _C_free_list = _C_free_list->_C_next;
            return __tmp;
        }
        if (_C_next_avail == _C_last)
            _C_add_buffer (__empty_list);
        return _C_next_avail++;
    }

    void _C_put_node (_C_link_type __link) {
        __link->_C_next = _C_free_list;
        _C_free_list = __link;
    }

#else // defined (_RWSTD_NO_LIST_NODE_BUFFER)

#  define _RWSTD_NODE_BUFFER_INIT(ignore0,ignore1)
#  define _RWSTD_NODE_LIST_FREE()
#  define _RWSTD_NODE_LIST_SWAP(ignore)

#  define _RWSTD_LIST_INSERT_RANGE(b,e,v)                             \
        insert (b,e,v)

    _C_link_type _C_get_node (bool = false) {
        return _C_node_alloc_type (*this).allocate (1, (void*)_C_last);
    }

    void _C_put_node (_C_link_type __link) {
        _C_node_alloc_type (*this).deallocate (__link, 1);
    }

#endif // _RWSTD_NO_LIST_NODE_BUFFER

#  define _RWSTD_LIST_SAFE_INSERT_RANGE(__it, __first, __last)  \
    _RWSTD_ASSERT_RANGE (begin (), __it);                       \
    _RWSTD_ASSERT_RANGE (__first, __last);                      \
                                                                \
    if (!(__first == __last)) {                                 \
        iterator __start = __it;                                \
                                                                \
        _TRY {                                                  \
            __start = insert (__it, *__first);                  \
                                                                \
            while (!(++__first == __last))                      \
                insert (__it, *__first);                        \
        } _CATCH (...) {                                        \
            erase (__start, __it);                              \
            _RETHROW;                                           \
        }                                                       \
    } typedef void __dummy_t


    // here and only here is _C_node initialized
    void _C_init (bool __empty_list = false) {
        _C_node = _C_get_node (__empty_list);

        (*_C_node)._C_next = _C_node;
        (*_C_node)._C_prev = _C_node; 
    }
    
    void _C_init (size_type __n, const value_type& __val) {
        _C_init();
        _RWSTD_LIST_INSERT_RANGE (begin (), __n, __val);
    }

public:

    explicit
    list (const allocator_type& __alloc = allocator_type ())
        : allocator_type (__alloc), _RWSTD_NODE_BUFFER_INIT(0,0)
          _C_next_avail (0), _C_last (0), _C_node (0), _C_length (0) {
        _C_init (true);
    }
    
    explicit
    list (size_type             __n, 
          const_reference       __x     = value_type (),
          const allocator_type &__alloc = allocator_type ())
        : allocator_type (__alloc), _RWSTD_NODE_BUFFER_INIT(0,0)
          _C_next_avail (0), _C_last (0), _C_node (0), _C_length (0) {
        _C_init (__n, __x);
    }

    template<class _InputIterator>
    void _C_init (_InputIterator __first, _InputIterator __last, void*) {
        _RWSTD_ASSERT_RANGE (__first, __last);
        _C_init();
        _RWSTD_LIST_INSERT_RANGE (begin (), __first, __last);
    }

    template<class _InputIterator>
    void _C_init (_InputIterator __first, _InputIterator __last, int) {
        _RWSTD_ASSERT_RANGE (__first, __last);
        _C_init (__first, __last);
    }

    template<class _InputIterator>
    list (_InputIterator __first, _InputIterator __last, 
          const allocator_type& __alloc = allocator_type ())
        : allocator_type (__alloc), _RWSTD_NODE_BUFFER_INIT(0,0)
          _C_next_avail (0), _C_last (0), _C_node (0), _C_length (0) {
        _RWSTD_ASSERT_RANGE (__first, __last);
        _C_init (__first, __last, _RWSTD_DISPATCH (_InputIterator));
    }

    list (const list &__rhs)
        : allocator_type(__rhs.get_allocator()), _RWSTD_NODE_BUFFER_INIT(0,0) 
          _C_next_avail (0), _C_last (0), _C_node (0), _C_length (0) {
        _C_init();
        _RWSTD_LIST_INSERT_RANGE (begin (), __rhs.begin (), __rhs.end ());
    }

    ~list ();

    list& operator= (const list&);   

    template<class _InputIterator>
    void assign (_InputIterator __first, _InputIterator __last) {
        _RWSTD_ASSERT_RANGE (__first, __last);

        clear ();
        _C_insert (begin (), __first, __last,
                   _RWSTD_DISPATCH (_InputIterator));
    }

    void assign (size_type __n, const_reference __val) {
        clear ();
        insert (begin (), __n, __val);
    }

    allocator_type get_allocator () const {
        return *this;
    }

    iterator begin () {
        return _C_make_iter ((*_C_node)._C_next);
    }

    const_iterator begin () const {
        return _C_make_iter ((*_C_node)._C_next);
    }

    iterator end () {
        return _C_make_iter (_C_node);
    }

    const_iterator end () const {
        return _C_make_iter (_C_node);
    }

    reverse_iterator rbegin () { 
        return reverse_iterator (end ());
    }

    const_reverse_iterator rbegin () const { 
        return const_reverse_iterator (end ());
    }

    reverse_iterator rend () { 
        return reverse_iterator (begin ());
    }

    const_reverse_iterator rend () const {
        return const_reverse_iterator (begin ());
    }

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

    size_type size () const {
        return _C_length;
    }

    size_type max_size () const {
        return _C_node_alloc_type (*this).max_size ();
    }

    void resize (size_type, value_type);

    void resize (size_type __n) {
        resize (__n, value_type ());
    }

    reference front () {
        _RWSTD_ASSERT (!empty ());
        return *begin ();
    }

    const_reference front () const {
        _RWSTD_ASSERT (!empty ());
        return *begin ();
    }

    reference back () {
        _RWSTD_ASSERT (!empty ());
        return *--end ();
    }

    const_reference back () const {
        _RWSTD_ASSERT (!empty ());
        return *--end ();
    }

    void push_front (const_reference __x) {
        insert (begin (), __x);
        _RWSTD_ASSERT (!empty ());
    }

    void push_back  (const_reference __x) {
        insert (end (), __x);
        _RWSTD_ASSERT (!empty ());
    }
    
    void pop_front () {
        _RWSTD_ASSERT (!empty ());
        erase (begin ());
    }

    void pop_back () {
        _RWSTD_ASSERT (!empty ());
        erase (--end ());
    }

    iterator insert (iterator __it, const_reference __x);

    // handles nonintegral types
    template<class _InputIterator>
    void _C_insert (const iterator &__it,
                    _InputIterator  __first, _InputIterator __last, void*) {

        _RWSTD_LIST_SAFE_INSERT_RANGE (__it, __first, __last);
    }

    // handles integral types
    template<class _InputIterator>
    void _C_insert (const iterator &__it, 
                    _InputIterator  __first, _InputIterator __last, int) {
        _C_insert (__it, size_type (__first), const_reference (__last));
    }

    template<class _InputIterator>
    void insert (iterator __it, 
                 _InputIterator __first, _InputIterator __last) {

        _RWSTD_ASSERT_RANGE (begin (), __it);
        _RWSTD_ASSERT_RANGE (__first, __last);

        // calling insert on a list specialized on an integral type
        // may lead to ambiguities if the actual function arguments do not
        // exactly match those of the non-templatized function (below)
        // the dispatch mechanism determines whether the arguments
        // really are iterators or whether they are just integral types
        // and calls the appropriate implementation function
        _C_insert  (__it, __first, __last, _RWSTD_DISPATCH (_InputIterator));
    }

    void insert (iterator __it, size_type __n, const_reference __val) {
        _RWSTD_ASSERT_RANGE (begin (), __it);

        _C_insert (__it, __n, __val);
    }

    iterator erase (iterator);

    iterator erase (iterator, iterator);

    void swap (list&);

    void clear () {
        erase (begin (), end ());
    }

#if defined (_RWSTD_NO_PART_SPEC_OVERLOAD)
    friend void swap (list& __lhs, list& __rhs) {
        __lhs.swap (__rhs);
    }
#endif

protected:
    
    void _C_transfer (iterator, iterator, iterator, list&);

    void _C_advance (iterator &__it, difference_type __n,
                     const iterator &__end) {
        while (__n-- && !(__it == __end))
            ++__it;
    }
      
    // uses transfer_node to merge in list by transfering nodes to list
    void _C_adjacent_merge (iterator, iterator, iterator);

    // uses transfer_node to merge in list by transfering nodes to list
    template<class _Compare>
    void _C_adjacent_merge (iterator, iterator, iterator, _Compare);

    void _C_insert (iterator __it, size_type __n, const_reference __x) {
        _RWSTD_ASSERT_RANGE (begin (), __it);

        if (__n) {
            iterator __start = __it;

            _TRY {
                __start = insert (__it, __x);

                while (--__n)
                    insert (__it, __x);
            } _CATCH (...) {
                erase (__start, __it);
                _RETHROW;
            }
        }
    }

public:

    // 23.2.2.4, p4
    void splice (iterator, list&);

    // 23.2.2.4, p7
    void splice (iterator, list&, iterator);

    // 23.2.2.4, p11
    void splice (iterator, list&, iterator, iterator);

    void remove (const_reference);

    void unique ();

    void merge (list&);

    void reverse ();

    void sort ();

    template<class _Predicate>
    void remove_if (_Predicate);

    template<class _BinaryPredicate>
    void unique (_BinaryPredicate);

    template<class _Compare>
    void merge (list &__x, _Compare);

    template<class _Compare>
    void sort (_Compare);

};


template <class _TypeT, class _Allocator>
inline bool
operator== (const list<_TypeT, _Allocator>& __x, 
            const list<_TypeT, _Allocator>& __y)
{
    return    __x.size () == __y.size ()
           && equal (__x.begin (), __x.end (), __y.begin ());
}


template <class _TypeT, class _Allocator>
inline bool
operator< (const list<_TypeT, _Allocator>& __x, 
           const list<_TypeT, _Allocator>& __y)
{
    return lexicographical_compare (__x.begin (), __x.end (), 
                                    __y.begin (), __y.end ());
}


template <class _TypeT, class _Allocator>
inline bool
operator!= (const list<_TypeT, _Allocator>& __x, 
            const list<_TypeT, _Allocator>& __y)
{
    return !(__x == __y);
}


template <class _TypeT, class _Allocator>
inline bool
operator<= (const list<_TypeT, _Allocator>& __x, 
            const list<_TypeT, _Allocator>& __y)
{
    return !(__y < __x);
}


template <class _TypeT, class _Allocator>
inline bool
operator> (const list<_TypeT, _Allocator>& __x, 
            const list<_TypeT, _Allocator>& __y)
{
    return __y < __x;
}


template <class _TypeT, class _Allocator>
inline bool
operator>= (const list<_TypeT, _Allocator>& __x, 
            const list<_TypeT, _Allocator>& __y)
{
    return !(__x < __y);
}


#ifndef _RWSTD_NO_PART_SPEC_OVERLOAD

template <class _TypeT, class _Allocator>
inline void swap (list<_TypeT, _Allocator>& __x, 
                  list<_TypeT, _Allocator>& __y)
{
    __x.swap (__y);
}

#endif   // _RWSTD_NO_PART_SPEC_OVERLOAD


template <class _TypeT, class _Allocator>
inline typename list<_TypeT, _Allocator>::iterator 
list<_TypeT, _Allocator>::insert (iterator __it, const_reference __x)
{
    _RWSTD_ASSERT_RANGE (begin (), __it);

    // create temporary allocator for non-conforming compilers
    //  which need to use allocator_interface
    _C_link_type __tmp = _C_get_node (false);

    _TRY {
        _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
                            construct (_RWSTD_VALUE_ALLOC
                                       (_C_value_alloc_type, *this,
                                        address ((*__tmp)._C_data)), __x));
    }
    _CATCH (...) {
        _C_put_node (__tmp);
        _RETHROW;
    }

    (*__tmp)._C_next = _ITER_NODE (__it);
    (*__tmp)._C_prev = (*_ITER_NODE (__it))._C_prev;

    (*(_C_link_type ((*_ITER_NODE (__it))._C_prev)))._C_next = __tmp;

    (*_ITER_NODE (__it))._C_prev = __tmp;

    ++_C_length;

    return _C_make_iter (__tmp);
}


template <class _TypeT, class _Allocator>
inline typename list<_TypeT, _Allocator>::iterator 
list<_TypeT, _Allocator>::erase (iterator __it)
{
    _RWSTD_ASSERT_RANGE (begin (), __it);

    if (__it == end ())
        return end ();

    iterator __tmp =
        _C_make_iter (_C_link_type ((*_ITER_NODE (__it))._C_next));

    (*(_C_link_type ((*_ITER_NODE (__it))._C_prev)))._C_next =
        (*_ITER_NODE (__it))._C_next;
    (*(_C_link_type ((*_ITER_NODE (__it))._C_next)))._C_prev =
        (*_ITER_NODE (__it))._C_prev;

    --_C_length;

    _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
                        destroy (_RWSTD_VALUE_ALLOC (_C_value_alloc_type,
                            *this, address ((*_ITER_NODE (__it))._C_data))));
    _C_put_node (_ITER_NODE (__it));

    return __tmp;
}


template <class _TypeT, class _Allocator>
inline void
list<_TypeT, _Allocator>::swap (list &__x)
{
    if (get_allocator () == __x.get_allocator ()) {
        _STD::swap (_C_node, __x._C_node); 
        _STD::swap (_C_length, __x._C_length);

        _RWSTD_NODE_LIST_SWAP(__x);

        _STD::swap (_C_next_avail, __x._C_next_avail);
        _STD::swap (_C_last, __x._C_last);
    }
    else {
        list __tmp (*this);
        *this = __x;
        __x = __tmp;
    }
}

}   // namespace std


#ifdef _RWSTD_NO_IMPLICIT_INCLUSION
#  include <list.cc>
#endif


#endif   //_RWSTD_LIST_INCLUDED
