/* * Copyright (c) 1995, 1996 Gunther Schadow. All rights reserved. * * This program 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 of the License, or * (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "pg_config.h" IDENT("@(#) RepeatBase.cc (Gunther Schadow) 12/19/96"); #pragma implementation #include "RepeatBase.h" #include "exception.h" #include "logfile.h" RepeatBase::RepeatBase(const RepeatBase &l) : PGObject(l.subclass(), 0) { const RepeatBase *p = &l; RepeatBase *q = this; while(p->_car != NULL) { q->_car = p->ctora(p->_car); q->_cdr = p->ctord(); q = q->_cdr; p = p->_cdr; } q->_car = NULL; q->_cdr = NULL; } RepeatBase::~RepeatBase() { if(_car!=NULL) { delete _car; _car = NULL; } if(_cdr!=NULL) { delete _cdr; // this is a recursion! _cdr = NULL; } } void RepeatBase::unset() { if(_car!=NULL) { delete _car; _car = NULL; } if(_cdr!=NULL) { delete _cdr; _cdr = NULL; } } PGObject& RepeatBase::operator [] (u_int i) { RepeatBase *p = this; while(i-- > 0) { if(p->_car == NULL) { p->_car = p->ctora(); p->_cdr = p->ctord(); } p = p->_cdr; } if(p->_car == NULL) { p->_car = p->ctora(); p->_cdr = p->ctord(); } return *p->_car; } PGObject &RepeatBase::prepend(const PGObject &x) { RepeatBase *p = ctord(); // a new container p->_car = _car; // gets my content p->_cdr = _cdr; // and my successor _car = ctora(&x); // while I will have a new content _cdr = p; // and the new container is my successor return *_car; } PGObject &RepeatBase::append(const PGObject &x) { RepeatBase *p = this; while(p->_car != NULL) p = p->_cdr; p->_car = p->ctora(&x); p->_cdr = p->ctord(); return *p->_car; } PGObject &RepeatBase::prepend() { RepeatBase *p = ctord(); // a new container p->_car = _car; // gets my content p->_cdr = _cdr; // and my successor _car = ctora(); // while I will have a new content _cdr = p; // and the new container is my successor return *_car; } PGObject &RepeatBase::append() { RepeatBase *p = this; while(p->_car != NULL) p = p->_cdr; p->_car = p->ctora(); p->_cdr = p->ctord(); return *p->_car; } const RepeatBase& RepeatBase::operator = (const RepeatBase &l) { if(&l == this) { LOGWARNING("Huh? assign myself to me?"); return *this; } PGObject::operator=(l); const RepeatBase *p = &l; RepeatBase *q = this; while(p->_car != NULL) { q->_car = p->ctora(p->_car); q->_cdr = p->ctord(); q = q->_cdr; p = p->_cdr; } // Cut off the rest if(q->_cdr != NULL) { delete q->_cdr; q->_cdr = NULL; } if(q->_car != NULL) { delete q->_car; q->_car = NULL; } return *this; } inline PGObject &RepeatBase::car() const { if(_car == NULL) FATAL("access into non existent object"); return *_car; } bool RepeatBase::OK() const { bool res = TRUE; const RepeatBase *p; for(p = this; p->_car != NULL; p = p->_cdr) res = res && p->_car->OK(); if(p->_cdr != NULL) FATAL("still have a rest at end of list"); return res; } bool RepeatBase::commit() { RepeatBase *p, *end = this; for(p = this; p->_car != NULL; p = p->_cdr) if(p->_car->commit()) end = p->_cdr; if(end->_car != NULL) { delete end->_car; end->_car = NULL; } if(end->_cdr != NULL) { delete end->_cdr; end->_cdr = NULL; } return end != this; }