1130812Smarcel// std::list utilities implementation -*- C++ -*-
2130812Smarcel
3130812Smarcel// Copyright (C) 2003, 2005 Free Software Foundation, Inc.
4130812Smarcel//
5130812Smarcel// This file is part of the GNU ISO C++ Library.  This library is free
6130812Smarcel// software; you can redistribute it and/or modify it under the
7130812Smarcel// terms of the GNU General Public License as published by the
8130812Smarcel// Free Software Foundation; either version 2, or (at your option)
9130812Smarcel// any later version.
10130812Smarcel
11130812Smarcel// This library is distributed in the hope that it will be useful,
12130812Smarcel// but WITHOUT ANY WARRANTY; without even the implied warranty of
13130812Smarcel// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14130812Smarcel// GNU General Public License for more details.
15130812Smarcel
16130812Smarcel// You should have received a copy of the GNU General Public License along
17130812Smarcel// with this library; see the file COPYING.  If not, write to the Free
18130812Smarcel// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19130812Smarcel// USA.
20130812Smarcel
21130812Smarcel// As a special exception, you may use this file as part of a free software
22130812Smarcel// library without restriction.  Specifically, if other files instantiate
23130812Smarcel// templates or use macros or inline functions from this file, or you compile
24130812Smarcel// this file and link it with other files to produce an executable, this
25130812Smarcel// file does not by itself cause the resulting executable to be covered by
26130812Smarcel// the GNU General Public License.  This exception does not however
27130812Smarcel// invalidate any other reasons why the executable file might be covered by
28130812Smarcel// the GNU General Public License.
29130812Smarcel
30130812Smarcel/*
31130812Smarcel *
32130812Smarcel * Copyright (c) 1994
33130812Smarcel * Hewlett-Packard Company
34130812Smarcel *
35130812Smarcel * Permission to use, copy, modify, distribute and sell this software
36130812Smarcel * and its documentation for any purpose is hereby granted without fee,
37130812Smarcel * provided that the above copyright notice appear in all copies and
38130812Smarcel * that both that copyright notice and this permission notice appear
39130812Smarcel * in supporting documentation.  Hewlett-Packard Company makes no
40130812Smarcel * representations about the suitability of this software for any
41130812Smarcel * purpose.  It is provided "as is" without express or implied warranty.
42130812Smarcel *
43130812Smarcel *
44130812Smarcel * Copyright (c) 1996,1997
45130812Smarcel * Silicon Graphics Computer Systems, Inc.
46130812Smarcel *
47130812Smarcel * Permission to use, copy, modify, distribute and sell this software
48130812Smarcel * and its documentation for any purpose is hereby granted without fee,
49130812Smarcel * provided that the above copyright notice appear in all copies and
50130812Smarcel * that both that copyright notice and this permission notice appear
51130812Smarcel * in supporting documentation.  Silicon Graphics makes no
52130812Smarcel * representations about the suitability of this software for any
53130812Smarcel * purpose.  It is provided "as is" without express or implied warranty.
54130812Smarcel */
55130812Smarcel
56130812Smarcel#include <list>
57130812Smarcel
58130812Smarcel_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
59130812Smarcel
60130812Smarcel  void
61130812Smarcel  _List_node_base::swap(_List_node_base& __x, _List_node_base& __y)
62130812Smarcel  {
63130812Smarcel    if ( __x._M_next != &__x )
64130812Smarcel    {
65130812Smarcel      if ( __y._M_next != &__y )
66130812Smarcel      {
67130812Smarcel        // Both __x and __y are not empty.
68130812Smarcel        std::swap(__x._M_next,__y._M_next);
69130812Smarcel        std::swap(__x._M_prev,__y._M_prev);
70130812Smarcel        __x._M_next->_M_prev = __x._M_prev->_M_next = &__x;
71130812Smarcel        __y._M_next->_M_prev = __y._M_prev->_M_next = &__y;
72130812Smarcel      }
73130812Smarcel      else
74130812Smarcel      {
75130812Smarcel        // __x is not empty, __y is empty.
76130812Smarcel        __y._M_next = __x._M_next;
77130812Smarcel        __y._M_prev = __x._M_prev;
78130812Smarcel        __y._M_next->_M_prev = __y._M_prev->_M_next = &__y;
79130812Smarcel        __x._M_next = __x._M_prev = &__x;
80130812Smarcel      }
81130812Smarcel    }
82130812Smarcel    else if ( __y._M_next != &__y )
83130812Smarcel    {
84130812Smarcel      // __x is empty, __y is not empty.
85130812Smarcel      __x._M_next = __y._M_next;
86130812Smarcel      __x._M_prev = __y._M_prev;
87130812Smarcel      __x._M_next->_M_prev = __x._M_prev->_M_next = &__x;
88130812Smarcel      __y._M_next = __y._M_prev = &__y;
89130812Smarcel    }
90130812Smarcel  }
91130812Smarcel
92130812Smarcel  void
93130812Smarcel  _List_node_base::transfer(_List_node_base * const __first,
94130812Smarcel                            _List_node_base * const __last)
95130812Smarcel  {
96130812Smarcel    if (this != __last)
97130812Smarcel    {
98130812Smarcel      // Remove [first, last) from its old position.
99130812Smarcel      __last->_M_prev->_M_next  = this;
100130812Smarcel      __first->_M_prev->_M_next = __last;
101130812Smarcel      this->_M_prev->_M_next    = __first;
102130812Smarcel
103130812Smarcel      // Splice [first, last) into its new position.
104130812Smarcel      _List_node_base* const __tmp = this->_M_prev;
105130812Smarcel      this->_M_prev                = __last->_M_prev;
106130812Smarcel      __last->_M_prev              = __first->_M_prev;
107130812Smarcel      __first->_M_prev             = __tmp;
108130812Smarcel    }
109130812Smarcel  }
110130812Smarcel
111130812Smarcel  void
112130812Smarcel  _List_node_base::reverse()
113130812Smarcel  {
114130812Smarcel    _List_node_base* __tmp = this;
115130812Smarcel    do
116130812Smarcel    {
117130812Smarcel      std::swap(__tmp->_M_next, __tmp->_M_prev);
118130812Smarcel      __tmp = __tmp->_M_prev;     // Old next node is now prev.
119130812Smarcel    }
120130812Smarcel    while (__tmp != this);
121130812Smarcel  }
122130812Smarcel
123130812Smarcel  void
124130812Smarcel  _List_node_base::hook(_List_node_base* const __position)
125130812Smarcel  {
126130812Smarcel    this->_M_next = __position;
127130812Smarcel    this->_M_prev = __position->_M_prev;
128130812Smarcel    __position->_M_prev->_M_next = this;
129130812Smarcel    __position->_M_prev = this;
130130812Smarcel  }
131130812Smarcel
132130812Smarcel  void
133130812Smarcel  _List_node_base::unhook()
134130812Smarcel  {
135130812Smarcel    _List_node_base* const __next_node = this->_M_next;
136130812Smarcel    _List_node_base* const __prev_node = this->_M_prev;
137130812Smarcel    __prev_node->_M_next = __next_node;
138130812Smarcel    __next_node->_M_prev = __prev_node;
139130812Smarcel  }
140130812Smarcel
141130812Smarcel_GLIBCXX_END_NESTED_NAMESPACE
142130812Smarcel