/*ident "@(#)List.c 1.1.2.4" */ /****************************************************************************** * * C++ Standard Components, Release 3.0. * * Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc. * Copyright (c) 1988, 1989, 1990 AT&T. All Rights Reserved. * * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System * Laboratories, Inc. The copyright notice above does not evidence * any actual or intended publication of such source code. * ******************************************************************************/ #ifndef _LIST_C_ #define _LIST_C_ #include #include #ifndef __GNUG__ #ifndef voidP_List #define voidP_List List #define voidP_Listiter Listiter #endif #endif #ifdef __GNUG__ template Pool *lnnk_ATTLC::pool() { Pool *lcl_pool = 0; if (lcl_pool == 0) { lcl_pool = new Pool(sizeof(lnnk_ATTLC)); } return lcl_pool; } #else template Pool* lnnk_ATTLC::pool = 0; #endif #ifndef __GNUG__ template lnnk_ATTLC::~lnnk_ATTLC() { } template lnk_ATTLC* lnnk_ATTLC::copy() { return new lnnk_ATTLC((T&)val); } template int lnnk_ATTLC::operator==(lnk_ATTLC& x) { return val == ((lnnk_ATTLC*)&x)->val; } #endif template void* lnnk_ATTLC::operator new(size_t) { #ifdef __GNUG__ return pool()->alloc(); #else return pool->alloc(); #endif } template lnk_ATTLC* lnnk_ATTLC::getnewlnnk_ATTLC(const T& x) { return (new lnnk_ATTLC((T&)x)); } template void lnnk_ATTLC::deletelnnk_ATTLC(T& t, lnnk_ATTLC* ptr) { t = ptr->val; delete ptr; } template List::List(const List& a0, const T& _t) : Lizt_ATTLC((Lizt_ATTLC&)a0) { put(_t); } template List::List() { #ifndef __GNUG__ lnnk_ATTLC::init_pool(); #endif } template List::List(const T& _t) { #ifndef __GNUG__ lnnk_ATTLC::init_pool(); #endif put(_t); } template List::List(const T& _t, const T& u) { #ifndef __GNUG__ lnnk_ATTLC::init_pool(); #endif put(_t); put(u); } template List::List(const T& _t, const T& u, const T& v) { #ifndef __GNUG__ lnnk_ATTLC::init_pool(); #endif put(_t); put(u); put(v); } template List::List(const T& _t, const T& u, const T& v, const T& w) { #ifndef __GNUG__ lnnk_ATTLC::init_pool(); #endif put(_t); put(u); put(v); put(w); } template List::List(const List& a) : Lizt_ATTLC((const Lizt_ATTLC&)a) { #ifndef __GNUG__ lnnk_ATTLC::init_pool(); #endif } template T List::unput() { lnnk_ATTLC* ll = (lnnk_ATTLC*)Lizt_ATTLC::unput(); T ans = ll->val; delete ll; return ans; } template T List::get() { lnnk_ATTLC* ll = (lnnk_ATTLC*)Lizt_ATTLC::get(); // if (ll == 0) // return 0; T ans = ll->val; delete ll; return ans; } template T* List::getAt(int i) { lnnk_ATTLC* ll = (lnnk_ATTLC*)Lizt_ATTLC::getAt(i); if ( ll ) return &(ll->val); else return (T*)0; } template T& List::operator[](unsigned ii) { return (T&)*(getAt(ii)); } template const T& List::operator[](unsigned ii) const { return (const T&)*(((List*)this)->getAt(ii)); } template T* List::head() const { lnnk_ATTLC* ll = (lnnk_ATTLC*)Lizt_ATTLC::head(); if (ll == 0) return 0; return &(ll->val); } template T* List::tail() const { lnnk_ATTLC* ll = (lnnk_ATTLC*)Lizt_ATTLC::tail(); if (ll == 0) return 0; return &(ll->val); } template void List::sort(int (*cmp)(const T&,const T&)) { if ( length() < 2 ) return; voidP_List_sort_internal(*(List*)this, (int (*)(const T &, const T &))cmp); reset_all_iters(); } template int List::unput(T& _t) { lnnk_ATTLC* ll = (lnnk_ATTLC*)Lizt_ATTLC::unput(); if ( ll ) { lnnk_ATTLC::deletelnnk_ATTLC(_t, ll); return 1; } else return 0; } template int List::get(T& _t) { lnnk_ATTLC* ll = (lnnk_ATTLC*)Lizt_ATTLC::get(); if ( ll ) { lnnk_ATTLC::deletelnnk_ATTLC(_t, ll); return 1; } else return 0; } template List& List::put(const T& x) { return (List&) Lizt_ATTLC::put(lnnk_ATTLC::getnewlnnk_ATTLC(x)); } template List& List::unget(const T& x) { return (List&)Lizt_ATTLC::unget(lnnk_ATTLC::getnewlnnk_ATTLC(x)); } template Const_listiter::Const_listiter(const List& a) : Liztiter_ATTLC((Lizt_ATTLC&)a) { } template Const_listiter::Const_listiter(const Const_listiter& a) : Liztiter_ATTLC((const Liztiter_ATTLC&)a) { } template int Const_listiter::next(T& t) { if ( at_end() ) return 0; else return (t = ((lnnk_ATTLC*)Liztiter_ATTLC::next())->val, 1); } template int Const_listiter::next(T*& t) { if ( at_end() ) return 0; else return (t = &((lnnk_ATTLC*)Liztiter_ATTLC::next())->val, 1); } template T* Const_listiter::next() { if ( at_end() ) return 0; lnnk_ATTLC* ll = (lnnk_ATTLC*)Liztiter_ATTLC::next(); return &(ll->val); } template int Const_listiter::prev(T& t) { if ( at_head() ) return 0; else return (t=((lnnk_ATTLC*)Liztiter_ATTLC::prev())->val, 1); } template int Const_listiter::prev(T*& t) { if ( at_head() ) return 0; else return (t= &((lnnk_ATTLC*)Liztiter_ATTLC::prev())->val, 1); } template T* Const_listiter::prev() { if ( at_head() ) return 0; lnnk_ATTLC* ll = (lnnk_ATTLC*)Liztiter_ATTLC::prev(); return &(ll->val); } template int Const_listiter::find_prev(const T& x) { if ( at_head() || theLizt->length()==0 ) return 0; lnnk_ATTLC* iter = (lnnk_ATTLC*) pred->nxt; register int i = index; do { iter = (lnnk_ATTLC*) iter->prv; if (iter->val==x) { index = i; pred = iter; return 1; } i--; } while ( i > 0 ); return 0; } template int Const_listiter::find_next(const T& x) { if ( at_end() || theLizt->length()==0 ) return 0; lnnk_ATTLC* iter = (lnnk_ATTLC*) pred; register int i = index; do { iter = (lnnk_ATTLC*) iter->nxt; if (iter->val==x) { index = i; pred = iter->prv; return 1; } i++; } while ( i < theLizt->length() ); return 0; } template T* Const_listiter::peek_prev() const { if ( at_head() ) return 0; return &(((lnnk_ATTLC*)Liztiter_ATTLC::peek_prev())->val); } template int Const_listiter::peek_prev(T& t) const { if ( at_head() ) return 0; else return (t = ((lnnk_ATTLC*)Liztiter_ATTLC::peek_prev())->val, 1); } template int Const_listiter::peek_prev(T*& t) const { if ( at_head() ) return 0; else return (t = &((lnnk_ATTLC*)Liztiter_ATTLC::peek_prev())->val, 1); } template T* Const_listiter::peek_next() const { if ( at_end() ) return 0; return &(((lnnk_ATTLC*)Liztiter_ATTLC::peek_next())->val); } template int Const_listiter::peek_next(T& t) const { if ( at_end() ) return 0; else return (t = ((lnnk_ATTLC*)Liztiter_ATTLC::peek_next())->val, 1); } template int Const_listiter::peek_next(T*& t) const { if ( at_end() ) return 0; else return (t = &((lnnk_ATTLC*)Liztiter_ATTLC::peek_next())->val, 1); } template T* Const_listiter::getAt(int i) { lnnk_ATTLC* ll = ((lnnk_ATTLC*)Liztiter_ATTLC::getAt(i)); if ( ll ) return &(ll->val); else return (T*)0; } template Listiter::Listiter(List& a) : Const_listiter((const List&)a) { } template Listiter::Listiter(const Listiter& a) : Const_listiter((Const_listiter)a) { } template int Listiter::remove_prev() { lnnk_ATTLC *aLink = (lnnk_ATTLC *)Liztiter_ATTLC::remove_prev(); if ( aLink ) { delete aLink; return 1; } else return 0; } template int Listiter::remove_prev(T &x) { lnnk_ATTLC *aLink = (lnnk_ATTLC *)Liztiter_ATTLC::remove_prev(); if ( aLink ) { x = aLink->val; delete aLink; return 1; } else return 0; } template int Listiter::remove_next() { lnnk_ATTLC *aLink = (lnnk_ATTLC *)Liztiter_ATTLC::remove_next(); if ( aLink ) { delete aLink; return 1; } else return 0; } template int Listiter::remove_next(T &x) { lnnk_ATTLC *aLink = (lnnk_ATTLC *)Liztiter_ATTLC::remove_next(); if ( aLink ) { x = aLink->val; delete aLink; return 1; } else return 0; } template int Listiter::replace_prev(const T& x) { if ( at_head() ) return 0; else return (((lnnk_ATTLC*)Liztiter_ATTLC::peek_prev())->val=x,1); } template int Listiter::replace_next(const T& x) { if ( at_end() ) return 0; else return (((lnnk_ATTLC*)Liztiter_ATTLC::peek_next())->val=x,1); } template void Listiter::insert_prev(const T& x) { Liztiter_ATTLC::insert_prev(lnnk_ATTLC::getnewlnnk_ATTLC(x)); } template void Listiter::insert_next(const T& x) { Liztiter_ATTLC::insert_next(lnnk_ATTLC::getnewlnnk_ATTLC(x)); } template List_of_piter::List_of_piter(List_of_p& l) : Const_list_of_piter((const List_of_p&)l) { } template List_of_piter::List_of_piter(const List_of_piter& l) : Const_list_of_piter((Const_list_of_piter)l) { } template List_of_piter::~List_of_piter() { } template List_of_p::List_of_p(const T* x) : voidP_List((voidP) x) { } template List_of_p::List_of_p(const T* x, const T* y) : voidP_List((voidP) x, (voidP) y) { } template List_of_p::List_of_p(const T* x, const T* y, const T* z) : voidP_List((voidP)x, (voidP)y, (voidP)z) { } template List_of_p::List_of_p(const T* x, const T* y, const T* z, const T* w) : voidP_List((voidP) x, (voidP) y, (voidP) z, (voidP) w) { } template Const_list_of_piter::Const_list_of_piter(const List_of_p& l) : voidP_Listiter((voidP_List&) l) { } template Const_list_of_piter::Const_list_of_piter(const Const_list_of_piter& l) : voidP_Listiter((voidP_Listiter&) l) { } template List_of_p List_of_p::operator+(const List_of_p& ll) { voidP_List result((voidP_List&)*this + (voidP_List&)ll); return (List_of_p&)result; } template List_of_p List_of_p::operator+(const T* _t) { voidP_List result((voidP_List&)*this + (voidP)_t); return (List_of_p&)result; } template T*& List_of_p::operator[](unsigned ii) { return (T*&)*getAt(ii); } template const T*& List_of_p::operator[](unsigned ii) const { return (const T*&)*((List_of_p*)this)->getAt(ii); } template ostream& operator<<(ostream& oo, const List& ll) { int first = 1; oo << "( "; Const_listiter l(ll); while (!l.at_end()) { if (!first) oo << ", "; first = 0; oo << *(l.next()); } oo << " )"; return oo; } template ostream& List::print(ostream& oo) const { int first = 1; oo << "( "; Const_listiter l(*this); while (!l.at_end()) { if (!first) oo << ", "; first = 0; oo << *(l.next()); } oo << " )"; return oo; } template ostream& operator<<(ostream& oo, const List_of_p& ll) { int first = 1; oo << "( "; Const_list_of_piter l(ll); while (!l.at_end()) { if (!first) oo << ", "; first = 0; oo << *(l.next()); } oo << " )"; return oo; } template ostream& List_of_p::print(ostream& oo) const { int first = 1; oo << "( "; Const_list_of_piter l(*this); while (!l.at_end()) { if (!first) oo << ", "; first = 0; oo << *(l.next()); } oo << " )"; return oo; } template void voidP_List_sort_internal(List& aList, int (*lessThan)(const T &, const T &)) { const int logN = 32; // max capacity will be 2^logN register lnnk_ATTLC* temp; register lnnk_ATTLC* newCh; register lnnk_ATTLC* oldCh; lnnk_ATTLC* bitPos[logN]; lnnk_ATTLC** bitPtr; lnnk_ATTLC** bitPtrMax = &bitPos[0]; for (bitPtr = &bitPos[0]; bitPtr < &bitPos[logN]; *bitPtr++ = 0) ; lnnk_ATTLC* nextPtr = aList.t ? (lnnk_ATTLC*) aList.t->nxt: 0; aList.t->nxt = 0; lnnk_ATTLC* ans; while (newCh = nextPtr) { nextPtr = (lnnk_ATTLC*)nextPtr->nxt; newCh->nxt = 0; for (bitPtr = &bitPos[0];; bitPtr++) { if (bitPtr > bitPtrMax) bitPtrMax = bitPtr; if (*bitPtr == 0) { *bitPtr = newCh; break; } oldCh = *bitPtr; *bitPtr = 0; if (!(*lessThan)(newCh->val, oldCh->val)) { ans = oldCh; for(;;) { while ((temp = (lnnk_ATTLC*)oldCh->nxt) && !(*lessThan)(newCh->val, temp->val)) oldCh = temp; oldCh->nxt = newCh; if ((oldCh = temp) == 0) { newCh = ans; break; } bMerge: while ((temp = (lnnk_ATTLC*)newCh->nxt) && (*lessThan)(temp->val, oldCh->val)) newCh = temp; newCh->nxt = oldCh; if ((newCh = temp) == 0) { newCh = ans; break; } } } else { ans = newCh; goto bMerge; } } } // final merge sweep lnnk_ATTLC** bPtr2; for (bitPtr = &bitPos[0];; bitPtr = bPtr2) { while (*bitPtr == 0) bitPtr++; if (bitPtr == bitPtrMax) break; for (bPtr2 = bitPtr + 1; *bPtr2 == 0; bPtr2++) ; oldCh = *bPtr2; newCh = *bitPtr; if (!(*lessThan)(newCh->val, oldCh->val)) { ans = oldCh; for(;;) { while ((temp = (lnnk_ATTLC*)oldCh->nxt) && !(*lessThan)(newCh->val, temp->val)) oldCh = temp; oldCh->nxt = newCh; if ((oldCh = temp) == 0) { newCh = ans; break; } eMerge: while ((temp = (lnnk_ATTLC*)newCh->nxt) && (*lessThan)(temp->val, oldCh->val)) newCh = temp; newCh->nxt = oldCh; if ((newCh = temp) == 0) { newCh = ans; break; } } } else { ans = newCh; goto eMerge; } *bPtr2 = ans; } for (newCh = *bitPtr; newCh->nxt; newCh = (lnnk_ATTLC*)newCh->nxt) newCh->nxt->prv = newCh; newCh->nxt = *bitPtr; (*bitPtr)->prv = newCh; aList.t = newCh; } #endif