home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1999 mARCH
/
PCWK3A99.iso
/
Linux
/
DDD331
/
DDD-3_1_.000
/
DDD-3_1_
/
ddd-3.1.1
/
ddd
/
Assoc.h
< prev
next >
Wrap
C/C++ Source or Header
|
1998-11-24
|
7KB
|
338 lines
// $Id: Assoc.h,v 1.16 1998/11/24 16:42:53 zeller Exp $
// Associative array
// Copyright (C) 1995-1998 Technische Universitaet Braunschweig, Germany.
// Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
//
// This file is part of the ICE Library.
//
// The ICE Library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// The ICE Library 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 Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with the ICE Library -- see the file COPYING.LIB.
// If not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// ICE is the incremental configuration environment.
// For details, see the ICE World-Wide-Web page,
// `http://www.cs.tu-bs.de/softech/ice/',
// or send a mail to the ICE developers <ice@ips.cs.tu-bs.de>.
#ifndef _ICE_Assoc_h
#define _ICE_Assoc_h
#if defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 5)
#pragma interface
#endif
#include "bool.h"
#include "assert.h"
#include <stdlib.h> // abort()
template<class K, class V> class AssocMark;
template<class K, class V> class _Assoc;
template<class K, class V> class Assoc;
template<class K, class V> class AssocIter;
template<class K, class V>
class AssocRec {
friend class _Assoc<K,V>;
friend class Assoc<K,V>;
friend class AssocIter<K,V>;
private:
AssocRec<K,V> *next; // For Assoc usage only
public:
K key;
V value;
// Constructor
AssocRec(const K& k, const V& v)
: next(0), key(k), value(v)
{}
AssocRec(const K& k)
: next(0), key(k)
{}
private:
AssocRec(const AssocRec<K, V>& x)
: next(0), key(x.key), value(x.value)
{
assert(0);
}
AssocRec<K,V>& operator = (const AssocRec<K, V>&)
{
assert(0); return *this;
}
};
template<class K, class V>
class _Assoc {
friend class AssocMark<K,V>;
protected:
AssocRec<K,V> *entries; // Entries
virtual AssocRec<K,V> *lookup(const K& key) const
{
for (AssocRec<K,V> *e = entries; e != 0; e = e->next)
if (key == e->key)
return e;
return 0;
}
virtual AssocRec<K,V> *insert(const K& key)
{
AssocRec<K,V> *e = new AssocRec<K,V>(key);
e->next = entries;
return entries = e;
}
public:
// Constructors
_Assoc():
entries(0)
{}
// Destructor
virtual ~_Assoc()
{
AssocRec<K,V> *next = 0;
for (AssocRec<K,V> *e = entries; e != 0; e = next)
{
next = e->next;
delete e;
}
}
// Resources
// Access (or create) element KEY
V& operator[] (const K& key)
{
AssocRec<K,V> *e = lookup(key);
if (e == 0)
e = insert(key);
return e->value;
}
// Access element KEY; abort if non-existent
const V& operator[] (const K& key) const
{
AssocRec<K,V> *e = lookup(key);
if (e == 0)
abort();
return e->value;
}
// Add element KEY
void add(const K& key)
{
insert(key);
}
// Check if element KEY is present
bool has(const K& key) const
{
return lookup(key) != 0;
}
// Remove up to N elements KEY
void remove(const K& key, int n = -1)
{
if (n == 0)
return;
AssocRec<K,V> *prev = 0;
AssocRec<K,V> *e = entries;
while (e != 0)
{
AssocRec<K,V> *next = e->next;
if (key == e->key)
{
if (prev == 0)
entries = next;
else
prev->next = next;
delete e;
if (--n == 0)
return;
}
else
{
prev = e;
}
e = next;
}
}
// Copy constructor
_Assoc(const _Assoc<K,V>& m):
entries(0)
{
for (AssocRec<K,V> *e = m.entries; e != 0; e = e->next)
(*this)[e->key] = e->value;
}
// Assignment
_Assoc<K, V>& operator = (const _Assoc<K,V>& m)
{
if (this != &m)
{
if (entries)
delete entries;
entries = 0;
for (AssocRec<K,V> *e = m.entries; e != 0; e = e->next)
(*this)[e->key] = e->value;
}
return *this;
}
};
template<class K, class V>
class AssocMark {
friend class Assoc<K,V>;
protected:
AssocRec<K,V> *rec;
AssocMark(AssocRec<K,V> *ptr):
rec(ptr)
{}
public:
AssocMark(const Assoc<K,V>& assoc):
rec(assoc.entries)
{}
AssocMark(const AssocMark<K,V>& mark):
rec(mark.rec)
{}
AssocMark<K,V>& operator = (const Assoc<K,V>& assoc)
{
rec = assoc.entries;
return *this;
}
AssocMark<K,V>& operator = (const AssocMark<K,V>& mark)
{
rec = mark.rec;
return *this;
}
};
template<class K, class V>
class AssocIter: public AssocMark<K,V> {
protected:
AssocIter(AssocRec<K,V> *ptr):
AssocMark<K,V>(ptr)
{}
public:
AssocIter(const Assoc<K,V>& assoc):
AssocMark<K,V>(assoc)
{}
AssocIter(const AssocIter<K,V>& iter):
AssocMark<K,V>(iter)
{}
AssocIter<K,V>& operator = (const Assoc<K,V>& assoc)
{
AssocMark<K,V>::operator = (assoc);
return *this;
}
AssocIter<K,V>& operator = (const AssocIter<K,V>& iter)
{
AssocMark<K,V>::operator = (iter);
return *this;
}
const K& key() const { return rec->key; }
const V& value() const { return rec->value; }
V& value() { return rec->value; }
bool ok() { return rec != 0; }
AssocIter<K,V> next() { return AssocIter<K,V>(rec->next); }
const AssocIter<K,V>& operator ++ ()
{
rec = rec->next; return *this;
}
const AssocIter<K,V> operator ++ (int)
{
AssocIter<K,V> old(*this);
rec = rec->next;
return old;
}
};
template<class K, class V>
class Assoc: public _Assoc<K, V>
{
protected:
AssocRec<K,V> *lookup(const K& key) const
{
return _Assoc<K, V>::lookup(key);
}
AssocRec<K,V> *insert(const K& key)
{
return _Assoc<K, V>::insert(key);
}
public:
// Truncate array up to assoc iterator
void release (const AssocMark<K, V>& mark)
{
AssocRec<K, V> *e = entries;
while (e != 0 && e != mark.rec)
{
AssocRec<K, V> *tmp = e;
e = e->next;
tmp->next = 0;
delete tmp;
}
entries = e;
}
// Constructor
Assoc()
: _Assoc<K, V>()
{}
// Destructor
~Assoc() {}
// Copy
Assoc(const Assoc<K, V>& m)
: _Assoc<K, V>(m)
{}
// Assignment
Assoc<K, V>& operator = (const Assoc<K, V>& m)
{
_Assoc<K, V>::operator =(m);
return *this;
}
};
#endif // _ICE_Assoc_h
// DON'T ADD ANYTHING BEHIND THIS #endif