Boost logo

Boost-Commit :

From: phil_at_[hidden]
Date: 2008-07-22 05:14:39


Author: pbouchard
Date: 2008-07-22 05:14:39 EDT (Tue, 22 Jul 2008)
New Revision: 47677
URL: http://svn.boost.org/trac/boost/changeset/47677

Log:
Trying adding patch & tcc files.
Added:
   sandbox/shifted_ptr/bits/list.tcc (contents, props changed)
   sandbox/shifted_ptr/bits/list.tcc.patch (contents, props changed)
   sandbox/shifted_ptr/bits/stl_list.h (contents, props changed)
   sandbox/shifted_ptr/bits/stl_list.h.patch (contents, props changed)

Added: sandbox/shifted_ptr/bits/list.tcc
==============================================================================
--- (empty file)
+++ sandbox/shifted_ptr/bits/list.tcc 2008-07-22 05:14:39 EDT (Tue, 22 Jul 2008)
@@ -0,0 +1,409 @@
+// List implementation (out of line) -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003, 2004 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 2, 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * 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.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * 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. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/**
+ Copyright (c) 2008 Phil Bouchard <phil_at_[hidden]>.
+
+ Distributed under the Boost Software License, Version 1.0.
+
+ See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+
+ See http://www.boost.org/libs/smart_ptr/doc/index.html for documentation.
+*/
+
+/** @file list.tcc
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _LIST_TCC
+#define _LIST_TCC 1
+
+namespace _GLIBCXX_STD
+{
+ template<typename _Alloc>
+ void
+ _List_node_base<_Alloc>::hook(pointer const & __position)
+ {
+ this->_M_next = __position;
+ this->_M_prev = __position->_M_prev;
+ __position->_M_prev->_M_next = this;
+ __position->_M_prev = this;
+ }
+
+ template<typename _Alloc>
+ void
+ _List_node_base<_Alloc>::unhook()
+ {
+ pointer const __next_node = this->_M_next;
+ pointer const __prev_node = this->_M_prev;
+ __prev_node->_M_next = __next_node;
+ __next_node->_M_prev = __prev_node;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void
+ _List_base<_Tp,_Alloc>::
+ _M_clear()
+ {
+ typedef _List_node<_Tp,_Alloc> _Node;
+ typedef _List_node_base<_Alloc> _Node_base;
+ _Node* __cur = static_cast<_Node*>(static_cast<_Node_base*>(this->_M_impl._M_node._M_next));
+ while (__cur != &this->_M_impl._M_node)
+ {
+ _Node* __tmp = __cur;
+ __cur = static_cast<_Node*>(static_cast<_Node_base*>(__cur->_M_next));
+ std::_Destroy(&__tmp->_M_data);
+ _M_put_node(__tmp);
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ typename list<_Tp,_Alloc>::iterator
+ list<_Tp,_Alloc>::
+ insert(iterator __position, const value_type& __x)
+ {
+ typename _Node::pointer __tmp = _M_create_node(__x);
+ __tmp->hook(__position._M_node);
+ return __tmp;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ typename list<_Tp,_Alloc>::iterator
+ list<_Tp,_Alloc>::
+ erase(iterator __position)
+ {
+ iterator __ret = __position._M_node->_M_next;
+ _M_erase(__position);
+ return __ret;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void
+ list<_Tp,_Alloc>::
+ resize(size_type __new_size, const value_type& __x)
+ {
+ iterator __i = begin();
+ size_type __len = 0;
+ for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
+ ;
+ if (__len == __new_size)
+ erase(__i, end());
+ else // __i == end()
+ insert(end(), __new_size - __len, __x);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ list<_Tp,_Alloc>&
+ list<_Tp,_Alloc>::
+ operator=(const list& __x)
+ {
+ if (this != &__x)
+ {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ const_iterator __first2 = __x.begin();
+ const_iterator __last2 = __x.end();
+ while (__first1 != __last1 && __first2 != __last2)
+ *__first1++ = *__first2++;
+ if (__first2 == __last2)
+ erase(__first1, __last1);
+ else
+ insert(__last1, __first2, __last2);
+ }
+ return *this;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void
+ list<_Tp,_Alloc>::
+ _M_fill_assign(size_type __n, const value_type& __val)
+ {
+ iterator __i = begin();
+ for ( ; __i != end() && __n > 0; ++__i, --__n)
+ *__i = __val;
+ if (__n > 0)
+ insert(end(), __n, __val);
+ else
+ erase(__i, end());
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _InputIterator>
+ void
+ list<_Tp,_Alloc>::
+ _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
+ __false_type)
+ {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ for (; __first1 != __last1 && __first2 != __last2;
+ ++__first1, ++__first2)
+ *__first1 = *__first2;
+ if (__first2 == __last2)
+ erase(__first1, __last1);
+ else
+ insert(__last1, __first2, __last2);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void
+ list<_Tp,_Alloc>::
+ remove(const value_type& __value)
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ while (__first != __last)
+ {
+ iterator __next = __first;
+ ++__next;
+ if (*__first == __value)
+ _M_erase(__first);
+ __first = __next;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void
+ list<_Tp,_Alloc>::
+ unique()
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ if (__first == __last)
+ return;
+ iterator __next = __first;
+ while (++__next != __last)
+ {
+ if (*__first == *__next)
+ _M_erase(__next);
+ else
+ __first = __next;
+ __next = __first;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void
+ list<_Tp,_Alloc>::
+ merge(list& __x)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 300. list::merge() specification incomplete
+ if (this != &__x)
+ {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ iterator __first2 = __x.begin();
+ iterator __last2 = __x.end();
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first2 < *__first1)
+ {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2)
+ _M_transfer(__last1, __first2, __last2);
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void
+ list<_Tp,_Alloc>::
+ 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];
+ list * __fill = &__tmp[0];
+ list * __counter;
+
+ do
+ {
+ __carry.splice(__carry.begin(), *this, begin());
+
+ for(__counter = &__tmp[0];
+ (__counter != __fill) && !__counter->empty();
+ ++__counter)
+ {
+ __counter->merge(__carry);
+ __carry.swap(*__counter);
+ }
+ __carry.swap(*__counter);
+ if (__counter == __fill)
+ ++__fill;
+ }
+ while ( !empty() );
+
+ for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
+ __counter->merge( *(__counter-1) );
+ swap( *(__fill-1) );
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _Predicate>
+ void
+ list<_Tp,_Alloc>::
+ remove_if(_Predicate __pred)
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ while (__first != __last)
+ {
+ iterator __next = __first;
+ ++__next;
+ if (__pred(*__first))
+ _M_erase(__first);
+ __first = __next;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _BinaryPredicate>
+ void
+ list<_Tp,_Alloc>::
+ unique(_BinaryPredicate __binary_pred)
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ if (__first == __last) return;
+ iterator __next = __first;
+ while (++__next != __last)
+ {
+ if (__binary_pred(*__first, *__next))
+ _M_erase(__next);
+ else
+ __first = __next;
+ __next = __first;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _StrictWeakOrdering>
+ void
+ list<_Tp,_Alloc>::
+ merge(list& __x, _StrictWeakOrdering __comp)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 300. list::merge() specification incomplete
+ if (this != &__x)
+ {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ iterator __first2 = __x.begin();
+ iterator __last2 = __x.end();
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first2, *__first1))
+ {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2)
+ _M_transfer(__last1, __first2, __last2);
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _StrictWeakOrdering>
+ void
+ list<_Tp,_Alloc>::
+ 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];
+ list * __fill = &__tmp[0];
+ list * __counter;
+
+ do
+ {
+ __carry.splice(__carry.begin(), *this, begin());
+
+ for(__counter = &__tmp[0];
+ (__counter != __fill) && !__counter->empty();
+ ++__counter)
+ {
+ __counter->merge(__carry, __comp);
+ __carry.swap(*__counter);
+ }
+ __carry.swap(*__counter);
+ if (__counter == __fill)
+ ++__fill;
+ }
+ while ( !empty() );
+
+ for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
+ __counter->merge( *(__counter-1), __comp );
+ swap( *(__fill-1) );
+ }
+ }
+} // namespace std
+
+#endif /* _LIST_TCC */
+

Added: sandbox/shifted_ptr/bits/list.tcc.patch
==============================================================================
--- (empty file)
+++ sandbox/shifted_ptr/bits/list.tcc.patch 2008-07-22 05:14:39 EDT (Tue, 22 Jul 2008)
@@ -0,0 +1,81 @@
+--- /local/include/c++/3.4.5/bits/list.tcc Wed Jan 18 11:06:46 2006
++++ list.tcc Mon Jul 21 03:28:48 2008
+@@ -51,42 +51,74 @@
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
++/**
++ Copyright (c) 2008 Phil Bouchard <phil_at_[hidden]>.
++
++ Distributed under the Boost Software License, Version 1.0.
++
++ See accompanying file LICENSE_1_0.txt or copy at
++ http://www.boost.org/LICENSE_1_0.txt
++
++ See http://www.boost.org/libs/smart_ptr/doc/index.html for documentation.
++*/
++
+ /** @file list.tcc
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+ #ifndef _LIST_TCC
+ #define _LIST_TCC 1
+
+ namespace _GLIBCXX_STD
+ {
++ template<typename _Alloc>
++ void
++ _List_node_base<_Alloc>::hook(pointer const & __position)
++ {
++ this->_M_next = __position;
++ this->_M_prev = __position->_M_prev;
++ __position->_M_prev->_M_next = this;
++ __position->_M_prev = this;
++ }
++
++ template<typename _Alloc>
++ void
++ _List_node_base<_Alloc>::unhook()
++ {
++ pointer const __next_node = this->_M_next;
++ pointer const __prev_node = this->_M_prev;
++ __prev_node->_M_next = __next_node;
++ __next_node->_M_prev = __prev_node;
++ }
++
+ template<typename _Tp, typename _Alloc>
+ void
+ _List_base<_Tp,_Alloc>::
+ _M_clear()
+ {
+- typedef _List_node<_Tp> _Node;
+- _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next);
++ typedef _List_node<_Tp,_Alloc> _Node;
++ typedef _List_node_base<_Alloc> _Node_base;
++ _Node* __cur = static_cast<_Node*>(static_cast<_Node_base*>(this->_M_impl._M_node._M_next));
+ while (__cur != &this->_M_impl._M_node)
+ {
+ _Node* __tmp = __cur;
+- __cur = static_cast<_Node*>(__cur->_M_next);
++ __cur = static_cast<_Node*>(static_cast<_Node_base*>(__cur->_M_next));
+ std::_Destroy(&__tmp->_M_data);
+ _M_put_node(__tmp);
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ typename list<_Tp,_Alloc>::iterator
+ list<_Tp,_Alloc>::
+ insert(iterator __position, const value_type& __x)
+ {
+- _Node* __tmp = _M_create_node(__x);
++ typename _Node::pointer __tmp = _M_create_node(__x);
+ __tmp->hook(__position._M_node);
+ return __tmp;
+ }
+
+ template<typename _Tp, typename _Alloc>

Added: sandbox/shifted_ptr/bits/stl_list.h
==============================================================================
--- (empty file)
+++ sandbox/shifted_ptr/bits/stl_list.h 2008-07-22 05:14:39 EDT (Tue, 22 Jul 2008)
@@ -0,0 +1,1285 @@
+// List implementation -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 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 2, 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * 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.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * 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. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/**
+ Copyright (c) 2008 Phil Bouchard <phil_at_[hidden]>.
+
+ Distributed under the Boost Software License, Version 1.0.
+
+ See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+
+ See http://www.boost.org/libs/smart_ptr/doc/index.html for documentation.
+*/
+
+/** @file stl_list.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _LIST_H
+#define _LIST_H 1
+
+#include <bits/concept_check.h>
+
+namespace _GLIBCXX_STD
+{
+ // Supporting structures are split into common and templated types; the
+ // latter publicly inherits from the former in an effort to reduce code
+ // duplication. This results in some "needless" static_cast'ing later on,
+ // but it's all safe downcasting.
+
+ /// @if maint Common part of a node in the %list. @endif
+ template<typename _Alloc>
+ struct _List_node_base
+ {
+ typedef typename _Alloc::template rebind<_List_node_base<_Alloc> >::other _Node_Alloc_type;
+
+ typedef typename _Node_Alloc_type::pointer pointer;
+ typedef typename _Node_Alloc_type::const_pointer const_pointer;
+ typedef typename _Node_Alloc_type::reference reference;
+ typedef typename _Node_Alloc_type::const_reference const_reference;
+
+ pointer _M_next; ///< Self-explanatory
+ pointer _M_prev; ///< Self-explanatory
+
+ static void
+ swap(_List_node_base& __x, _List_node_base& __y);
+
+ void
+ transfer(pointer const & __first,
+ pointer const & __last);
+
+ void
+ reverse();
+
+ void
+ hook(pointer const & __position);
+
+ void
+ unhook();
+ };
+
+ /// @if maint An actual node in the %list. @endif
+ template<typename _Tp, typename _Alloc>
+ struct _List_node : public _List_node_base<_Alloc>
+ {
+ typedef typename _Alloc::template rebind<_List_node<_Tp, _Alloc> >::other _Node_Alloc_type;
+
+ typedef typename _Node_Alloc_type::pointer pointer;
+ typedef typename _Node_Alloc_type::const_pointer const_pointer;
+ typedef typename _Node_Alloc_type::reference reference;
+ typedef typename _Node_Alloc_type::const_reference const_reference;
+
+ _Tp _M_data; ///< User's data.
+ };
+
+ /**
+ * @brief A list::iterator.
+ *
+ * @if maint
+ * All the functions are op overloads.
+ * @endif
+ */
+ template<typename _Tp, typename _Alloc>
+ struct _List_iterator
+ {
+ typedef _List_iterator<_Tp, _Alloc> _Self;
+ typedef _List_node<_Tp, _Alloc> _Node;
+
+ typedef ptrdiff_t difference_type;
+ typedef bidirectional_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef _Tp* pointer;
+ typedef _Tp& reference;
+
+ _List_iterator()
+ : _M_node() { }
+
+ _List_iterator(_List_node_base<_Alloc>* __x)
+ : _M_node(__x) { }
+
+ // Must downcast from List_node_base to _List_node to get to _M_data.
+ reference
+ operator*() const
+ { return static_cast<_Node*>(_M_node)->_M_data; }
+
+ pointer
+ operator->() const
+ { return &static_cast<_Node*>(_M_node)->_M_data; }
+
+ _Self&
+ operator++()
+ {
+ _M_node = _M_node->_M_next;
+ return *this;
+ }
+
+ _Self
+ operator++(int)
+ {
+ _Self __tmp = *this;
+ _M_node = _M_node->_M_next;
+ return __tmp;
+ }
+
+ _Self&
+ operator--()
+ {
+ _M_node = _M_node->_M_prev;
+ return *this;
+ }
+
+ _Self
+ operator--(int)
+ {
+ _Self __tmp = *this;
+ _M_node = _M_node->_M_prev;
+ return __tmp;
+ }
+
+ bool
+ operator==(const _Self& __x) const
+ { return _M_node == __x._M_node; }
+
+ bool
+ operator!=(const _Self& __x) const
+ { return _M_node != __x._M_node; }
+
+ // The only member points to the %list element.
+ _List_node_base<_Alloc>* _M_node;
+ };
+
+ /**
+ * @brief A list::const_iterator.
+ *
+ * @if maint
+ * All the functions are op overloads.
+ * @endif
+ */
+ template<typename _Tp, typename _Alloc>
+ struct _List_const_iterator
+ {
+ typedef _List_const_iterator<_Tp, _Alloc> _Self;
+ typedef const _List_node<_Tp, _Alloc> _Node;
+ typedef _List_iterator<_Tp, _Alloc> iterator;
+
+ typedef ptrdiff_t difference_type;
+ typedef bidirectional_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef const _Tp* pointer;
+ typedef const _Tp& reference;
+
+ _List_const_iterator()
+ : _M_node() { }
+
+ _List_const_iterator(const _List_node_base<_Alloc>* __x)
+ : _M_node(__x) { }
+
+ _List_const_iterator(const iterator& __x)
+ : _M_node(__x._M_node) { }
+
+ // Must downcast from List_node_base to _List_node to get to
+ // _M_data.
+ reference
+ operator*() const
+ { return static_cast<_Node*>(_M_node)->_M_data; }
+
+ pointer
+ operator->() const
+ { return &static_cast<_Node*>(_M_node)->_M_data; }
+
+ _Self&
+ operator++()
+ {
+ _M_node = _M_node->_M_next;
+ return *this;
+ }
+
+ _Self
+ operator++(int)
+ {
+ _Self __tmp = *this;
+ _M_node = _M_node->_M_next;
+ return __tmp;
+ }
+
+ _Self&
+ operator--()
+ {
+ _M_node = _M_node->_M_prev;
+ return *this;
+ }
+
+ _Self
+ operator--(int)
+ {
+ _Self __tmp = *this;
+ _M_node = _M_node->_M_prev;
+ return __tmp;
+ }
+
+ bool
+ operator==(const _Self& __x) const
+ { return _M_node == __x._M_node; }
+
+ bool
+ operator!=(const _Self& __x) const
+ { return _M_node != __x._M_node; }
+
+ // The only member points to the %list element.
+ const _List_node_base<_Alloc>* _M_node;
+ };
+
+ template<typename _Val, typename _Alloc>
+ inline bool
+ operator==(const _List_iterator<_Val, _Alloc>& __x,
+ const _List_const_iterator<_Val, _Alloc>& __y)
+ { return __x._M_node == __y._M_node; }
+
+ template<typename _Val, typename _Alloc>
+ inline bool
+ operator!=(const _List_iterator<_Val, _Alloc>& __x,
+ const _List_const_iterator<_Val, _Alloc>& __y)
+ { return __x._M_node != __y._M_node; }
+
+
+ /**
+ * @if maint
+ * See bits/stl_deque.h's _Deque_base for an explanation.
+ * @endif
+ */
+ template<typename _Tp, typename _Alloc>
+ class _List_base
+ {
+ protected:
+ // NOTA BENE
+ // The stored instance is not actually of "allocator_type"'s
+ // type. Instead we rebind the type to
+ // Allocator<List_node<Tp>>, which according to [20.1.5]/4
+ // should probably be the same. List_node<Tp> is not the same
+ // size as Tp (it's two pointers larger), and specializations on
+ // Tp may go unused because List_node<Tp> is being bound
+ // instead.
+ //
+ // We put this to the test in the constructors and in
+ // get_allocator, where we use conversions between
+ // allocator_type and _Node_Alloc_type. The conversion is
+ // required by table 32 in [20.1.5].
+ typedef typename _Alloc::template rebind<_List_node<_Tp, _Alloc> >::other
+
+ _Node_Alloc_type;
+
+ struct _List_impl
+ : public _Node_Alloc_type {
+ _List_node_base<_Alloc> _M_node;
+ _List_impl (const _Node_Alloc_type& __a)
+ : _Node_Alloc_type(__a)
+ { }
+ };
+
+ _List_impl _M_impl;
+
+ _List_node<_Tp, _Alloc> *
+ _M_get_node()
+ { return _M_impl._Node_Alloc_type::allocate(1); }
+
+ void
+ _M_put_node(_List_node<_Tp, _Alloc> * __p)
+ { _M_impl._Node_Alloc_type::deallocate(__p, 1); }
+
+ public:
+ typedef _Node_Alloc_type 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.
+ ~_List_base()
+ { _M_clear(); }
+
+ void
+ _M_clear();
+
+ 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;
+ }
+ };
+
+ /**
+ * @brief A standard container with linear time access to elements,
+ * and fixed time insertion/deletion at any point in the sequence.
+ *
+ * @ingroup Containers
+ * @ingroup Sequences
+ *
+ * Meets the requirements of a container, a
+ * reversible container, and a
+ * sequence, including the
+ * optional sequence requirements with the
+ * %exception of @c at and @c operator[].
+ *
+ * This is a @e doubly @e linked %list. Traversal up and down the
+ * %list requires linear time, but adding and removing elements (or
+ * @e nodes) is done in constant time, regardless of where the
+ * change takes place. Unlike std::vector and std::deque,
+ * random-access iterators are not provided, so subscripting ( @c
+ * [] ) access is not allowed. For algorithms which only need
+ * sequential access, this lack makes no difference.
+ *
+ * Also unlike the other standard containers, std::list provides
+ * specialized algorithms %unique to linked lists, such as
+ * splicing, sorting, and in-place reversal.
+ *
+ * @if maint
+ * A couple points on memory allocation for list<Tp>:
+ *
+ * First, we never actually allocate a Tp, we allocate
+ * List_node<Tp>'s and trust [20.1.5]/4 to DTRT. This is to ensure
+ * that after elements from %list<X,Alloc1> are spliced into
+ * %list<X,Alloc2>, destroying the memory of the second %list is a
+ * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away.
+ *
+ * Second, a %list conceptually represented as
+ * @code
+ * A <---> B <---> C <---> D
+ * @endcode
+ * is actually circular; a link exists between A and D. The %list
+ * class holds (as its only data member) a private list::iterator
+ * pointing to @e D, not to @e A! To get to the head of the %list,
+ * we start at the tail and move forward by one. When this member
+ * iterator's next/previous pointers refer to itself, the %list is
+ * %empty. @endif
+ */
+ template<typename _Tp, typename _Alloc = allocator<_Tp> >
+ class list : protected _List_base<_Tp, _Alloc>
+ {
+ // concept requirements
+ __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+
+ typedef _List_base<_Tp, _Alloc> _Base;
+
+ public:
+ typedef _Tp value_type;
+ typedef typename _List_node<_Tp, _Alloc>::pointer pointer;
+ typedef typename _List_node<_Tp, _Alloc>::const_pointer const_pointer;
+ typedef typename _List_node<_Tp, _Alloc>::reference reference;
+ typedef typename _List_node<_Tp, _Alloc>::const_reference const_reference;
+ typedef _List_iterator<_Tp, _Alloc> iterator;
+ typedef _List_const_iterator<_Tp, _Alloc> const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef typename _Base::allocator_type allocator_type;
+
+ protected:
+ // Note that pointers-to-_Node's can be ctor-converted to
+ // iterator types.
+ typedef _List_node<_Tp, _Alloc> _Node;
+
+ /** @if maint
+ * One data member plus two memory-handling functions. If the
+ * _Alloc type requires separate instances, then one of those
+ * will also be included, accumulated from the topmost parent.
+ * @endif
+ */
+ using _Base::_M_impl;
+ using _Base::_M_put_node;
+ using _Base::_M_get_node;
+
+ /**
+ * @if maint
+ * @param x An instance of user data.
+ *
+ * Allocates space for a new node and constructs a copy of @a x in it.
+ * @endif
+ */
+ _Node*
+ _M_create_node(const value_type& __x)
+ {
+ _Node* __p = this->_M_get_node();
+ try
+ {
+ std::_Construct(&__p->_M_data, __x);
+ }
+ catch(...)
+ {
+ _M_put_node(__p);
+ __throw_exception_again;
+ }
+ return __p;
+ }
+
+ /**
+ * @if maint
+ * Allocates space for a new node and default-constructs a new
+ * instance of @c value_type in it.
+ * @endif
+ */
+ _Node*
+ _M_create_node()
+ {
+ _Node* __p = this->_M_get_node();
+ try
+ {
+ std::_Construct(&__p->_M_data);
+ }
+ catch(...)
+ {
+ _M_put_node(__p);
+ __throw_exception_again;
+ }
+ return __p;
+ }
+
+ public:
+ // [23.2.2.1] construct/copy/destroy
+ // (assign() and get_allocator() are also listed in this section)
+ /**
+ * @brief Default constructor creates no elements.
+ */
+ explicit
+ list(const allocator_type& __a = allocator_type())
+ : _Base(__a) { }
+
+ /**
+ * @brief Create a %list with copies of an exemplar element.
+ * @param n The number of elements to initially create.
+ * @param value An element to copy.
+ *
+ * This constructor fills the %list with @a n copies of @a value.
+ */
+ list(size_type __n, const value_type& __value,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ { this->insert(begin(), __n, __value); }
+
+ /**
+ * @brief Create a %list with default elements.
+ * @param n The number of elements to initially create.
+ *
+ * This constructor fills the %list with @a n copies of a
+ * default-constructed element.
+ */
+ explicit
+ list(size_type __n)
+ : _Base(allocator_type())
+ { this->insert(begin(), __n, value_type()); }
+
+ /**
+ * @brief %List copy constructor.
+ * @param x A %list of identical element and allocator types.
+ *
+ * The newly-created %list uses a copy of the allocation object used
+ * by @a x.
+ */
+ list(const list& __x)
+ : _Base(__x.get_allocator())
+ { this->insert(begin(), __x.begin(), __x.end()); }
+
+ /**
+ * @brief Builds a %list from a range.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ *
+ * Create a %list consisting of copies of the elements from
+ * [@a first,@a last). This is linear in N (where N is
+ * distance(@a first,@a last)).
+ *
+ * @if maint
+ * We don't need any dispatching tricks here, because insert does all of
+ * that anyway.
+ * @endif
+ */
+ template<typename _InputIterator>
+ list(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ { this->insert(begin(), __first, __last); }
+
+ /**
+ * No explicit dtor needed as the _Base dtor takes care of
+ * things. The _Base dtor only erases the elements, and note
+ * that if the elements themselves are pointers, the pointed-to
+ * memory is not touched in any way. Managing the pointer is
+ * the user's responsibilty.
+ */
+
+ /**
+ * @brief %List assignment operator.
+ * @param x A %list of identical element and allocator types.
+ *
+ * All the elements of @a x are copied, but unlike the copy
+ * constructor, the allocator object is not copied.
+ */
+ list&
+ operator=(const list& __x);
+
+ /**
+ * @brief Assigns a given value to a %list.
+ * @param n Number of elements to be assigned.
+ * @param val Value to be assigned.
+ *
+ * This function fills a %list with @a n copies of the given
+ * value. Note that the assignment completely changes the %list
+ * and that the resulting %list's size is the same as the number
+ * of elements assigned. Old data may be lost.
+ */
+ void
+ assign(size_type __n, const value_type& __val)
+ { _M_fill_assign(__n, __val); }
+
+ /**
+ * @brief Assigns a range to a %list.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ *
+ * This function fills a %list with copies of the elements in the
+ * range [@a first,@a last).
+ *
+ * Note that the assignment completely changes the %list and
+ * that the resulting %list's size is the same as the number of
+ * elements assigned. Old data may be lost.
+ */
+ template<typename _InputIterator>
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
+ // Check whether it's an integral type. If so, it's not an iterator.
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_assign_dispatch(__first, __last, _Integral());
+ }
+
+ /// Get a copy of the memory allocation object.
+ allocator_type
+ get_allocator() const
+ { return _Base::get_allocator(); }
+
+ // iterators
+ /**
+ * Returns a read/write iterator that points to the first element in the
+ * %list. Iteration is done in ordinary element order.
+ */
+ iterator
+ begin()
+ { return iterator(this->_M_impl._M_node._M_next); }
+
+ /**
+ * Returns a read-only (constant) iterator that points to the
+ * first element in the %list. Iteration is done in ordinary
+ * element order.
+ */
+ const_iterator
+ begin() const
+ { return const_iterator(this->_M_impl._M_node._M_next); }
+
+ /**
+ * Returns a read/write iterator that points one past the last
+ * element in the %list. Iteration is done in ordinary element
+ * order.
+ */
+ iterator
+ end() { return &this->_M_impl._M_node; }
+
+ /**
+ * Returns a read-only (constant) iterator that points one past
+ * the last element in the %list. Iteration is done in ordinary
+ * element order.
+ */
+ const_iterator
+ end() const
+ { return &this->_M_impl._M_node; }
+
+ /**
+ * Returns a read/write reverse iterator that points to the last
+ * element in the %list. Iteration is done in reverse element
+ * order.
+ */
+ reverse_iterator
+ rbegin()
+ { return reverse_iterator(end()); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to
+ * the last element in the %list. Iteration is done in reverse
+ * element order.
+ */
+ const_reverse_iterator
+ rbegin() const
+ { return const_reverse_iterator(end()); }
+
+ /**
+ * Returns a read/write reverse iterator that points to one
+ * before the first element in the %list. Iteration is done in
+ * reverse element order.
+ */
+ reverse_iterator
+ rend()
+ { return reverse_iterator(begin()); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to one
+ * before the first element in the %list. Iteration is done in reverse
+ * element order.
+ */
+ const_reverse_iterator
+ rend() const
+ { return const_reverse_iterator(begin()); }
+
+ // [23.2.2.2] capacity
+ /**
+ * Returns true if the %list is empty. (Thus begin() would equal
+ * end().)
+ */
+ 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
+ size() const
+ { return std::distance(begin(), end()); }
+
+ /** Returns the size() of the largest possible %list. */
+ size_type
+ max_size() const
+ { return size_type(-1); }
+
+ /**
+ * @brief Resizes the %list to the specified number of elements.
+ * @param new_size Number of elements the %list should contain.
+ * @param x Data with which new elements should be populated.
+ *
+ * This function will %resize the %list to the specified number
+ * of elements. If the number is smaller than the %list's
+ * current size the %list is truncated, otherwise the %list is
+ * extended and new elements are populated with given data.
+ */
+ void
+ resize(size_type __new_size, const value_type& __x);
+
+ /**
+ * @brief Resizes the %list to the specified number of elements.
+ * @param new_size Number of elements the %list should contain.
+ *
+ * This function will resize the %list to the specified number of
+ * elements. If the number is smaller than the %list's current
+ * size the %list is truncated, otherwise the %list is extended
+ * and new elements are default-constructed.
+ */
+ void
+ resize(size_type __new_size)
+ { this->resize(__new_size, value_type()); }
+
+ // element access
+ /**
+ * Returns a read/write reference to the data at the first
+ * element of the %list.
+ */
+ reference
+ front()
+ { return *begin(); }
+
+ /**
+ * Returns a read-only (constant) reference to the data at the first
+ * element of the %list.
+ */
+ const_reference
+ front() const
+ { return *begin(); }
+
+ /**
+ * Returns a read/write reference to the data at the last element
+ * of the %list.
+ */
+ reference
+ back()
+ { return *(--end()); }
+
+ /**
+ * Returns a read-only (constant) reference to the data at the last
+ * element of the %list.
+ */
+ const_reference
+ back() const
+ { return *(--end()); }
+
+ // [23.2.2.3] modifiers
+ /**
+ * @brief Add data to the front of the %list.
+ * @param x Data to be added.
+ *
+ * This is a typical stack operation. The function creates an
+ * element at the front of the %list and assigns the given data
+ * to it. Due to the nature of a %list this operation can be
+ * done in constant time, and does not invalidate iterators and
+ * references.
+ */
+ void
+ push_front(const value_type& __x)
+ { this->_M_insert(begin(), __x); }
+
+ /**
+ * @brief Removes first element.
+ *
+ * This is a typical stack operation. It shrinks the %list by
+ * one. Due to the nature of a %list this operation can be done
+ * in constant time, and only invalidates iterators/references to
+ * the element being removed.
+ *
+ * Note that no data is returned, and if the first element's data
+ * is needed, it should be retrieved before pop_front() is
+ * called.
+ */
+ void
+ pop_front()
+ { this->_M_erase(begin()); }
+
+ /**
+ * @brief Add data to the end of the %list.
+ * @param x Data to be added.
+ *
+ * This is a typical stack operation. The function creates an
+ * element at the end of the %list and assigns the given data to
+ * it. Due to the nature of a %list this operation can be done
+ * in constant time, and does not invalidate iterators and
+ * references.
+ */
+ void
+ push_back(const value_type& __x)
+ { this->_M_insert(end(), __x); }
+
+ /**
+ * @brief Removes last element.
+ *
+ * This is a typical stack operation. It shrinks the %list by
+ * one. Due to the nature of a %list this operation can be done
+ * in constant time, and only invalidates iterators/references to
+ * the element being removed.
+ *
+ * Note that no data is returned, and if the last element's data
+ * is needed, it should be retrieved before pop_back() is called.
+ */
+ void
+ pop_back()
+ { this->_M_erase(this->_M_impl._M_node._M_prev); }
+
+ /**
+ * @brief Inserts given value into %list before specified iterator.
+ * @param position An iterator into the %list.
+ * @param x Data to be inserted.
+ * @return An iterator that points to the inserted data.
+ *
+ * This function will insert a copy of the given value before
+ * the specified location. Due to the nature of a %list this
+ * operation can be done in constant time, and does not
+ * invalidate iterators and references.
+ */
+ iterator
+ insert(iterator __position, const value_type& __x);
+
+ /**
+ * @brief Inserts a number of copies of given data into the %list.
+ * @param position An iterator into the %list.
+ * @param n Number of elements to be inserted.
+ * @param x Data to be inserted.
+ *
+ * This function will insert a specified number of copies of the
+ * given data before the location specified by @a position.
+ *
+ * Due to the nature of a %list this operation can be done in
+ * constant time, and does not invalidate iterators and
+ * references.
+ */
+ void
+ insert(iterator __position, size_type __n, const value_type& __x)
+ { _M_fill_insert(__position, __n, __x); }
+
+ /**
+ * @brief Inserts a range into the %list.
+ * @param position An iterator into the %list.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ *
+ * This function will insert copies of the data in the range [@a
+ * first,@a last) into the %list before the location specified by
+ * @a position.
+ *
+ * Due to the nature of a %list this operation can be done in
+ * constant time, and does not invalidate iterators and
+ * references.
+ */
+ template<typename _InputIterator>
+ void
+ insert(iterator __position, _InputIterator __first,
+ _InputIterator __last)
+ {
+ // Check whether it's an integral type. If so, it's not an iterator.
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_insert_dispatch(__position, __first, __last, _Integral());
+ }
+
+ /**
+ * @brief Remove element at given position.
+ * @param position Iterator pointing to element to be erased.
+ * @return An iterator pointing to the next element (or end()).
+ *
+ * This function will erase the element at the given position and thus
+ * shorten the %list by one.
+ *
+ * Due to the nature of a %list this operation can be done in
+ * constant time, and only invalidates iterators/references to
+ * the element being removed. The user is also cautioned that
+ * this function only erases the element, and that if the element
+ * is itself a pointer, the pointed-to memory is not touched in
+ * any way. Managing the pointer is the user's responsibilty.
+ */
+ iterator
+ erase(iterator __position);
+
+ /**
+ * @brief Remove a range of elements.
+ * @param first Iterator pointing to the first element to be erased.
+ * @param last Iterator pointing to one past the last element to be
+ * erased.
+ * @return An iterator pointing to the element pointed to by @a last
+ * prior to erasing (or end()).
+ *
+ * This function will erase the elements in the range @a
+ * [first,last) and shorten the %list accordingly.
+ *
+ * Due to the nature of a %list this operation can be done in
+ * constant time, and only invalidates iterators/references to
+ * the element being removed. The user is also cautioned that
+ * this function only erases the elements, and that if the
+ * elements themselves are pointers, the pointed-to memory is not
+ * touched in any way. Managing the pointer is the user's
+ * responsibilty.
+ */
+ iterator
+ erase(iterator __first, iterator __last)
+ {
+ while (__first != __last)
+ __first = erase(__first);
+ return __last;
+ }
+
+ /**
+ * @brief Swaps data with another %list.
+ * @param x A %list of the same element and allocator types.
+ *
+ * This exchanges the elements between two lists in constant
+ * time. Note that the global std::swap() function is
+ * specialized such that std::swap(l1,l2) will feed to this
+ * function.
+ */
+ void
+ swap(list& __x)
+ { _List_node_base<_Alloc>::swap(this->_M_impl._M_node,__x._M_impl._M_node); }
+
+ /**
+ * Erases all the elements. Note that this function only erases
+ * the elements, and that if the elements themselves are
+ * pointers, the pointed-to memory is not touched in any way.
+ * Managing the pointer is the user's responsibilty.
+ */
+ void
+ clear()
+ {
+ _Base::_M_clear();
+ _Base::_M_init();
+ }
+
+ // [23.2.2.4] list operations
+ /**
+ * @brief Insert contents of another %list.
+ * @param position Iterator referencing the element to insert before.
+ * @param x Source list.
+ *
+ * The elements of @a x are inserted in constant time in front of
+ * the element referenced by @a position. @a x becomes an empty
+ * list.
+ */
+ void
+ splice(iterator __position, list& __x)
+ {
+ if (!__x.empty())
+ this->_M_transfer(__position, __x.begin(), __x.end());
+ }
+
+ /**
+ * @brief Insert element from another %list.
+ * @param position Iterator referencing the element to insert before.
+ * @param x Source list.
+ * @param i Iterator referencing the element to move.
+ *
+ * Removes the element in list @a x referenced by @a i and
+ * inserts it into the current list before @a position.
+ */
+ void
+ splice(iterator __position, list&, iterator __i)
+ {
+ iterator __j = __i;
+ ++__j;
+ if (__position == __i || __position == __j)
+ return;
+ this->_M_transfer(__position, __i, __j);
+ }
+
+ /**
+ * @brief Insert range from another %list.
+ * @param position Iterator referencing the element to insert before.
+ * @param x Source list.
+ * @param first Iterator referencing the start of range in x.
+ * @param last Iterator referencing the end of range in x.
+ *
+ * Removes elements in the range [first,last) and inserts them
+ * before @a position in constant time.
+ *
+ * Undefined if @a position is in [first,last).
+ */
+ void
+ splice(iterator __position, list&, iterator __first, iterator __last)
+ {
+ if (__first != __last)
+ this->_M_transfer(__position, __first, __last);
+ }
+
+ /**
+ * @brief Remove all elements equal to value.
+ * @param value The value to remove.
+ *
+ * Removes every element in the list equal to @a value.
+ * Remaining elements stay in list order. Note that this
+ * function only erases the elements, and that if the elements
+ * themselves are pointers, the pointed-to memory is not
+ * touched in any way. Managing the pointer is the user's
+ * responsibilty.
+ */
+ void
+ remove(const _Tp& __value);
+
+ /**
+ * @brief Remove all elements satisfying a predicate.
+ * @param Predicate Unary predicate function or object.
+ *
+ * Removes every element in the list for which the predicate
+ * returns true. Remaining elements stay in list order. Note
+ * that this function only erases the elements, and that if the
+ * elements themselves are pointers, the pointed-to memory is
+ * not touched in any way. Managing the pointer is the user's
+ * responsibilty.
+ */
+ template<typename _Predicate>
+ void
+ remove_if(_Predicate);
+
+ /**
+ * @brief Remove consecutive duplicate elements.
+ *
+ * For each consecutive set of elements with the same value,
+ * remove all but the first one. Remaining elements stay in
+ * list order. Note that this function only erases the
+ * elements, and that if the elements themselves are pointers,
+ * the pointed-to memory is not touched in any way. Managing
+ * the pointer is the user's responsibilty.
+ */
+ void
+ unique();
+
+ /**
+ * @brief Remove consecutive elements satisfying a predicate.
+ * @param BinaryPredicate Binary predicate function or object.
+ *
+ * For each consecutive set of elements [first,last) that
+ * satisfy predicate(first,i) where i is an iterator in
+ * [first,last), remove all but the first one. Remaining
+ * elements stay in list order. Note that this function only
+ * erases the elements, and that if the elements themselves are
+ * pointers, the pointed-to memory is not touched in any way.
+ * Managing the pointer is the user's responsibilty.
+ */
+ template<typename _BinaryPredicate>
+ void
+ unique(_BinaryPredicate);
+
+ /**
+ * @brief Merge sorted lists.
+ * @param x Sorted list to merge.
+ *
+ * Assumes that both @a x and this list are sorted according to
+ * operator<(). Merges elements of @a x into this list in
+ * sorted order, leaving @a x empty when complete. Elements in
+ * this list precede elements in @a x that are equal.
+ */
+ void
+ merge(list& __x);
+
+ /**
+ * @brief Merge sorted lists according to comparison function.
+ * @param x Sorted list to merge.
+ * @param StrictWeakOrdering Comparison function definining
+ * sort order.
+ *
+ * Assumes that both @a x and this list are sorted according to
+ * StrictWeakOrdering. Merges elements of @a x into this list
+ * in sorted order, leaving @a x empty when complete. Elements
+ * in this list precede elements in @a x that are equivalent
+ * according to StrictWeakOrdering().
+ */
+ template<typename _StrictWeakOrdering>
+ void
+ merge(list&, _StrictWeakOrdering);
+
+ /**
+ * @brief Reverse the elements in list.
+ *
+ * Reverse the order of elements in the list in linear time.
+ */
+ void
+ reverse()
+ { this->_M_impl._M_node.reverse(); }
+
+ /**
+ * @brief Sort the elements.
+ *
+ * Sorts the elements of this list in NlogN time. Equivalent
+ * elements remain in list order.
+ */
+ void
+ sort();
+
+ /**
+ * @brief Sort the elements according to comparison function.
+ *
+ * Sorts the elements of this list in NlogN time. Equivalent
+ * elements remain in list order.
+ */
+ template<typename _StrictWeakOrdering>
+ void
+ sort(_StrictWeakOrdering);
+
+ protected:
+ // Internal assign functions follow.
+
+ // Called by the range assign to implement [23.1.1]/9
+ template<typename _Integer>
+ void
+ _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+ {
+ _M_fill_assign(static_cast<size_type>(__n),
+ static_cast<value_type>(__val));
+ }
+
+ // Called by the range assign to implement [23.1.1]/9
+ template<typename _InputIterator>
+ void
+ _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
+ __false_type);
+
+ // Called by assign(n,t), and the range assign when it turns out
+ // to be the same thing.
+ void
+ _M_fill_assign(size_type __n, const value_type& __val);
+
+
+ // Internal insert functions follow.
+
+ // Called by the range insert to implement [23.1.1]/9
+ template<typename _Integer>
+ void
+ _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
+ __true_type)
+ {
+ _M_fill_insert(__pos, static_cast<size_type>(__n),
+ static_cast<value_type>(__x));
+ }
+
+ // Called by the range insert to implement [23.1.1]/9
+ template<typename _InputIterator>
+ void
+ _M_insert_dispatch(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ __false_type)
+ {
+ for ( ; __first != __last; ++__first)
+ _M_insert(__pos, *__first);
+ }
+
+ // Called by insert(p,n,x), and the range insert when it turns out
+ // to be the same thing.
+ void
+ _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
+ {
+ for ( ; __n > 0; --__n)
+ _M_insert(__pos, __x);
+ }
+
+
+ // Moves the elements from [first,last) before position.
+ void
+ _M_transfer(iterator __position, iterator __first, iterator __last)
+ { __position._M_node->transfer(__first._M_node,__last._M_node); }
+
+ // Inserts new element at position given and with value given.
+ void
+ _M_insert(iterator __position, const value_type& __x)
+ {
+ _Node* __tmp = _M_create_node(__x);
+ __tmp->hook(__position._M_node);
+ }
+
+ // Erases element at position given.
+ void
+ _M_erase(iterator __position)
+ {
+ __position._M_node->unhook();
+/**
+ FIXME: distinguish with raw pointers
+
+ _Node* __n = static_cast<_Node*>(__position._M_node);
+ std::_Destroy(&__n->_M_data);
+ _M_put_node(__n);
+*/
+ }
+ };
+
+ /**
+ * @brief List equality comparison.
+ * @param x A %list.
+ * @param y A %list of the same type as @a x.
+ * @return True iff the size and elements of the lists are equal.
+ *
+ * This is an equivalence relation. It is linear in the size of
+ * the lists. Lists are considered equivalent if their sizes are
+ * equal, and if corresponding elements compare equal.
+ */
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ {
+ typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
+ const_iterator __end1 = __x.end();
+ const_iterator __end2 = __y.end();
+
+ const_iterator __i1 = __x.begin();
+ const_iterator __i2 = __y.begin();
+ while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2)
+ {
+ ++__i1;
+ ++__i2;
+ }
+ return __i1 == __end1 && __i2 == __end2;
+ }
+
+ /**
+ * @brief List ordering relation.
+ * @param x A %list.
+ * @param y A %list of the same type as @a x.
+ * @return True iff @a x is lexicographically less than @a y.
+ *
+ * This is a total ordering relation. It is linear in the size of the
+ * lists. The elements must be comparable with @c <.
+ *
+ * See std::lexicographical_compare() for how the determination is made.
+ */
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return std::lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end()); }
+
+ /// Based on operator==
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return !(__x == __y); }
+
+ /// Based on operator<
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return __y < __x; }
+
+ /// Based on operator<
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return !(__y < __x); }
+
+ /// Based on operator<
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return !(__x < __y); }
+
+ /// See std::list::swap().
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
+ { __x.swap(__y); }
+} // namespace std
+
+#endif /* _LIST_H */
+

Added: sandbox/shifted_ptr/bits/stl_list.h.patch
==============================================================================
--- (empty file)
+++ sandbox/shifted_ptr/bits/stl_list.h.patch 2008-07-22 05:14:39 EDT (Tue, 22 Jul 2008)
@@ -0,0 +1,316 @@
+--- /local/include/c++/3.4.5/bits/stl_list.h Wed Jan 18 11:06:54 2006
++++ stl_list.h Tue Jul 22 02:11:25 2008
+@@ -51,10 +51,21 @@
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
++/**
++ Copyright (c) 2008 Phil Bouchard <phil_at_[hidden]>.
++
++ Distributed under the Boost Software License, Version 1.0.
++
++ See accompanying file LICENSE_1_0.txt or copy at
++ http://www.boost.org/LICENSE_1_0.txt
++
++ See http://www.boost.org/libs/smart_ptr/doc/index.html for documentation.
++*/
++
+ /** @file stl_list.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+@@ -69,62 +80,77 @@
+ // latter publicly inherits from the former in an effort to reduce code
+ // duplication. This results in some "needless" static_cast'ing later on,
+ // but it's all safe downcasting.
+
+ /// @if maint Common part of a node in the %list. @endif
++ template<typename _Alloc>
+ struct _List_node_base
+ {
+- _List_node_base* _M_next; ///< Self-explanatory
+- _List_node_base* _M_prev; ///< Self-explanatory
++ typedef typename _Alloc::template rebind<_List_node_base<_Alloc> >::other _Node_Alloc_type;
++
++ typedef typename _Node_Alloc_type::pointer pointer;
++ typedef typename _Node_Alloc_type::const_pointer const_pointer;
++ typedef typename _Node_Alloc_type::reference reference;
++ typedef typename _Node_Alloc_type::const_reference const_reference;
++
++ pointer _M_next; ///< Self-explanatory
++ pointer _M_prev; ///< Self-explanatory
+
+ static void
+ swap(_List_node_base& __x, _List_node_base& __y);
+
+ void
+- transfer(_List_node_base * const __first,
+- _List_node_base * const __last);
++ transfer(pointer const & __first,
++ pointer const & __last);
+
+ void
+ reverse();
+
+ void
+- hook(_List_node_base * const __position);
++ hook(pointer const & __position);
+
+ void
+ unhook();
+ };
+
+ /// @if maint An actual node in the %list. @endif
+- template<typename _Tp>
+- struct _List_node : public _List_node_base
++ template<typename _Tp, typename _Alloc>
++ struct _List_node : public _List_node_base<_Alloc>
+ {
++ typedef typename _Alloc::template rebind<_List_node<_Tp, _Alloc> >::other _Node_Alloc_type;
++
++ typedef typename _Node_Alloc_type::pointer pointer;
++ typedef typename _Node_Alloc_type::const_pointer const_pointer;
++ typedef typename _Node_Alloc_type::reference reference;
++ typedef typename _Node_Alloc_type::const_reference const_reference;
++
+ _Tp _M_data; ///< User's data.
+ };
+
+ /**
+ * @brief A list::iterator.
+ *
+ * @if maint
+ * All the functions are op overloads.
+ * @endif
+ */
+- template<typename _Tp>
++ template<typename _Tp, typename _Alloc>
+ struct _List_iterator
+ {
+- typedef _List_iterator<_Tp> _Self;
+- typedef _List_node<_Tp> _Node;
++ typedef _List_iterator<_Tp, _Alloc> _Self;
++ typedef _List_node<_Tp, _Alloc> _Node;
+
+ typedef ptrdiff_t difference_type;
+ typedef bidirectional_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef _Tp* pointer;
+ typedef _Tp& reference;
+
+ _List_iterator()
+ : _M_node() { }
+
+- _List_iterator(_List_node_base* __x)
++ _List_iterator(_List_node_base<_Alloc>* __x)
+ : _M_node(__x) { }
+
+ // Must downcast from List_node_base to _List_node to get to _M_data.
+ reference
+ operator*() const
+@@ -171,37 +197,37 @@
+ bool
+ operator!=(const _Self& __x) const
+ { return _M_node != __x._M_node; }
+
+ // The only member points to the %list element.
+- _List_node_base* _M_node;
++ _List_node_base<_Alloc>* _M_node;
+ };
+
+ /**
+ * @brief A list::const_iterator.
+ *
+ * @if maint
+ * All the functions are op overloads.
+ * @endif
+ */
+- template<typename _Tp>
++ template<typename _Tp, typename _Alloc>
+ struct _List_const_iterator
+ {
+- typedef _List_const_iterator<_Tp> _Self;
+- typedef const _List_node<_Tp> _Node;
+- typedef _List_iterator<_Tp> iterator;
++ typedef _List_const_iterator<_Tp, _Alloc> _Self;
++ typedef const _List_node<_Tp, _Alloc> _Node;
++ typedef _List_iterator<_Tp, _Alloc> iterator;
+
+ typedef ptrdiff_t difference_type;
+ typedef bidirectional_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef const _Tp* pointer;
+ typedef const _Tp& reference;
+
+ _List_const_iterator()
+ : _M_node() { }
+
+- _List_const_iterator(const _List_node_base* __x)
++ _List_const_iterator(const _List_node_base<_Alloc>* __x)
+ : _M_node(__x) { }
+
+ _List_const_iterator(const iterator& __x)
+ : _M_node(__x._M_node) { }
+
+@@ -252,23 +278,23 @@
+ bool
+ operator!=(const _Self& __x) const
+ { return _M_node != __x._M_node; }
+
+ // The only member points to the %list element.
+- const _List_node_base* _M_node;
++ const _List_node_base<_Alloc>* _M_node;
+ };
+
+- template<typename _Val>
++ template<typename _Val, typename _Alloc>
+ inline bool
+- operator==(const _List_iterator<_Val>& __x,
+- const _List_const_iterator<_Val>& __y)
++ operator==(const _List_iterator<_Val, _Alloc>& __x,
++ const _List_const_iterator<_Val, _Alloc>& __y)
+ { return __x._M_node == __y._M_node; }
+
+- template<typename _Val>
++ template<typename _Val, typename _Alloc>
+ inline bool
+- operator!=(const _List_iterator<_Val>& __x,
+- const _List_const_iterator<_Val>& __y)
++ operator!=(const _List_iterator<_Val, _Alloc>& __x,
++ const _List_const_iterator<_Val, _Alloc>& __y)
+ { return __x._M_node != __y._M_node; }
+
+
+ /**
+ * @if maint
+@@ -290,34 +316,34 @@
+ //
+ // We put this to the test in the constructors and in
+ // get_allocator, where we use conversions between
+ // allocator_type and _Node_Alloc_type. The conversion is
+ // required by table 32 in [20.1.5].
+- typedef typename _Alloc::template rebind<_List_node<_Tp> >::other
++ typedef typename _Alloc::template rebind<_List_node<_Tp, _Alloc> >::other
+
+ _Node_Alloc_type;
+
+ struct _List_impl
+ : public _Node_Alloc_type {
+- _List_node_base _M_node;
++ _List_node_base<_Alloc> _M_node;
+ _List_impl (const _Node_Alloc_type& __a)
+ : _Node_Alloc_type(__a)
+ { }
+ };
+
+ _List_impl _M_impl;
+
+- _List_node<_Tp>*
++ _List_node<_Tp, _Alloc> *
+ _M_get_node()
+ { return _M_impl._Node_Alloc_type::allocate(1); }
+
+ void
+- _M_put_node(_List_node<_Tp>* __p)
++ _M_put_node(_List_node<_Tp, _Alloc> * __p)
+ { _M_impl._Node_Alloc_type::deallocate(__p, 1); }
+
+ public:
+- typedef _Alloc allocator_type;
++ typedef _Node_Alloc_type allocator_type;
+
+ allocator_type
+ get_allocator() const
+ { return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); }
+
+@@ -393,26 +419,26 @@
+
+ typedef _List_base<_Tp, _Alloc> _Base;
+
+ public:
+ typedef _Tp value_type;
+- typedef typename _Alloc::pointer pointer;
+- typedef typename _Alloc::const_pointer const_pointer;
+- typedef typename _Alloc::reference reference;
+- typedef typename _Alloc::const_reference const_reference;
+- typedef _List_iterator<_Tp> iterator;
+- typedef _List_const_iterator<_Tp> const_iterator;
++ typedef typename _List_node<_Tp, _Alloc>::pointer pointer;
++ typedef typename _List_node<_Tp, _Alloc>::const_pointer const_pointer;
++ typedef typename _List_node<_Tp, _Alloc>::reference reference;
++ typedef typename _List_node<_Tp, _Alloc>::const_reference const_reference;
++ typedef _List_iterator<_Tp, _Alloc> iterator;
++ typedef _List_const_iterator<_Tp, _Alloc> const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef typename _Base::allocator_type allocator_type;
+
+ protected:
+ // Note that pointers-to-_Node's can be ctor-converted to
+ // iterator types.
+- typedef _List_node<_Tp> _Node;
++ typedef _List_node<_Tp, _Alloc> _Node;
+
+ /** @if maint
+ * One data member plus two memory-handling functions. If the
+ * _Alloc type requires separate instances, then one of those
+ * will also be included, accumulated from the topmost parent.
+@@ -595,20 +621,20 @@
+ * Returns a read/write iterator that points to the first element in the
+ * %list. Iteration is done in ordinary element order.
+ */
+ iterator
+ begin()
+- { return this->_M_impl._M_node._M_next; }
++ { return iterator(this->_M_impl._M_node._M_next); }
+
+ /**
+ * Returns a read-only (constant) iterator that points to the
+ * first element in the %list. Iteration is done in ordinary
+ * element order.
+ */
+ const_iterator
+ begin() const
+- { return this->_M_impl._M_node._M_next; }
++ { return const_iterator(this->_M_impl._M_node._M_next); }
+
+ /**
+ * Returns a read/write iterator that points one past the last
+ * element in the %list. Iteration is done in ordinary element
+ * order.
+@@ -908,11 +934,11 @@
+ * specialized such that std::swap(l1,l2) will feed to this
+ * function.
+ */
+ void
+ swap(list& __x)
+- { _List_node_base::swap(this->_M_impl._M_node,__x._M_impl._M_node); }
++ { _List_node_base<_Alloc>::swap(this->_M_impl._M_node,__x._M_impl._M_node); }
+
+ /**
+ * Erases all the elements. Note that this function only erases
+ * the elements, and that if the elements themselves are
+ * pointers, the pointed-to memory is not touched in any way.
+@@ -1167,13 +1193,17 @@
+ // Erases element at position given.
+ void
+ _M_erase(iterator __position)
+ {
+ __position._M_node->unhook();
++/**
++ FIXME: distinguish with raw pointers
++
+ _Node* __n = static_cast<_Node*>(__position._M_node);
+ std::_Destroy(&__n->_M_data);
+ _M_put_node(__n);
++*/
+ }
+ };
+
+ /**
+ * @brief List equality comparison.


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk