/*ident "@(#)Map.c 1.1.2.3" */ /****************************************************************************** * * 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 _MAP_C_ #define _MAP_C_ template Mapnode_ATTLC::~Mapnode_ATTLC() { } template Map::~Map() { Mapiter* p = iter_head; while (p) { p->m = 0; p = p->iter_next; } } template Mapiter::Mapiter (const Map* map, Mapnode_ATTLC* n): p(n) { m = (Map*)map; m->mi_count++; iter_next = m->iter_head; m->iter_head = this; } template Mapiter::Mapiter (const Map& map): p(0) { m = (Map*)(&map); m->mi_count++; iter_next = m->iter_head; m->iter_head = this; } template Mapiter::~Mapiter () { if (m==0 || m->iter_head == 0) return; if (--m->mi_count == 0 && m->remove_flag) { m->remove_deadwood(); m->remove_flag = 0; } if (this == m->iter_head) { m->iter_head = iter_next; } else { Mapiter* _p = m->iter_head; while (_p->iter_next!=this) { _p = _p->iter_next; } _p->iter_next = iter_next; } } template Mapnode_ATTLC::Mapnode_ATTLC(const S& xs, const T& xt): map_data (xs) { map_data.value = xt; } template Map::Map() : def (*Mapnode_ATTLC::default_T()) { mi_count = 0; remove_flag = 0; iter_head = 0; } template Map::Map(const T& d) : def (d) { mi_count = 0; remove_flag = 0; iter_head = 0; } template Map& Map::operator= (const Map& m) { if (this != &m) { make_empty(); for (Mapiter p (m); ++p; ) { // S s = p.key(); /* sidestep a cfront bug */ // (*this) [s] = p.value(); (*this) [p.key()] = p.value(); } // iter_head=0; // mi_count = 0; /* march through the iterator list, setting each to vacuous */ for (Mapiter *ip = iter_head; ip; ip = ip->iter_next) { /* ip->m = this; */ /* unnecessary */ ip->p = 0; } remove_flag = 0; } return *this; } /** template int Map::operator== (const Map& m) { if (m.size() != n) { cout << "aaa\n"; return 0; } if (this != &m) { Mapiter q(*this); Mapiter p(m); while (++p) { if (++q == 0) return 0; if (q.key() != p.key()) { cout << "bbb:q=" << q.key() << " p=" << p.key() << "\n"; return 0; } if (q.value() != p.value()) { cout << "bbb:q=" << q.value().value() << " p=" << p.value().value() << "\n"; return 0; } } if (++q == 0) return 1; cout << "ccc:" << (void*)p << " " << (void*)q << "\n"; return 0; } cout << "ddd\n"; return 1; } **/ template Map::Map (const Map& m): def (m.def), mi_count(0), remove_flag(0), iter_head(0) { operator= (m); } template T& Map::newnode (Mapnodebase_ATTLC*& ptr, const S& s, Mapnode_ATTLC* parent) { Mapnode_ATTLC* p = new Mapnode_ATTLC (s, def); ptr = p; T& retval = p->map_data.value; p->U_ = parent; n++; Mapbase_ATTLC::newnode(ptr); return retval; } template T& Map::operator[] (const S& s) { if (head()) { Mapnode_ATTLC* t = head(); for(;;) { if (s < t->map_data.key) { if (t->L()) t = t->L(); else return newnode (t->L_, s, t); } else if (t->map_data.key < s) { if (t->R()) t = t->R(); else return newnode (t->R_, s, t); } else break; } if (t->remove_mark != 0) { t->remove_mark = 0; t->map_data.value = def; n++; } return t->map_data.value; } else return newnode (head_, s, 0); } template const T& Map::operator[] (const S& s) const { return (const T&)(((Map*)this)->operator[](s)); } template Mapiter Map::element (const S& s) const { Mapnode_ATTLC* t = head(); while (t) { if (s < t->map_data.key) t = t->L(); else if (t->map_data.key < s) t = t->R(); else break; } if (t && t->remove_mark == 0) return Mapiter (this, t); else return Mapiter (this, 0); } template Mapiter Map::lub (const S& s) const { Mapnode_ATTLC* t = head(); while(t){ if(s < t->map_data.key){ if(t->L()) t = t->L(); else break; } else if(t->map_data.key < s){ if(t->R()) t = t->R(); else { t = successor(t); break; } } else break; } while (t && t->remove_mark){ t = successor(t); } if(t) return Mapiter (this, t); else return Mapiter (this, 0); } template Mapiter Map::glb (const S& s) const { Mapnode_ATTLC* t = head(); while(t){ if(t->map_data.key < s){ if(t->R()) t = t->R(); else break; } else if (s < t->map_data.key){ if(t->L()) t = t->L(); else { t = predecessor(t); break; } } else break; } while (t && t->remove_mark){ t = predecessor(t); } if(t) return Mapiter (this, t); else return Mapiter (this, 0); } template int Map::remove(const S& s) { Mapnode_ATTLC* t = head(); while (t) { if (s < t->map_data.key) t = t->L(); else if (t->map_data.key < s) t = t->R(); else break; } if (t) { if (mi_count > 0) { remove_flag = 1; if (!t->remove_mark) { t->remove_mark = 1; n--; } return (1); } else { removenode(t); delete t; n--; return (1); } } else { return (0); } } template Mapiter Map::first() const { return ++Mapiter (*this); } template Mapiter Map::last() const { return --Mapiter (*this); } template void Mapiter::remove() { if (p) { m->remove_flag = 1; p->remove_mark = 1; m->n--; } } template Mapiter& Mapiter::operator++() { while (1) { p = m->successor(p); if (p == 0 || p->remove_mark == 0) { return (*this); } } } template Mapiter& Mapiter::operator--() { while (1) { p = m->predecessor(p); if (p == 0 || p->remove_mark == 0) { return (*this); } } } template Mapiter::Mapiter(const Mapiter& mi) : m(mi.m),p(mi.p) { m->mi_count++; iter_next = m->iter_head; m->iter_head = this; } template Mapiter& Mapiter::operator=(const Mapiter& mi) { if (this == m->iter_head) { m->iter_head = iter_next; } else { Mapiter* _p = m->iter_head; while (_p && _p->iter_next!=this) { _p = _p->iter_next; } if (_p) { _p->iter_next = iter_next; } } ((Map*)m)->mi_count--; ((Map*)mi.m)->mi_count++; m = (Map*)(mi.m); p = mi.p; iter_next = m->iter_head; m->iter_head = this; return *this; } template const S* Mapnode_ATTLC::default_S() { static S S_default_item; return (&S_default_item); } template const T* Mapnode_ATTLC::default_T() { static T T_default_item; return (&T_default_item); } template ostream &operator<<(ostream& os, const Map& m) { Mapiter mi(m); os << '{'; while (++mi) { os << "[ " << mi.curr()->key << ' ' << mi.curr()->value << " ]"; } os << '}'; return os; } #endif