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