diff options
author | svn2git <svn2git@FreeBSD.org> | 1994-05-01 00:00:00 -0800 |
---|---|---|
committer | svn2git <svn2git@FreeBSD.org> | 1994-05-01 00:00:00 -0800 |
commit | a16f65c7d117419bd266c28a1901ef129a337569 (patch) | |
tree | 2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /gnu/lib/libg++/g++-include | |
parent | 8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff) | |
download | src-a16f65c7d117419bd266c28a1901ef129a337569.tar.gz src-a16f65c7d117419bd266c28a1901ef129a337569.zip |
Release FreeBSD 1.1release/1.1.0_cvs
This commit was manufactured to restore the state of the 1.1-RELEASE image.
Releases prior to 5.3-RELEASE are omitting the secure/ and crypto/ subdirs.
Diffstat (limited to 'gnu/lib/libg++/g++-include')
157 files changed, 23737 insertions, 0 deletions
diff --git a/gnu/lib/libg++/g++-include/assert.h b/gnu/lib/libg++/g++-include/assert.h new file mode 100644 index 000000000000..44a65704cfae --- /dev/null +++ b/gnu/lib/libg++/g++-include/assert.h @@ -0,0 +1,14 @@ +#ifndef __libgxx_assert_h + +extern "C" { +#ifdef __assert_h_recursive +#include_next <assert.h> +#else +/* assert.h on some systems needs stdio.h, in violation of ANSI. */ +#include <stdio.h> +#include_next <assert.h> + +#define __libgxx_assert_h 1 +#endif +} +#endif diff --git a/gnu/lib/libg++/g++-include/bstring.h b/gnu/lib/libg++/g++-include/bstring.h new file mode 100644 index 000000000000..3b2f5900276f --- /dev/null +++ b/gnu/lib/libg++/g++-include/bstring.h @@ -0,0 +1 @@ +#include <string.h> diff --git a/gnu/lib/libg++/g++-include/ctype.h b/gnu/lib/libg++/g++-include/ctype.h new file mode 100644 index 000000000000..b573e1995df9 --- /dev/null +++ b/gnu/lib/libg++/g++-include/ctype.h @@ -0,0 +1,10 @@ +#include <_G_config.h> +extern "C" { +#include_next <ctype.h> +#ifndef toupper +extern int toupper _G_ARGS((int)); +#endif +#ifndef tolower +extern int tolower _G_ARGS((int)); +#endif +} diff --git a/gnu/lib/libg++/g++-include/curses.h b/gnu/lib/libg++/g++-include/curses.h new file mode 100644 index 000000000000..b7b32be78c77 --- /dev/null +++ b/gnu/lib/libg++/g++-include/curses.h @@ -0,0 +1,82 @@ +#ifndef _G_curses_h + +#include <_G_config.h> + +#if _G_HAVE_CURSES + +#ifdef __curses_h_recursive +#include_next <curses.h> +#else +#define __curses_h_recursive + +extern "C" { +#include_next <curses.h> + +/* Some systems (SVR4 for example) allow the definition of CHTYPE to set the + type of some arguments to the curses functions. It can be set to "char" + to save space, or it can be set to something longer to store both a + character and some attributes. By default they do not define CHTYPE, + and when CHTYPE is not defined, the default type is "unsigned long" instead + of the traditional "char". However, SVR4 <curses.h> does define + _VR3_COMPAT_CODE, so we can use that to detect when we should use the SVR4 + default if CHTYPE is not defined. For other systems, just default to the + traditional default "char". */ + +#ifdef CHTYPE + typedef CHTYPE _G_chtype; /* Use specified type. */ +#else +#ifdef _VR3_COMPAT_CODE + typedef unsigned long _G_chtype; /* SVR4 default is "unsigned long" */ +#elif defined(hpux) + typedef unsigned int _G_chtype; +#else + typedef char _G_chtype; /* Traditional default is "char" */ +#endif +#endif + +/* Some args are conceptually const, but SVR4 (and others?) get it wrong. */ +#define _C_const /* const */ + +WINDOW * (newwin)(int, int, int, int); +WINDOW * (subwin)(WINDOW *, int, int, int, int); +WINDOW * (initscr)(); +int (box) (WINDOW*, _G_chtype, _G_chtype); +int (delwin)(WINDOW*); +int (getcurx)(WINDOW*); +int (getcury)(WINDOW*); +int (mvcur)(int, int, int, int); +int (overlay)(WINDOW*, WINDOW*); +int (overwrite)(WINDOW*, WINDOW*); +int (scroll)(WINDOW*); +int (touchwin)(WINDOW*); +int (waddch)(WINDOW*, _G_chtype); +int (waddstr) _G_ARGS((WINDOW*, const char*)); +int (wclear)(WINDOW*); +int (wclrtobot)(WINDOW*); +int (wclrtoeol)(WINDOW*); +int (wdelch)(WINDOW*); +int (wdeleteln)(WINDOW*); +int (werase)(WINDOW*); +int (wgetch)(WINDOW*); +int (wgetstr)(WINDOW*, char*); +int (winsch)(WINDOW*, _G_chtype); +int (winsertln)(WINDOW*); +int (wmove)(WINDOW*, int, int); +int (wrefresh)(WINDOW*); +int (wstandend)(WINDOW*); +int (wstandout)(WINDOW*); + +// SVR4 rather inanely bundles the format-string parameter with the '...'. +// This breaks VMS, and I don't want to penalize VMS for being right for once! + +int (wprintw)(WINDOW*, _G_CURSES_FORMAT_ARG ...); +int (mvwprintw)(WINDOW*, int y, int x, _G_CURSES_FORMAT_ARG ...); +int (wscanw)(WINDOW*, _G_CURSES_FORMAT_ARG ...); +int (mvwscanw)(WINDOW*, int, int, _G_CURSES_FORMAT_ARG ...); +int (endwin)(); + +} +#define _G_curses_h +#endif +#endif /* _G_HAVE_CURSES */ +#endif /* _G_curses_h */ diff --git a/gnu/lib/libg++/g++-include/dir.h b/gnu/lib/libg++/g++-include/dir.h new file mode 100644 index 000000000000..78c540242c57 --- /dev/null +++ b/gnu/lib/libg++/g++-include/dir.h @@ -0,0 +1 @@ +#include <sys/dir.h> diff --git a/gnu/lib/libg++/g++-include/dirent.h b/gnu/lib/libg++/g++-include/dirent.h new file mode 100644 index 000000000000..4c06ea837a8f --- /dev/null +++ b/gnu/lib/libg++/g++-include/dirent.h @@ -0,0 +1,44 @@ +#ifndef __libgxx_dirent_h + +#include <_G_config.h> + +#if !_G_HAVE_DIRENT +#define __libgxx_dirent_h +#define direct dirent +#include <sys/dir.h> +#else + +extern "C" { + +#ifdef __dirent_h_recursive +#include_next <dirent.h> +#else +// Note: sys/dir.h checks __dirent_h_recursive +#define __dirent_h_recursive +#define opendir __hide_opendir +#define closedir __hide_closedir +#define readdir __hide_readdir +#define telldir __hide_telldir +#define seekdir __hide_seekdir + +#include_next <dirent.h> + +#define __libgxx_dirent_h +#undef opendir +#undef closedir +#undef readdir +#undef telldir +#undef seekdir + +DIR *opendir(const char *); +int closedir(DIR *); +struct dirent *readdir(DIR *); +long telldir(DIR *); +void seekdir(DIR *, long); +// We don't bother with rewinddir (many systems define it as a macro). +// void rewinddir(DIR *); +#endif +} + +#endif +#endif diff --git a/gnu/lib/libg++/g++-include/errno.h b/gnu/lib/libg++/g++-include/errno.h new file mode 100644 index 000000000000..f9f86c85d142 --- /dev/null +++ b/gnu/lib/libg++/g++-include/errno.h @@ -0,0 +1,24 @@ +#ifndef errno_h + +extern "C" { + +#ifdef __errno_h_recursive +#include_next <errno.h> +#else +#define __errno_h_recursive +#include_next <errno.h> + +#define errno_h 1 + +extern char* sys_errlist[]; +extern int sys_nerr; +#ifndef errno +extern int errno; +#endif +void perror(const char*); +char* strerr(int); + +#endif +} + +#endif diff --git a/gnu/lib/libg++/g++-include/fcntl.h b/gnu/lib/libg++/g++-include/fcntl.h new file mode 100644 index 000000000000..48637ef0167f --- /dev/null +++ b/gnu/lib/libg++/g++-include/fcntl.h @@ -0,0 +1,29 @@ +#ifndef fcntl_h + +extern "C" { + +#ifdef __fcntl_h_recursive +#include_next <fcntl.h> +#else +#define fcntl __hide_fcntl +#define open __hide_open +#define creat __hide_creat + +#define __fcntl_h_recursive +#include <_G_config.h> +#include_next <fcntl.h> + +#undef fcntl +#undef open +#undef creat + +#define fcntl_h 1 + +int fcntl(int, int, ...); +int creat _G_ARGS((const char*, unsigned short int)); + +int open _G_ARGS((const char*, int, ...)); + +#endif +} +#endif diff --git a/gnu/lib/libg++/g++-include/gen/AVLMap.ccP b/gnu/lib/libg++/g++-include/gen/AVLMap.ccP new file mode 100644 index 000000000000..a9be60f06612 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLMap.ccP @@ -0,0 +1,614 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.<C>.AVLMap.h" + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(<T><C>AVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(<T><C>AVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(<T><C>AVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(<T><C>AVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(<T><C>AVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(<T><C>AVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +<T><C>AVLNode* <T><C>AVLMap::leftmost() +{ + <T><C>AVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T><C>AVLNode* <T><C>AVLMap::rightmost() +{ + <T><C>AVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T><C>AVLNode* <T><C>AVLMap::succ(<T><C>AVLNode* t) +{ + <T><C>AVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +<T><C>AVLNode* <T><C>AVLMap::pred(<T><C>AVLNode* t) +{ + <T><C>AVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix <T><C>AVLMap::seek(<T&> key) +{ + <T><C>AVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = <T>CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static <T>* _target_item; // add/del_item target +static <T><C>AVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases + + +void <T><C>AVLMap:: _add(<T><C>AVLNode*& t) +{ + int cmp = <T>CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new <T><C>AVLNode(*_target_item, def); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + } + else + _add(t->lt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + <T><C>AVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + <T><C>AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new <T><C>AVLNode(*_target_item, def); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + <T><C>AVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + <T><C>AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +<C>& <T><C>AVLMap::operator [] (<T&> item) +{ + if (root == 0) + { + ++count; + root = new <T><C>AVLNode(item, def); + set_rthread(root, 1); + set_lthread(root, 1); + return root->cont; + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _add(root); + return _found_node->cont; + } +} + + +void <T><C>AVLMap::_del(<T><C>AVLNode* par, <T><C>AVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = <T>CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + <T><C>AVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + <T><C>AVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + return; + } + else // replace item & find someone deletable + { + <T><C>AVLNode* p = pred(t); + t->item = p->item; + t->cont = p->cont; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + <T><C>AVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + <T><C>AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + <T><C>AVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + <T><C>AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + + +void <T><C>AVLMap::del(<T&> item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +void <T><C>AVLMap::_kill(<T><C>AVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +<T><C>AVLMap::<T><C>AVLMap(<T><C>AVLMap& b) :<T><C>Map(b.def) +{ + root = 0; + count = 0; + for (Pix i = b.first(); i != 0; b.next(i)) + (*this)[b.key(i)] = b.contents(i); +} + + +int <T><C>AVLMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T><C>AVLNode* trail = leftmost(); + <T><C>AVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/AVLMap.hP b/gnu/lib/libg++/g++-include/gen/AVLMap.hP new file mode 100644 index 000000000000..119ee82caa33 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLMap.hP @@ -0,0 +1,141 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T><C>AVLMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T><C>AVLMap_h 1 + +#include "<T>.<C>.Map.h" + +struct <T><C>AVLNode +{ + <T><C>AVLNode* lt; + <T><C>AVLNode* rt; + <T> item; + <C> cont; + char stat; + <T><C>AVLNode(<T&> h, <C&> c, + <T><C>AVLNode* l=0, <T><C>AVLNode* r=0); + ~<T><C>AVLNode(); +}; + +inline <T><C>AVLNode::<T><C>AVLNode(<T&> h, <C&> c, + <T><C>AVLNode* l, <T><C>AVLNode* r) + :item(h), cont(c), lt(l), rt(r), stat(0) {} + +inline <T><C>AVLNode::~<T><C>AVLNode() {} + +typedef <T><C>AVLNode* <T><C>AVLNodePtr; + + +class <T><C>AVLMap : public <T><C>Map +{ +protected: + <T><C>AVLNode* root; + + <T><C>AVLNode* leftmost(); + <T><C>AVLNode* rightmost(); + <T><C>AVLNode* pred(<T><C>AVLNode* t); + <T><C>AVLNode* succ(<T><C>AVLNode* t); + void _kill(<T><C>AVLNode* t); + void _add(<T><C>AVLNode*& t); + void _del(<T><C>AVLNode* p, <T><C>AVLNode*& t); + +public: + <T><C>AVLMap(<C&> dflt); + <T><C>AVLMap(<T><C>AVLMap& a); + ~<T><C>AVLMap(); + + <C>& operator [] (<T&> key); + + void del(<T&> key); + + Pix first(); + void next(Pix& i); + <T>& key(Pix i); + <C>& contents(Pix i); + + Pix seek(<T&> key); + int contains(<T&> key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline <T><C>AVLMap::~<T><C>AVLMap() +{ + _kill(root); +} + +inline <T><C>AVLMap::<T><C>AVLMap(<C&> dflt) :<T><C>Map(dflt) +{ + root = 0; +} + +inline Pix <T><C>AVLMap::first() +{ + return Pix(leftmost()); +} + +inline Pix <T><C>AVLMap::last() +{ + return Pix(rightmost()); +} + +inline void <T><C>AVLMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T><C>AVLNode*)i)); +} + +inline void <T><C>AVLMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T><C>AVLNode*)i)); +} + +inline <T>& <T><C>AVLMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>AVLNode*)i)->item; +} + +inline <C>& <T><C>AVLMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>AVLNode*)i)->cont; +} + +inline void <T><C>AVLMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T><C>AVLMap::contains(<T&> key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/AVLSet.ccP b/gnu/lib/libg++/g++-include/gen/AVLSet.ccP new file mode 100644 index 000000000000..b170734e547f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLSet.ccP @@ -0,0 +1,892 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.AVLSet.h" +#include <stdlib.h> + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(<T>AVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(<T>AVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(<T>AVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(<T>AVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(<T>AVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(<T>AVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +<T>AVLNode* <T>AVLSet::leftmost() +{ + <T>AVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T>AVLNode* <T>AVLSet::rightmost() +{ + <T>AVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T>AVLNode* <T>AVLSet::succ(<T>AVLNode* t) +{ + <T>AVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +<T>AVLNode* <T>AVLSet::pred(<T>AVLNode* t) +{ + <T>AVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix <T>AVLSet::seek(<T&> key) +{ + <T>AVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = <T>CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static <T>* _target_item; // add/del_item target +static <T>AVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases + +static <T>AVLNode** _hold_nodes; // used for rebuilding trees +static int _max_hold_index; // # elements-1 in _hold_nodes + + +void <T>AVLSet:: _add(<T>AVLNode*& t) +{ + int cmp = <T>CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new <T>AVLNode(*_target_item); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + } + else + _add(t->lt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + <T>AVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + <T>AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new <T>AVLNode(*_target_item); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + <T>AVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + <T>AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +Pix <T>AVLSet::add(<T&> item) +{ + if (root == 0) + { + ++count; + root = new <T>AVLNode(item); + set_rthread(root, 1); + set_lthread(root, 1); + return Pix(root); + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _add(root); + return Pix(_found_node); + } +} + + +void <T>AVLSet::_del(<T>AVLNode* par, <T>AVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = <T>CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + <T>AVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + <T>AVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + return; + } + else // replace item & find someone deletable + { + <T>AVLNode* p = pred(t); + t->item = p->item; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + <T>AVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + <T>AVLNode* l = r->lt; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + <T>AVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + <T>AVLNode* r = l->rt; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + + +void <T>AVLSet::del(<T&> item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +// build an ordered array of pointers to tree nodes back into a tree +// we know that at least one element exists + +static <T>AVLNode* _do_treeify(int lo, int hi, int& h) +{ + int lh, rh; + int mid = (lo + hi) / 2; + <T>AVLNode* t = _hold_nodes[mid]; + if (lo > mid - 1) + { + set_lthread(t, 1); + if (mid == 0) + t->lt = 0; + else + t->lt = _hold_nodes[mid-1]; + lh = 0; + } + else + { + set_lthread(t, 0); + t->lt = _do_treeify(lo, mid-1, lh); + } + if (hi < mid + 1) + { + set_rthread(t, 1); + if (mid == _max_hold_index) + t->rt = 0; + else + t->rt = _hold_nodes[mid+1]; + rh = 0; + } + else + { + set_rthread(t, 0); + t->rt = _do_treeify(mid+1, hi, rh); + } + if (lh == rh) + { + set_bf(t, AVLBALANCED); + h = lh + 1; + } + else if (lh == rh - 1) + { + set_bf(t, AVLRIGHTHEAVY); + h = rh + 1; + } + else if (rh == lh - 1) + { + set_bf(t, AVLLEFTHEAVY); + h = lh + 1; + } + else // can't happen + abort(); + + return t; +} + +static <T>AVLNode* _treeify(int n) +{ + <T>AVLNode* t; + if (n == 0) + t = 0; + else + { + int b; + _max_hold_index = n-1; + t = _do_treeify(0, _max_hold_index, b); + } + delete _hold_nodes; + return t; +} + + +void <T>AVLSet::_kill(<T>AVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +<T>AVLSet::<T>AVLSet(<T>AVLSet& b) +{ + if ((count = b.count) == 0) + { + root = 0; + } + else + { + _hold_nodes = new <T>AVLNodePtr [count]; + <T>AVLNode* t = b.leftmost(); + int i = 0; + while (t != 0) + { + _hold_nodes[i++] = new <T>AVLNode(t->item); + t = b.succ(t); + } + root = _treeify(count); + } +} + + +int <T>AVLSet::operator == (<T>AVLSet& y) +{ + if (count != y.count) + return 0; + else + { + <T>AVLNode* t = leftmost(); + <T>AVLNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!(<T>EQ(t->item, u->item))) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int <T>AVLSet::operator <= (<T>AVLSet& y) +{ + if (count > y.count) + return 0; + else + { + <T>AVLNode* t = leftmost(); + <T>AVLNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = <T>CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + +void <T>AVLSet::operator |=(<T>AVLSet& y) +{ + <T>AVLNode* t = leftmost(); + <T>AVLNode* u = y.leftmost(); + int rsize = count + y.count; + _hold_nodes = new <T>AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + { + while (u != 0) + { + _hold_nodes[k++] = new <T>AVLNode(u->item); + u = y.succ(u); + } + break; + } + else if (u == 0) + { + while (t != 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + break; + } + int cmp = <T>CMP(t->item, u->item); + if (cmp == 0) + { + _hold_nodes[k++] = t; + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + else + { + _hold_nodes[k++] = new <T>AVLNode(u->item); + u = y.succ(u); + } + } + root = _treeify(k); + count = k; +} + +void <T>AVLSet::operator &= (<T>AVLSet& y) +{ + <T>AVLNode* t = leftmost(); + <T>AVLNode* u = y.leftmost(); + int rsize = (count < y.count)? count : y.count; + _hold_nodes = new <T>AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + break; + if (u == 0) + { + while (t != 0) + { + <T>AVLNode* tmp = succ(t); + delete t; + t = tmp; + } + break; + } + int cmp = <T>CMP(t->item, u->item); + if (cmp == 0) + { + _hold_nodes[k++] = t; + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + { + <T>AVLNode* tmp = succ(t); + delete t; + t = tmp; + } + else + u = y.succ(u); + } + root = _treeify(k); + count = k; +} + + +void <T>AVLSet::operator -=(<T>AVLSet& y) +{ + <T>AVLNode* t = leftmost(); + <T>AVLNode* u = y.leftmost(); + int rsize = count; + _hold_nodes = new <T>AVLNodePtr [rsize]; + int k = 0; + for (;;) + { + if (t == 0) + break; + else if (u == 0) + { + while (t != 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + break; + } + int cmp = <T>CMP(t->item, u->item); + if (cmp == 0) + { + <T>AVLNode* tmp = succ(t); + delete t; + t = tmp; + u = y.succ(u); + } + else if (cmp < 0) + { + _hold_nodes[k++] = t; + t = succ(t); + } + else + u = y.succ(u); + } + root = _treeify(k); + count = k; +} + +int <T>AVLSet::owns(Pix i) +{ + if (i == 0) return 0; + for (<T>AVLNode* t = leftmost(); t != 0; t = succ(t)) + if (Pix(t) == i) return 1; + return 0; +} + +int <T>AVLSet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T>AVLNode* trail = leftmost(); + <T>AVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/AVLSet.hP b/gnu/lib/libg++/g++-include/gen/AVLSet.hP new file mode 100644 index 000000000000..16ad1d194686 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVLSet.hP @@ -0,0 +1,152 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>AVL_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>AVL_h 1 + +#include "<T>.Set.h" + +struct <T>AVLNode +{ + <T>AVLNode* lt; + <T>AVLNode* rt; + <T> item; + char stat; + <T>AVLNode(<T&> h, <T>AVLNode* l=0, <T>AVLNode* r=0); + ~<T>AVLNode(); +}; + +inline <T>AVLNode::<T>AVLNode(<T&> h, <T>AVLNode* l, <T>AVLNode* r) +:item(h), lt(l), rt(r), stat(0) {} + +inline <T>AVLNode::~<T>AVLNode() {} + +typedef <T>AVLNode* <T>AVLNodePtr; + + +class <T>AVLSet : public <T>Set +{ +protected: + <T>AVLNode* root; + + <T>AVLSet(<T>AVLNode* p, int l); + + <T>AVLNode* leftmost(); + <T>AVLNode* rightmost(); + <T>AVLNode* pred(<T>AVLNode* t); + <T>AVLNode* succ(<T>AVLNode* t); + void _kill(<T>AVLNode* t); + void _add(<T>AVLNode*& t); + void _del(<T>AVLNode* p, <T>AVLNode*& t); + +public: + <T>AVLSet(); + <T>AVLSet(<T>AVLSet& a); + ~<T>AVLSet(); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + int owns(Pix i); + Pix seek(<T&> item); + + Pix last(); + void prev(Pix& i); + + void operator |= (<T>AVLSet& b); + void operator -= (<T>AVLSet& b); + void operator &= (<T>AVLSet& b); + + int operator == (<T>AVLSet& b); + int operator != (<T>AVLSet& b); + int operator <= (<T>AVLSet& b); + + int OK(); +}; + +inline <T>AVLSet::~<T>AVLSet() +{ + _kill(root); +} + +inline <T>AVLSet::<T>AVLSet() +{ + root = 0; + count = 0; +} + +inline <T>AVLSet::<T>AVLSet(<T>AVLNode* p, int l) +{ + root = p; + count = l; +} + +inline int <T>AVLSet::operator != (<T>AVLSet& b) +{ + return ! ((*this) == b); +} + +inline Pix <T>AVLSet::first() +{ + return Pix(leftmost()); +} + +inline Pix <T>AVLSet::last() +{ + return Pix(rightmost()); +} + +inline void <T>AVLSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T>AVLNode*)i)); +} + +inline void <T>AVLSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T>AVLNode*)i)); +} + +inline <T>& <T>AVLSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>AVLNode*)i)->item; +} + +inline void <T>AVLSet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T>AVLSet::contains(<T&> key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/AVec.ccP b/gnu/lib/libg++/g++-include/gen/AVec.ccP new file mode 100644 index 000000000000..bc671bf8e1d7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVec.ccP @@ -0,0 +1,397 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include <builtin.h> +#include "<T>.AVec.h" + +/* + The following brought to you by the department of redundancy department +*/ + +<T>AVec& <T>AVec::operator = (<T>AVec& v) +{ + if (len != 0 && len != v.capacity()) + error("nonconformant vectors."); + if (len == 0) + s = new <T> [len = v.capacity()]; + if (s != v.vec()) + { + for (int i = 0; i < len; ++i) + s[i] = v.vec()[i]; + } + return *this; +} + +<T>AVec& <T>AVec::operator = (<T&> f) +{ + for (int i = 0; i < len; ++i) s[i] = f; + return *this; +} + + +<T>AVec concat(<T>AVec & a, <T>AVec & b) +{ + int newl = a.capacity() + b.capacity(); + <T>* news = new <T> [newl]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + while (t < top) *p++ = *t++; + top = &(b.vec()[b.capacity()]); + t = b.vec(); + while (t < top) *p++ = *t++; + return <T>AVec(newl, news); +} + + +<T>AVec combine(<T>Combiner f, <T>AVec& a, <T>AVec& b) +{ + int newl = (a.capacity() < b.capacity())? a.capacity() : b.capacity(); + <T>* news = new <T> [newl]; + <T>* p = news; + <T>* top = &(a.vec()[newl]); + <T>* t = a.vec(); + <T>* u = b.vec(); + while (t < top) *p++ = (*f)(*t++, *u++); + return <T>AVec(newl, news); +} + +<T>AVec reverse(<T>AVec& a) +{ + <T>* news = new <T> [a.capacity()]; + if (a.capacity() != 0) + { + <T>* lo = news; + <T>* hi = &(news[a.capacity() - 1]); + while (lo < hi) + { + <T> tmp = *lo; + *lo++ = *hi; + *hi-- = tmp; + } + } + return <T>AVec(a.capacity(), news); +} + +<T>AVec map(<T>Mapper f, <T>AVec& a) +{ + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + while(t < top) *p++ = (*f)(*t++); + return <T>AVec(a.capacity(), news); +} + +<T>AVec <T>AVec::at(int from, int n) +{ + int to; + if (n < 0) + { + n = len - from; + to = len - 1; + } + else + to = from + n - 1; + if ((unsigned)from > (unsigned)to) + range_error(); + <T>* news = new <T> [n]; + <T>* p = news; + <T>* t = &(s[from]); + <T>* top = &(s[to]); + while (t <= top) *p++ = *t++; + return <T>AVec(n, news); +} + +<T>AVec merge(<T>AVec & a, <T>AVec & b, <T>Comparator f) +{ + int newl = a.capacity() + b.capacity(); + <T>* news = new <T> [newl]; + <T>* p = news; + <T>* topa = &(a.vec()[a.capacity()]); + <T>* as = a.vec(); + <T>* topb = &(b.vec()[b.capacity()]); + <T>* bs = b.vec(); + + for (;;) + { + if (as >= topa) + { + while (bs < topb) *p++ = *bs++; + break; + } + else if (bs >= topb) + { + while (as < topa) *p++ = *as++; + break; + } + else if ((*f)(*as, *bs) <= 0) + *p++ = *as++; + else + *p++ = *bs++; + } + return <T>AVec(newl, news); +} + +<T>AVec operator + (<T>AVec& a, <T>AVec& b) +{ + a.check_len(b.capacity()); + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + <T>* u = b.vec(); + while (t < top) *p++ = *t++ + *u++; + return <T>AVec(a.capacity(), news); +} + +<T>AVec operator - (<T>AVec& a, <T>AVec& b) +{ + a.check_len(b.capacity()); + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + <T>* u = b.vec(); + while (t < top) *p++ = *t++ - *u++; + return <T>AVec(a.capacity(), news); +} + +<T>AVec product (<T>AVec& a, <T>AVec& b) +{ + a.check_len(b.capacity()); + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + <T>* u = b.vec(); + while (t < top) *p++ = *t++ * *u++; + return <T>AVec(a.capacity(), news); +} + +<T>AVec quotient(<T>AVec& a, <T>AVec& b) +{ + a.check_len(b.capacity()); + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + <T>* u = b.vec(); + while (t < top) *p++ = *t++ / *u++; + return <T>AVec(a.capacity(), news); +} + +<T>AVec operator + (<T>AVec& a, <T&> b) +{ + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + while (t < top) *p++ = *t++ + b; + return <T>AVec(a.capacity(), news); +} + +<T>AVec operator - (<T>AVec& a, <T&> b) +{ + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + while (t < top) *p++ = *t++ - b; + return <T>AVec(a.capacity(), news); +} + +<T>AVec operator * (<T>AVec& a, <T&> b) +{ + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + while (t < top) *p++ = *t++ * b; + return <T>AVec(a.capacity(), news); +} + +<T>AVec operator / (<T>AVec& a, <T&> b) +{ + <T>* news = new <T> [a.capacity()]; + <T>* p = news; + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + while (t < top) *p++ = *t++ / b; + return <T>AVec(a.capacity(), news); +} + +<T>AVec <T>AVec::operator - () +{ + <T>* news = new <T> [len]; + <T>* p = news; + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *p++ = -(*t++); + return <T>AVec(len, news); +} + +<T>AVec& <T>AVec::operator += (<T>AVec& b) +{ + check_len(b.capacity()); + <T>* u = b.vec(); + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ += *u++; + return *this; +} + +<T>AVec& <T>AVec::operator -= (<T>AVec& b) +{ + check_len(b.capacity()); + <T>* u = b.vec(); + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ -= *u++; + return *this; +} + +<T>AVec& <T>AVec::product(<T>AVec& b) +{ + check_len(b.capacity()); + <T>* u = b.vec(); + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ *= *u++; + return *this; +} + +<T>AVec& <T>AVec::quotient(<T>AVec& b) +{ + check_len(b.capacity()); + <T>* u = b.vec(); + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ /= *u++; + return *this; +} + +<T>AVec& <T>AVec::operator += (<T&> b) +{ + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ += b; + return *this; +} + +<T>AVec& <T>AVec::operator -= (<T&> b) +{ + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ -= b; + return *this; +} + +<T>AVec& <T>AVec::operator *= (<T&> b) +{ + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ *= b; + return *this; +} + +<T>AVec& <T>AVec::operator /= (<T&> b) +{ + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) *t++ /= b; + return *this; +} + +<T> <T>AVec::max() +{ + if (len == 0) + return 0; + <T>* top = &(s[len]); + <T>* t = s; + <T> res = *t++; + for (; t < top; ++t) if (*t > res) res = *t; + return res; +} + +int <T>AVec::max_index() +{ + if (len == 0) + return -1; + int ind = 0; + for (int i = 1; i < len; ++i) + if (s[i] > s[ind]) + ind = i; + return ind; +} + +<T> <T>AVec::min() +{ + if (len == 0) + return 0; + <T>* top = &(s[len]); + <T>* t = s; + <T> res = *t++; + for (; t < top; ++t) if (*t < res) res = *t; + return res; +} + +int <T>AVec::min_index() +{ + if (len == 0) + return -1; + int ind = 0; + for (int i = 1; i < len; ++i) + if (s[i] < s[ind]) + ind = i; + return ind; +} + +<T> <T>AVec::sum() +{ + <T> res = 0; + <T>* top = &(s[len]); + <T>* t = s; + while (t < top) res += *t++; + return res; +} + + +<T> <T>AVec::sumsq() +{ + <T> res = 0; + <T>* top = &(s[len]); + <T>* t = s; + for (; t < top; ++t) res += *t * *t; + return res; +} + +<T> operator * (<T>AVec& a, <T>AVec& b) +{ + a.check_len(b.capacity()); + <T>* top = &(a.vec()[a.capacity()]); + <T>* t = a.vec(); + <T>* u = b.vec(); + <T> res = 0; + while (t < top) res += *t++ * *u++; + return res; +} diff --git a/gnu/lib/libg++/g++-include/gen/AVec.hP b/gnu/lib/libg++/g++-include/gen/AVec.hP new file mode 100644 index 000000000000..cd9a9c3fe5d6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/AVec.hP @@ -0,0 +1,113 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>AVec_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>AVec_h 1 + +#include "<T>.Vec.h" + +class <T>AVec : public <T>Vec +{ +protected: + void check_len(int l); + <T>* vec(); + <T>AVec(int l, <T>* d); + public: + <T>AVec (); + <T>AVec (int l); + <T>AVec (int l, <T&> fill_value); + <T>AVec (<T>AVec&); + ~<T>AVec (); + + <T>AVec& operator = (<T>AVec& a); + <T>AVec& operator = (<T&> fill_value); + +// vector by scalar -> vector operations + + friend <T>AVec operator + (<T>AVec& a, <T&> b); + friend <T>AVec operator - (<T>AVec& a, <T&> b); + friend <T>AVec operator * (<T>AVec& a, <T&> b); + friend <T>AVec operator / (<T>AVec& a, <T&> b); + + <T>AVec& operator += (<T&> b); + <T>AVec& operator -= (<T&> b); + <T>AVec& operator *= (<T&> b); + <T>AVec& operator /= (<T&> b); + +// vector by vector -> vector operations + + friend <T>AVec operator + (<T>AVec& a, <T>AVec& b); + friend <T>AVec operator - (<T>AVec& a, <T>AVec& b); + <T>AVec& operator += (<T>AVec& b); + <T>AVec& operator -= (<T>AVec& b); + + <T>AVec operator - (); + + friend <T>AVec product(<T>AVec& a, <T>AVec& b); + <T>AVec& product(<T>AVec& b); + friend <T>AVec quotient(<T>AVec& a, <T>AVec& b); + <T>AVec& quotient(<T>AVec& b); + +// vector -> scalar operations + + friend <T> operator * (<T>AVec& a, <T>AVec& b); + + <T> sum(); + <T> min(); + <T> max(); + <T> sumsq(); + +// indexing + + int min_index(); + int max_index(); + +// redundant but necesssary + friend <T>AVec concat(<T>AVec& a, <T>AVec& b); + friend <T>AVec map(<T>Mapper f, <T>AVec& a); + friend <T>AVec merge(<T>AVec& a, <T>AVec& b, <T>Comparator f); + friend <T>AVec combine(<T>Combiner f, <T>AVec& a, <T>AVec& b); + friend <T>AVec reverse(<T>AVec& a); + <T>AVec at(int from = 0, int n = -1); +}; + +inline <T>AVec::<T>AVec() {} +inline <T>AVec::<T>AVec(int l) :<T>Vec(l) {} +inline <T>AVec::<T>AVec(int l, <T&> fill_value) : <T>Vec (l, fill_value) {} +inline <T>AVec::<T>AVec(<T>AVec& v) :<T>Vec(v) {} +inline <T>AVec::<T>AVec(int l, <T>* d) :<T>Vec(l, d) {} +inline <T>AVec::~<T>AVec() {} + + +inline <T>* <T>AVec::vec() +{ + return s; +} + + +inline void <T>AVec::check_len(int l) +{ + if (l != len) + error("nonconformant vectors."); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/BSTSet.ccP b/gnu/lib/libg++/g++-include/gen/BSTSet.ccP new file mode 100644 index 000000000000..6a69d8f45b28 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/BSTSet.ccP @@ -0,0 +1,378 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.BSTSet.h" + + +/* + traversal primitives +*/ + + +<T>BSTNode* <T>BSTSet::leftmost() +{ + <T>BSTNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T>BSTNode* <T>BSTSet::rightmost() +{ + <T>BSTNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T>BSTNode* <T>BSTSet::succ(<T>BSTNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +<T>BSTNode* <T>BSTSet::pred(<T>BSTNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix <T>BSTSet::seek(<T&> key) +{ + <T>BSTNode* t = root; + for (;;) + { + if (t == 0) + return 0; + int comp = <T>CMP(key, t->item); + if (comp == 0) + return Pix(t); + else if (comp < 0) + t = t->lt; + else + t = t->rt; + } +} + + +Pix <T>BSTSet::add(<T&> item) +{ + if (root == 0) + { + ++count; + root = new <T>BSTNode(item); + return Pix(root); + } + + <T>BSTNode* t = root; + <T>BSTNode* p = root; + int comp; + for (;;) + { + if (t == 0) + { + ++count; + t = new <T>BSTNode(item); + if (comp > 0) + p->lt = t; + else + p->rt = t; + t->par = p; + return Pix(t); + } + p = t; + comp = <T>CMP(t->item, item); + if (comp == 0) + return Pix(t); + else if (comp > 0) + t = t->lt; + else + t = t->rt; + } +} + + +void <T>BSTSet::del(<T&> key) +{ + <T>BSTNode* t = root; + <T>BSTNode* p = root; + int comp; + for (;;) + { + if (t == 0) + return; + comp = <T>CMP(key, t->item); + if (comp == 0) + { + --count; + <T>BSTNode* repl; + if (t->lt == 0) + repl = t->rt; + else if (t->rt == 0) + repl = t->lt; + else + { + <T>BSTNode* prepl = t; + repl = t->lt; + while (repl->rt != 0) + { + prepl = repl; + repl = repl->rt; + } + if (prepl != t) + { + prepl->rt = repl->lt; + if (prepl->rt != 0) prepl->rt->par = prepl; + repl->lt = t->lt; + if (repl->lt != 0) repl->lt->par = repl; + } + repl->rt = t->rt; + if (repl->rt != 0) repl->rt->par = repl; + } + if (t == root) + { + root = repl; + if (repl != 0) repl->par = 0; + } + else + { + if (t == p->lt) + p->lt = repl; + else + p->rt = repl; + if (repl != 0) repl->par = p; + } + delete t; + return; + } + p = t; + if (comp < 0) + t = t->lt; + else + t = t->rt; + } +} + + +void <T>BSTSet::_kill(<T>BSTNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + +<T>BSTNode* <T>BSTSet::_copy(<T>BSTNode* t) +{ + if (t == 0) + return 0; + else + { + <T>BSTNode* u = new <T>BSTNode(t->item, _copy(t->lt), _copy(t->rt)); + if (u->lt != 0) u->lt->par = u; + if (u->rt != 0) u->rt->par = u; + return u; + } +} + + +int <T>BSTSet::operator == (<T>BSTSet& y) +{ + if (count != y.count) + return 0; + else + { + <T>BSTNode* t = leftmost(); + <T>BSTNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!<T>EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int <T>BSTSet::operator <= (<T>BSTSet& y) +{ + if (count > y.count) + return 0; + else + { + <T>BSTNode* t = leftmost(); + <T>BSTNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = <T>CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +// linear-time, zero space overhead binary tree rebalancing from +// Stout & Warren, ``Tree rebalancing in linear space and time'' +// CACM, Sept, 1986, p902. + + +void <T>BSTSet::balance() +{ + if (count <= 2) return; // don't bother -- + // also we assume non-null root, below + + // make re-attaching the root easy via trickery + + struct _fake_node { _fake_node *lt, *rt, *par; } fake_root; + + fake_root.rt = (_fake_node*)root; + fake_root.par = 0; + <T>BSTNode* pseudo_root = (<T>BSTNode*)&fake_root; + + // phase 1: tree-to-vine + + <T>BSTNode* vine_tail = pseudo_root; + <T>BSTNode* remainder = root; + + while (remainder != 0) + { + if (remainder->lt == 0) + { + vine_tail = remainder; + remainder = remainder->rt; + } + else + { + <T>BSTNode* tmp = remainder->lt; + remainder->lt = tmp->rt; + if (remainder->lt != 0) remainder->lt->par = remainder; + tmp->rt = remainder; + remainder->par = tmp; + vine_tail->rt = remainder = tmp; + } + } + + // phase 2: vine-to-tree + + // Uses the slightly simpler version adapted from + // Day ``Balancing a binary tree'' Computer Journal, Nov. 1976, + // since it's not generally important whether the `stray' leaves are + // on the left or on the right. + + unsigned int spines = count - 1; + while (spines > 1) + { + int compressions = spines >> 1; // compress every other node + spines -= compressions + 1; // halve for next time + + <T>BSTNode* scanner = pseudo_root; + while (compressions-- > 0) + { + <T>BSTNode* child = scanner->rt; + <T>BSTNode* grandchild = child->rt; + scanner->rt = grandchild; + grandchild->par = scanner; + child->rt = grandchild->lt; + if (child->rt != 0) child->rt->par = child; + grandchild->lt = child; + child->par = grandchild; + scanner = grandchild; + } + } + + root = pseudo_root->rt; + root->par = 0; +} + + +int <T>BSTSet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T>BSTNode* trail = leftmost(); + <T>BSTNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/BSTSet.hP b/gnu/lib/libg++/g++-include/gen/BSTSet.hP new file mode 100644 index 000000000000..82f2069c0fa5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/BSTSet.hP @@ -0,0 +1,152 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>BSTSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>BSTSet_h 1 + +#include "<T>.Set.h" + +#ifndef _<T>BSTNode +#define _<T>BSTNode 1 + +struct <T>BSTNode +{ + <T>BSTNode* lt; + <T>BSTNode* rt; + <T>BSTNode* par; + <T> item; + <T>BSTNode(<T&> h, <T>BSTNode* l=0, <T>BSTNode* r=0, + <T>BSTNode* p = 0); + ~<T>BSTNode(); +}; + +inline <T>BSTNode::<T>BSTNode(<T&> h, <T>BSTNode* l, <T>BSTNode* r, + <T>BSTNode* p) +:item(h), lt(l), rt(r), par(p) {} + +inline <T>BSTNode::~<T>BSTNode() {} + +typedef <T>BSTNode* <T>BSTNodePtr; + +#endif + +class <T>BSTSet : public <T>Set +{ +protected: + <T>BSTNode* root; + + <T>BSTNode* leftmost(); + <T>BSTNode* rightmost(); + <T>BSTNode* pred(<T>BSTNode* t); + <T>BSTNode* succ(<T>BSTNode* t); + void _kill(<T>BSTNode* t); + <T>BSTNode* _copy(<T>BSTNode* t); + +public: + <T>BSTSet(); + <T>BSTSet(<T>BSTSet& a); + ~<T>BSTSet(); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item); + + Pix last(); + void prev(Pix& i); + + int operator == (<T>BSTSet& b); + int operator != (<T>BSTSet& b); + int operator <= (<T>BSTSet& b); + + void balance(); + int OK(); +}; + +inline <T>BSTSet::~<T>BSTSet() +{ + _kill(root); +} + +inline <T>BSTSet::<T>BSTSet() +{ + root = 0; + count = 0; +} + + +inline <T>BSTSet::<T>BSTSet(<T>BSTSet& a) +{ + count = a.count; + root = _copy(a.root); +} + +inline int <T>BSTSet::operator != (<T>BSTSet& b) +{ + return ! (*this == b); +} + +inline Pix <T>BSTSet::first() +{ + return Pix(leftmost()); +} + +inline Pix <T>BSTSet::last() +{ + return Pix(rightmost()); +} + +inline void <T>BSTSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T>BSTNode*)i)); +} + +inline void <T>BSTSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T>BSTNode*)i)); +} + +inline <T>& <T>BSTSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>BSTNode*)i)->item; +} + +inline void <T>BSTSet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T>BSTSet::contains(<T&> key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Bag.ccP b/gnu/lib/libg++/g++-include/gen/Bag.ccP new file mode 100644 index 000000000000..836d0d6656d2 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Bag.ccP @@ -0,0 +1,74 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <builtin.h> +#include "<T>.Bag.h" + +// error handling + +void <T>Bag::error(const char* msg) +{ + (*lib_error_handler)("Bag", msg); +} + + +Pix <T>Bag::seek(<T&> item, Pix i) +{ + if (i == 0) + i = first(); + else + next(i); + for (;i != 0 && (!(<T>EQ((*this)(i), item))); next(i)); + return i; +} + +int <T>Bag::owns(Pix p) +{ + if (p == 0) return 0; + for (Pix i = first(); i != 0; next(i)) if (i == p) return 1; + return 0; +} + +void <T>Bag::remove(<T&> item) +{ + int i = nof(item); + while (i-- > 0) del(item); +} + + +int <T>Bag::nof(<T&> item) +{ + int n = 0; + for (Pix p = first(); p; next(p)) if (<T>EQ((*this)(p), item)) ++n; + return n; +} + +void <T>Bag::clear() +{ + Pix i = first(); + while (i != 0) + { + del((*this)(i)); + i = first(); + } +} + + diff --git a/gnu/lib/libg++/g++-include/gen/Bag.hP b/gnu/lib/libg++/g++-include/gen/Bag.hP new file mode 100644 index 000000000000..4b9a87a9099c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Bag.hP @@ -0,0 +1,79 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>Bag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>Bag_h 1 + +#include <Pix.h> +#include "<T>.defs.h" + +class <T>Bag +{ +protected: + int count; + +public: + virtual ~<T>Bag(); + + int length(); // current number of items + int empty(); + + virtual Pix add(<T&> item) = 0; // add item; return Pix + + virtual void del(<T&> item) = 0; // delete 1 occurrence of item +#undef remove + virtual void remove(<T&> item); // delete all occurrences + virtual void clear(); // delete all items + + virtual int contains(<T&> item); // is item in Bag? + virtual int nof(<T&> item); // how many in Bag? + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + + virtual <T>& operator () (Pix i) = 0; // access item at i + + virtual Pix seek(<T&> item, Pix from=0); // Pix of next occurrence + virtual int owns(Pix i); // is i a valid Pix ? + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + +inline <T>Bag::~<T>Bag() {} + +inline int <T>Bag::length() +{ + return count; +} + +inline int <T>Bag::empty() +{ + return count == 0; +} + +inline int <T>Bag::contains(<T&> item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHBag.ccP b/gnu/lib/libg++/g++-include/gen/CHBag.ccP new file mode 100644 index 000000000000..16649ac22f2f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHBag.ccP @@ -0,0 +1,209 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.CHBag.h" + +// The nodes are linked together serially via a version +// of a trick used in some vtables: odd pointers are +// actually links to the next table entry. +// Not terrible, but not wonderful either + +static inline int goodCHptr(<T>CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline <T>CHNode* index_to_CHptr(int i) +{ + return (<T>CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(<T>CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +<T>CHBag::<T>CHBag(unsigned int sz) +{ + tab = (<T>CHNode**)(new <T>CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +<T>CHBag::<T>CHBag(<T>CHBag& a) +{ + tab = (<T>CHNode**)(new <T>CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +Pix <T>CHBag::seek(<T&> key, Pix i) +{ + <T>CHNode* p = (<T>CHNode*)i; + if (p == 0 || !<T>EQ(p->hd, key)) + { + unsigned int h = <T>HASH(key) % size; + for (<T>CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (<T>EQ(key, t->hd)) + return Pix(t); + } + else + { + for (p = p->tl; goodCHptr(p); p = p->tl) + if (<T>EQ(p->hd, key)) + return Pix(p); + } + return 0; +} + +int <T>CHBag::nof(<T&> key) +{ + int n = 0; + unsigned int h = <T>HASH(key) % size; + for (<T>CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (<T>EQ(key, t->hd)) ++n; + return n; +} + + +Pix <T>CHBag::add(<T&> item) +{ + unsigned int h = <T>HASH(item) % size; + <T>CHNode* t = new <T>CHNode(item); + t->tl = tab[h]; + tab[h] = t; + ++count; + return Pix(t); +} + +void <T>CHBag::del(<T&> key) +{ + unsigned int h = <T>HASH(key) % size; + + <T>CHNode* t = tab[h]; + <T>CHNode* trail = t; + while (goodCHptr(t)) + { + if (<T>EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + +void <T>CHBag::remove(<T&> key) +{ + unsigned int h = <T>HASH(key) % size; + + <T>CHNode* t = tab[h]; + <T>CHNode* trail = t; + while (goodCHptr(t)) + { + if (<T>EQ(key, t->hd)) + { + --count; + if (trail == t) + { + tab[h] = t->tl; + delete t; + t = trail = tab[h]; + } + else + { + trail->tl = t->tl; + delete t; + t = trail->tl; + } + } + else + { + trail = t; + t = t->tl; + } + } +} + + +void <T>CHBag::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + <T>CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + <T>CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix <T>CHBag::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void <T>CHBag::next(Pix& p) +{ + if (p == 0) return; + <T>CHNode* t = ((<T>CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + +int <T>CHBag::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (<T>CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/CHBag.hP b/gnu/lib/libg++/g++-include/gen/CHBag.hP new file mode 100644 index 000000000000..f6ca10b3b93e --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHBag.hP @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>CHBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>CHBag_h 1 + +#include "<T>.Bag.h" + + +#include "<T>.CHNode.h" + +class <T>CHBag : public <T>Bag +{ +protected: + <T>CHNode** tab; + unsigned int size; + +public: + <T>CHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + <T>CHBag(<T>CHBag& a); + ~<T>CHBag(); + + Pix add(<T&> item); + void del(<T&> item); + void remove(<T&>item); + int nof(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item, Pix from = 0); + + int OK(); +}; + + +inline <T>CHBag::~<T>CHBag() +{ + clear(); + delete tab; +} + +inline int <T>CHBag::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline <T>& <T>CHBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>CHNode*)i)->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHMap.ccP b/gnu/lib/libg++/g++-include/gen/CHMap.ccP new file mode 100644 index 000000000000..1bd76db5fc97 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHMap.ccP @@ -0,0 +1,166 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.<C>.CHMap.h" + +// The nodes are linked together serially via a version +// of a trick used in some vtables: odd pointers are +// actually links to the next table entry. +// Not terrible, but not wonderful either + +static inline int goodCHptr(<T><C>CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline <T><C>CHNode* index_to_CHptr(int i) +{ + return (<T><C>CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(<T><C>CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +<T><C>CHMap::<T><C>CHMap(<C&> dflt, unsigned int sz) + :<T><C>Map(dflt) +{ + tab = (<T><C>CHNode**)(new <T><C>CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +<T><C>CHMap::<T><C>CHMap(<T><C>CHMap& a) :<T><C>Map(a.def) +{ + tab = (<T><C>CHNode**)(new <T><C>CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p); +} + + +Pix <T><C>CHMap::seek(<T&> key) +{ + unsigned int h = <T>HASH(key) % size; + + for (<T><C>CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (<T>EQ(key, t->hd)) + return Pix(t); + + return 0; +} + + +<C>& <T><C>CHMap::operator [](<T&> item) +{ + unsigned int h = <T>HASH(item) % size; + + for (<T><C>CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (<T>EQ(item, t->hd)) + return t->cont; + + t = new <T><C>CHNode(item, def, tab[h]); + tab[h] = t; + ++count; + return t->cont; +} + + +void <T><C>CHMap::del(<T&> key) +{ + unsigned int h = <T>HASH(key) % size; + + <T><C>CHNode* t = tab[h]; + <T><C>CHNode* trail = t; + while (goodCHptr(t)) + { + if (<T>EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + + +void <T><C>CHMap::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + <T><C>CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + <T><C>CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix <T><C>CHMap::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void <T><C>CHMap::next(Pix& p) +{ + <T><C>CHNode* t = ((<T><C>CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + + +int <T><C>CHMap::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (<T><C>CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/CHMap.hP b/gnu/lib/libg++/g++-include/gen/CHMap.hP new file mode 100644 index 000000000000..95441a3544fd --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHMap.hP @@ -0,0 +1,104 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T><C>CHMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T><C>CHMap_h 1 + +#include "<T>.<C>.Map.h" + +#ifndef _<T><C>CHNode_h +#define _<T><C>CHNode_h 1 + +struct <T><C>CHNode +{ + <T><C>CHNode* tl; + <T> hd; + <C> cont; + <T><C>CHNode(); + <T><C>CHNode(<T&> h, <C&> c, <T><C>CHNode* t = 0); + ~<T><C>CHNode(); +}; + +inline <T><C>CHNode::<T><C>CHNode() {} + +inline <T><C>CHNode::<T><C>CHNode(<T&> h, <C&> c, <T><C>CHNode* t) + : hd(h), cont(c), tl(t) {} + +inline <T><C>CHNode::~<T><C>CHNode() {} + +typedef <T><C>CHNode* <T><C>CHNodePtr; + +#endif + + +class <T><C>CHMap : public <T><C>Map +{ +protected: + <T><C>CHNode** tab; + unsigned int size; + +public: + <T><C>CHMap(<C&> dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY); + <T><C>CHMap(<T><C>CHMap& a); + ~<T><C>CHMap(); + + <C>& operator [] (<T&> key); + + void del(<T&> key); + + Pix first(); + void next(Pix& i); + <T>& key(Pix i); + <C>& contents(Pix i); + + Pix seek(<T&> key); + int contains(<T&> key); + + void clear(); + int OK(); +}; + + +inline <T><C>CHMap::~<T><C>CHMap() +{ + clear(); + delete tab; +} + +inline int <T><C>CHMap::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline <T>& <T><C>CHMap::key(Pix p) +{ + if (p == 0) error("null Pix"); + return ((<T><C>CHNode*)p)->hd; +} + +inline <C>& <T><C>CHMap::contents(Pix p) +{ + if (p == 0) error("null Pix"); + return ((<T><C>CHNode*)p)->cont; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHNode.ccP b/gnu/lib/libg++/g++-include/gen/CHNode.ccP new file mode 100644 index 000000000000..e16725fd746c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHNode.ccP @@ -0,0 +1,21 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1992 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.CHNode.h" diff --git a/gnu/lib/libg++/g++-include/gen/CHNode.hP b/gnu/lib/libg++/g++-include/gen/CHNode.hP new file mode 100644 index 000000000000..84e67d069bee --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHNode.hP @@ -0,0 +1,43 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _<T>CHNode_h +#define _<T>CHNode_h 1 +#ifdef __GNUG__ +#pragma interface +#endif +#include "<T>.defs.h" + +struct <T>CHNode +{ + <T>CHNode* tl; + <T> hd; + <T>CHNode(); + <T>CHNode(<T&> h, <T>CHNode* t = 0); + ~<T>CHNode(); +}; + +inline <T>CHNode::<T>CHNode() {} + +inline <T>CHNode::<T>CHNode(<T&> h, <T>CHNode* t) :hd(h), tl(t) {} + +inline <T>CHNode::~<T>CHNode() {} + +typedef <T>CHNode* <T>CHNodePtr; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/CHSet.ccP b/gnu/lib/libg++/g++-include/gen/CHSet.ccP new file mode 100644 index 000000000000..330506cb1932 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHSet.ccP @@ -0,0 +1,271 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.CHSet.h" + +// A CHSet is implemented as an array (tab) of buckets, each of which +// contains a pointer to a list of <T>CHNodes. Each node contains a +// pointer to the next node in the list, and a pointer to the <T>. +// The end of the list is marked by a next node pointer which is odd +// when considered as an integer (least significant bit = 1). The +// assumption is that CHNodes will all begin on even addresses. If +// the odd pointer is right-shifted by one bit, it becomes the index +// within the tab array of the next bucket (that is, bucket i has +// next bucket pointer 2*(i+1)+1). + +// The bucket pointers are initialized by the constructor and +// used to support the next(Pix&) method. + +// This implementation is not portable to machines with different +// pointer and integer sizes, or on which CHNodes might be aligned on +// odd byte boundaries, but allows the same pointer to be used for +// chaining within a bucket and to the next bucket. + + +static inline int goodCHptr(<T>CHNode* t) +{ + return ((((unsigned)t) & 1) == 0); +} + +static inline <T>CHNode* index_to_CHptr(int i) +{ + return (<T>CHNode*)((i << 1) + 1); +} + +static inline int CHptr_to_index(<T>CHNode* t) +{ + return ( ((unsigned) t) >> 1); +} + +<T>CHSet::<T>CHSet(unsigned int sz) +{ + tab = (<T>CHNode**)(new <T>CHNodePtr[size = sz]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; +} + +<T>CHSet::<T>CHSet(<T>CHSet& a) +{ + tab = (<T>CHNode**)(new <T>CHNodePtr[size = a.size]); + for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1); + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +Pix <T>CHSet::seek(<T&> key) +{ + unsigned int h = <T>HASH(key) % size; + + for (<T>CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (<T>EQ(key, t->hd)) + return Pix(t); + + return 0; +} + + +Pix <T>CHSet::add(<T&> item) +{ + unsigned int h = <T>HASH(item) % size; + + for (<T>CHNode* t = tab[h]; goodCHptr(t); t = t->tl) + if (<T>EQ(item, t->hd)) + return Pix(t); + + ++count; + t = new <T>CHNode(item, tab[h]); + tab[h] = t; + return Pix(t); +} + + +void <T>CHSet::del(<T&> key) +{ + unsigned int h = <T>HASH(key) % size; + + <T>CHNode* t = tab[h]; + <T>CHNode* trail = t; + while (goodCHptr(t)) + { + if (<T>EQ(key, t->hd)) + { + if (trail == t) + tab[h] = t->tl; + else + trail->tl = t->tl; + delete t; + --count; + return; + } + trail = t; + t = t->tl; + } +} + + +void <T>CHSet::clear() +{ + for (unsigned int i = 0; i < size; ++i) + { + <T>CHNode* p = tab[i]; + tab[i] = index_to_CHptr(i+1); + while (goodCHptr(p)) + { + <T>CHNode* nxt = p->tl; + delete(p); + p = nxt; + } + } + count = 0; +} + +Pix <T>CHSet::first() +{ + for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]); + return 0; +} + +void <T>CHSet::next(Pix& p) +{ + if (p == 0) return; + <T>CHNode* t = ((<T>CHNode*)p)->tl; + if (goodCHptr(t)) + p = Pix(t); + else + { + for (unsigned int i = CHptr_to_index(t); i < size; ++i) + { + if (goodCHptr(tab[i])) + { + p = Pix(tab[i]); + return; + } + } + p = 0; + } +} + +int <T>CHSet::operator == (<T>CHSet& b) +{ + if (count != b.count) + return 0; + else + { + <T>CHNode* p; + for (unsigned int i = 0; i < size; ++i) + for (p = tab[i]; goodCHptr(p); p = p->tl) + if (b.seek(p->hd) == 0) + return 0; + for (i = 0; i < b.size; ++i) + for (p = b.tab[i]; goodCHptr(p); p = p->tl) + if (seek(p->hd) == 0) + return 0; + return 1; + } +} + +int <T>CHSet::operator <= (<T>CHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + for (<T>CHNode* p = tab[i]; goodCHptr(p); p = p->tl) + if (b.seek(p->hd) == 0) + return 0; + return 1; + } +} + +void <T>CHSet::operator |= (<T>CHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (unsigned int i = 0; i < b.size; ++i) + for (<T>CHNode* p = b.tab[i]; goodCHptr(p); p = p->tl) + add(p->hd); +} + +void <T>CHSet::operator &= (<T>CHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + <T>CHNode* t = tab[i]; + <T>CHNode* trail = t; + while (goodCHptr(t)) + { + <T>CHNode* nxt = t->tl; + if (b.seek(t->hd) == 0) + { + if (trail == tab[i]) + trail = tab[i] = nxt; + else + trail->tl = nxt; + delete t; + --count; + } + else + trail = t; + t = nxt; + } + } +} + +void <T>CHSet::operator -= (<T>CHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + <T>CHNode* t = tab[i]; + <T>CHNode* trail = t; + while (goodCHptr(t)) + { + <T>CHNode* nxt = t->tl; + if (b.seek(t->hd) != 0) + { + if (trail == tab[i]) + trail = tab[i] = nxt; + else + trail->tl = nxt; + delete t; + --count; + } + else + trail = t; + t = nxt; + } + } +} + +int <T>CHSet::OK() +{ + int v = tab != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + for (<T>CHNode* p = tab[i]; goodCHptr(p); p = p->tl) ++n; + v &= CHptr_to_index(p) == i + 1; + } + v &= count == n; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/CHSet.hP b/gnu/lib/libg++/g++-include/gen/CHSet.hP new file mode 100644 index 000000000000..f0a08de4ce6b --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/CHSet.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>CHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>CHSet_h 1 + +#include "<T>.Set.h" +#include "<T>.CHNode.h" + +class <T>CHSet : public <T>Set +{ +protected: + <T>CHNode** tab; + unsigned int size; + +public: + <T>CHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + <T>CHSet(<T>CHSet& a); + ~<T>CHSet(); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item); + + void operator |= (<T>CHSet& b); + void operator -= (<T>CHSet& b); + void operator &= (<T>CHSet& b); + + int operator == (<T>CHSet& b); + int operator != (<T>CHSet& b); + int operator <= (<T>CHSet& b); + + int OK(); +}; + +inline <T>CHSet::~<T>CHSet() +{ + clear(); + delete tab; +} + +inline int <T>CHSet::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline <T>& <T>CHSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>CHNode*)i)->hd; +} + +inline int <T>CHSet::operator != (<T>CHSet& b) +{ + return ! ((*this) == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/DLDeque.ccP b/gnu/lib/libg++/g++-include/gen/DLDeque.ccP new file mode 100644 index 000000000000..d5a0db7f910a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLDeque.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.DLDeque.h" diff --git a/gnu/lib/libg++/g++-include/gen/DLDeque.hP b/gnu/lib/libg++/g++-include/gen/DLDeque.hP new file mode 100644 index 000000000000..d91cdd41cbc7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLDeque.hP @@ -0,0 +1,130 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>DLDeque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>DLDeque_h + +#include "<T>.DLList.h" +#include "<T>.Deque.h" + +class <T>DLDeque : public <T>Deque +{ + <T>DLList p; + +public: + <T>DLDeque(); + <T>DLDeque(const <T>DLDeque& d); + ~<T>DLDeque(); + + void operator = (const <T>DLDeque&); + + void push(<T&> item); // insert at front + void enq(<T&> item); // insert at rear + + <T>& front(); + <T>& rear(); + + <T> deq(); + void del_front(); + void del_rear(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + + +inline <T>DLDeque::<T>DLDeque() : p() {} +inline <T>DLDeque::<T>DLDeque(const <T>DLDeque& d) : p(d.p) {} + +inline <T>DLDeque::~<T>DLDeque() {} + +inline void <T>DLDeque::push(<T&>item) +{ + p.prepend(item); +} + +inline void <T>DLDeque::enq(<T&>item) +{ + p.append(item); +} + +inline <T> <T>DLDeque::deq() +{ + return p.remove_front(); +} + +inline <T>& <T>DLDeque::front() +{ + return p.front(); +} + +inline <T>& <T>DLDeque::rear() +{ + return p.rear(); +} + +inline void <T>DLDeque::del_front() +{ + p.del_front(); +} + +inline void <T>DLDeque::del_rear() +{ + p.del_rear(); +} + +inline void <T>DLDeque::operator =(const <T>DLDeque& s) +{ + p.operator = (s.p); +} + + +inline int <T>DLDeque::empty() +{ + return p.empty(); +} + +inline int <T>DLDeque::full() +{ + return 0; +} + +inline int <T>DLDeque::length() +{ + return p.length(); +} + +inline int <T>DLDeque::OK() +{ + return p.OK(); +} + +inline void <T>DLDeque::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/DLList.ccP b/gnu/lib/libg++/g++-include/gen/DLList.ccP new file mode 100644 index 000000000000..cb1e22a33773 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLList.ccP @@ -0,0 +1,339 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../DLList.cc, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <values.h> +#include <stream.h> +#include <builtin.h> +#include "<T>.DLList.h" + +// error handling + + + +void <T>DLList::error(const char* msg) +{ + (*lib_error_handler)("DLList", msg); +} + +int <T>DLList::length() +{ + int l = 0; + <T>DLListNode* t = h; + if (t != 0) do { ++l; t = t->fd; } while (t != h); + return l; +} + +<T>DLList::<T>DLList(const <T>DLList& a) +{ + if (a.h == 0) + h = 0; + else + { + <T>DLListNode* p = a.h; + <T>DLListNode* t = new <T>DLListNode(p->hd); + h = t; + p = p->fd; + while (p != a.h) + { + <T>DLListNode* n = new <T>DLListNode(p->hd); + t->fd = n; + n->bk = t; + t = n; + p = p->fd; + } + t->fd = h; + h->bk = t; + return; + } +} + +<T>DLList& <T>DLList::operator = (const <T>DLList& a) +{ + if (h != a.h) + { + clear(); + if (a.h != 0) + { + <T>DLListNode* p = a.h; + <T>DLListNode* t = new <T>DLListNode(p->hd); + h = t; + p = p->fd; + while (p != a.h) + { + <T>DLListNode* n = new <T>DLListNode(p->hd); + t->fd = n; + n->bk = t; + t = n; + p = p->fd; + } + t->fd = h; + h->bk = t; + } + } + return *this; +} + +void <T>DLList::clear() +{ + if (h == 0) + return; + + <T>DLListNode* p = h->fd; + h->fd = 0; + h = 0; + + while (p != 0) + { + <T>DLListNode* nxt = p->fd; + delete(p); + p = nxt; + } +} + + +Pix <T>DLList::prepend(<T&> item) +{ + <T>DLListNode* t = new <T>DLListNode(item); + if (h == 0) + t->fd = t->bk = h = t; + else + { + t->fd = h; + t->bk = h->bk; + h->bk->fd = t; + h->bk = t; + h = t; + } + return Pix(t); +} + +Pix <T>DLList::append(<T&> item) +{ + <T>DLListNode* t = new <T>DLListNode(item); + if (h == 0) + t->fd = t->bk = h = t; + else + { + t->bk = h->bk; + t->bk->fd = t; + t->fd = h; + h->bk = t; + } + return Pix(t); +} + +Pix <T>DLList::ins_after(Pix p, <T&> item) +{ + if (p == 0) return prepend(item); + <T>DLListNode* u = (<T>DLListNode*) p; + <T>DLListNode* t = new <T>DLListNode(item, u, u->fd); + u->fd->bk = t; + u->fd = t; + return Pix(t); +} + +Pix <T>DLList::ins_before(Pix p, <T&> item) +{ + if (p == 0) error("null Pix"); + <T>DLListNode* u = (<T>DLListNode*) p; + <T>DLListNode* t = new <T>DLListNode(item, u->bk, u); + u->bk->fd = t; + u->bk = t; + if (u == h) h = t; + return Pix(t); +} + +void <T>DLList::join(<T>DLList& b) +{ + <T>DLListNode* t = b.h; + b.h = 0; + if (h == 0) + h = t; + else if (t != 0) + { + <T>DLListNode* l = t->bk; + h->bk->fd = t; + t->bk = h->bk; + h->bk = l; + l->fd = h; + } +} + +int <T>DLList::owns(Pix p) +{ + <T>DLListNode* t = h; + if (t != 0 && p != 0) + { + do + { + if (Pix(t) == p) return 1; + t = t->fd; + } while (t != h); + } + return 0; +} + +void <T>DLList::del(Pix& p, int dir) +{ + if (p == 0) error("null Pix"); + <T>DLListNode* t = (<T>DLListNode*) p; + if (t->fd == t) + { + h = 0; + p = 0; + } + else + { + if (dir < 0) + { + if (t == h) + p = 0; + else + p = Pix(t->bk); + } + else + { + if (t == h->bk) + p = 0; + else + p = Pix(t->fd); + } + t->bk->fd = t->fd; + t->fd->bk = t->bk; + if (t == h) h = t->fd; + } + delete t; +} + +void <T>DLList::del_after(Pix& p) +{ + if (p == 0) + { + del_front(); + return; + } + + <T>DLListNode* b = (<T>DLListNode*) p; + <T>DLListNode* t = b->fd; + + if (b == t) + { + h = 0; + p = 0; + } + else + { + t->bk->fd = t->fd; + t->fd->bk = t->bk; + if (t == h) h = t->fd; + } + delete t; +} + +<T> <T>DLList::remove_front() +{ + if (h == 0) + error("remove_front of empty list"); + <T>DLListNode* t = h; + <T> res = t->hd; + if (h->fd == h) + h = 0; + else + { + h->fd->bk = h->bk; + h->bk->fd = h->fd; + h = h->fd; + } + delete t; + return res; +} + + +void <T>DLList::del_front() +{ + if (h == 0) + error("del_front of empty list"); + <T>DLListNode* t = h; + if (h->fd == h) + h = 0; + else + { + h->fd->bk = h->bk; + h->bk->fd = h->fd; + h = h->fd; + } + delete t; +} + +<T> <T>DLList::remove_rear() +{ + if (h == 0) + error("remove_rear of empty list"); + <T>DLListNode* t = h->bk; + <T> res = t->hd; + if (h->fd == h) + h = 0; + else + { + t->fd->bk = t->bk; + t->bk->fd = t->fd; + } + delete t; + return res; +} + + +void <T>DLList::del_rear() +{ + if (h == 0) + error("del_rear of empty list"); + <T>DLListNode* t = h->bk; + if (h->fd == h) + h = 0; + else + { + t->fd->bk = t->bk; + t->bk->fd = t->fd; + } + delete t; +} + + +int <T>DLList::OK() +{ + int v = 1; + if (h != 0) + { + <T>DLListNode* t = h; + long count = MAXLONG; // Lots of chances to find h! + do + { + count--; + v &= t->bk->fd == t; + v &= t->fd->bk == t; + t = t->fd; + } while (v && count > 0 && t != h); + v &= count > 0; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/DLList.hP b/gnu/lib/libg++/g++-include/gen/DLList.hP new file mode 100644 index 000000000000..b115ab9f6fbb --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/DLList.hP @@ -0,0 +1,157 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../DLList.h, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>DLList_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>DLList_h 1 + +#include <Pix.h> +#include "<T>.defs.h" + +#ifndef _<T>DLListNode_h +#define _<T>DLListNode_h 1 + +struct <T>DLListNode +{ + <T>DLListNode* bk; + <T>DLListNode* fd; + <T> hd; + <T>DLListNode(); + <T>DLListNode(const <T&> h, + <T>DLListNode* p = 0, + <T>DLListNode* n = 0); + ~<T>DLListNode(); +}; + +inline <T>DLListNode::<T>DLListNode() {} + +inline <T>DLListNode::<T>DLListNode(const <T&> h, <T>DLListNode* p, + <T>DLListNode* n) + :hd(h), bk(p), fd(n) {} + +inline <T>DLListNode::~<T>DLListNode() {} + +typedef <T>DLListNode* <T>DLListNodePtr; + +#endif + +class <T>DLList +{ + friend class <T>DLListTrav; + + <T>DLListNode* h; + +public: + <T>DLList(); + <T>DLList(const <T>DLList& a); + ~<T>DLList(); + + <T>DLList& operator = (const <T>DLList& a); + + int empty(); + int length(); + + void clear(); + + Pix prepend(<T&> item); + Pix append(<T&> item); + void join(<T>DLList&); + + <T>& front(); + <T> remove_front(); + void del_front(); + + <T>& rear(); + <T> remove_rear(); + void del_rear(); + + <T>& operator () (Pix p); + Pix first(); + Pix last(); + void next(Pix& p); + void prev(Pix& p); + int owns(Pix p); + Pix ins_after(Pix p, <T&> item); + Pix ins_before(Pix p, <T&> item); + void del(Pix& p, int dir = 1); + void del_after(Pix& p); + + void error(const char* msg); + int OK(); +}; + + +inline <T>DLList::~<T>DLList() +{ + clear(); +} + +inline <T>DLList::<T>DLList() +{ + h = 0; +} + +inline int <T>DLList::empty() +{ + return h == 0; +} + + +inline void <T>DLList::next(Pix& p) +{ + p = (p == 0 || p == h->bk)? 0 : Pix(((<T>DLListNode*)p)->fd); +} + +inline void <T>DLList::prev(Pix& p) +{ + p = (p == 0 || p == h)? 0 : Pix(((<T>DLListNode*)p)->bk); +} + +inline Pix <T>DLList::first() +{ + return Pix(h); +} + +inline Pix <T>DLList::last() +{ + return (h == 0)? 0 : Pix(h->bk); +} + +inline <T>& <T>DLList::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return ((<T>DLListNode*)p)->hd; +} + +inline <T>& <T>DLList::front() +{ + if (h == 0) error("front: empty list"); + return h->hd; +} + +inline <T>& <T>DLList::rear() +{ + if (h == 0) error("rear: empty list"); + return h->bk->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Deque.ccP b/gnu/lib/libg++/g++-include/gen/Deque.ccP new file mode 100644 index 000000000000..79a9b72c875c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Deque.ccP @@ -0,0 +1,11 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.Deque.h" + +<T>Deque::~<T>Deque() {} + +void <T>Deque::error(const char* msg) +{ + (*lib_error_handler)("Deque", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Deque.hP b/gnu/lib/libg++/g++-include/gen/Deque.hP new file mode 100644 index 000000000000..7ec52d4a0c0f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Deque.hP @@ -0,0 +1,57 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>Deque_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>Deque_h + +#include <builtin.h> + +#include "<T>.defs.h" + +class <T>Deque +{ +public: + <T>Deque() { } + virtual ~<T>Deque(); + + virtual void push(<T&> item) = 0; // insert at front + virtual void enq(<T&> item) = 0; // insert at rear + + virtual <T>& front() = 0; + virtual <T>& rear() = 0; + + virtual <T> deq() = 0; + virtual void del_front() = 0; + virtual void del_rear() = 0; + + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + virtual void clear() = 0; + + virtual int OK() = 0; + + void error(const char*); +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/FPQueue.ccP b/gnu/lib/libg++/g++-include/gen/FPQueue.ccP new file mode 100644 index 000000000000..a358cacb60ee --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.FPQueue.h" diff --git a/gnu/lib/libg++/g++-include/gen/FPQueue.hP b/gnu/lib/libg++/g++-include/gen/FPQueue.hP new file mode 100644 index 000000000000..f647ae9dfd01 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPQueue.hP @@ -0,0 +1,112 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>FPQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>FPQueue_h + +#include "<T>.FPlex.h" +#include "<T>.Queue.h" + +class <T>FPQueue : public <T>Queue +{ + <T>FPlex p; + +public: + <T>FPQueue(int chunksize = DEFAULT_INITIAL_CAPACITY); + <T>FPQueue(const <T>FPQueue& q); + ~<T>FPQueue(); + + void operator = (const <T>FPQueue&); + + void enq(<T&> item); + <T> deq(); + <T>& front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline <T>FPQueue::<T>FPQueue(int chunksize) : p(chunksize) {} +inline <T>FPQueue::<T>FPQueue(const <T>FPQueue& q) : p(q.p) {} + +inline <T>FPQueue::~<T>FPQueue() {} + +inline void <T>FPQueue::enq(<T&>item) +{ + p.add_high(item); +} + +inline <T> <T>FPQueue::deq() +{ + <T> res = p.low_element(); + p.del_low(); + return res; +} + +inline <T>& <T>FPQueue::front() +{ + return p.low_element(); +} + + +inline void <T>FPQueue::del_front() +{ + p.del_low(); +} + +inline void <T>FPQueue::operator =(const <T>FPQueue& s) +{ + p = s.p; +} + +inline int <T>FPQueue::empty() +{ + return p.empty(); +} + +inline int <T>FPQueue::full() +{ + return p.full(); +} + +inline int <T>FPQueue::length() +{ + return p.length(); +} + +inline int <T>FPQueue::OK() +{ + return p.OK(); +} + +inline void <T>FPQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/FPStack.ccP b/gnu/lib/libg++/g++-include/gen/FPStack.ccP new file mode 100644 index 000000000000..954991193b7a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.FPStack.h" diff --git a/gnu/lib/libg++/g++-include/gen/FPStack.hP b/gnu/lib/libg++/g++-include/gen/FPStack.hP new file mode 100644 index 000000000000..091f25536002 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPStack.hP @@ -0,0 +1,114 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>FPStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>FPStack_h + +#include "<T>.FPlex.h" +#include "<T>.Stack.h" + +class <T>FPStack : public <T>Stack +{ + <T>FPlex p; + +public: + <T>FPStack(int chunksize = DEFAULT_INITIAL_CAPACITY); + <T>FPStack(const <T>FPStack& s); + ~<T>FPStack(); + + void operator = (const <T>FPStack&); + + void push(<T&> item); + <T> pop(); + <T>& top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + + +inline <T>FPStack::<T>FPStack(int chunksize) : p(chunksize) {} +inline <T>FPStack::<T>FPStack(const <T>FPStack& s) : p(s.p) {} + +inline <T>FPStack::~<T>FPStack() {} + +inline void <T>FPStack::push(<T&>item) +{ + p.add_high(item); +} + +inline <T> <T>FPStack::pop() +{ + <T> res = p.high_element(); + p.del_high(); + return res; +} + +inline <T>& <T>FPStack::top() +{ + return p.high_element(); +} + +inline void <T>FPStack::del_top() +{ + p.del_high(); +} + +inline void <T>FPStack::operator =(const <T>FPStack& s) +{ + p = s.p; +} + +inline int <T>FPStack::empty() +{ + return p.empty(); +} + +inline int <T>FPStack::full() +{ + return p.full(); +} + +inline int <T>FPStack::length() +{ + return p.length(); +} + +inline int <T>FPStack::OK() +{ + return p.OK(); +} + +inline void <T>FPStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/FPlex.ccP b/gnu/lib/libg++/g++-include/gen/FPlex.ccP new file mode 100644 index 000000000000..70d6c475571e --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPlex.ccP @@ -0,0 +1,167 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.FPlex.h" + + +<T>FPlex:: <T>FPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + <T>* data = new <T>[csize]; + hd = new <T>IChunk(data, lo, lo, fnc, csize); +} + +<T>FPlex:: <T>FPlex(int maxsize) +{ + if (maxsize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (maxsize > 0) + { + csize = maxsize; + <T>* data = new <T>[csize]; + hd = new <T>IChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -maxsize; + <T>* data = new <T>[csize]; + hd = new <T>IChunk(data, maxsize, lo, fnc, fnc); + } +} + + +<T>FPlex:: <T>FPlex(int l, int maxsize) +{ + if (maxsize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (maxsize > 0) + { + csize = maxsize; + <T>* data = new <T>[csize]; + hd = new <T>IChunk(data, lo, lo, fnc, csize+lo); + } + else + { + csize = -maxsize; + <T>* data = new <T>[csize]; + hd = new <T>IChunk(data, maxsize+lo, lo, fnc, fnc); + } +} + +<T>FPlex:: <T>FPlex(int l, int hi, const <T&> initval, int maxsize) +{ + lo = l; + fnc = hi + 1; + if (maxsize >= 0) + { + csize = maxsize; + if (csize < fnc - lo) + csize = fnc - lo; + <T>* data = new <T>[csize]; + hd = new <T>IChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -maxsize; + if (csize < fnc - lo) + csize = fnc - lo; + <T>* data = new <T>[csize]; + hd = new <T>IChunk(data, -csize, lo, fnc, fnc); + } + fill(initval); +} + +<T>FPlex::<T>FPlex(const <T>FPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = fnc - lo; + if (csize < a.csize) csize = a.csize; + <T>* data = new <T> [csize]; + hd = new <T>IChunk(data, lo, lo, fnc, lo+csize); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void <T>FPlex::operator= (const <T>FPlex& a) +{ + if (&a != this) + { + del_chunk(hd); + lo = a.lo; + fnc = a.fnc; + csize = fnc - lo; + if (csize < a.csize) csize = a.csize; + <T>* data = new <T> [csize]; + hd = new <T>IChunk(data, lo, lo, fnc, lo+csize); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void <T>FPlex::reverse() +{ + <T> tmp; + int l = lo; + int h = fnc - 1; + while (l < h) + { + tmp = (*this)[l]; + (*this)[l] = (*this)[h]; + (*this)[h] = tmp; + next(l); + prev(h); + } +} + +void <T>FPlex::fill(const <T&> x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void <T>FPlex::fill(const <T&> x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + +void <T>FPlex::clear() +{ + if (fnc != lo) + { + hd->clear(lo); + fnc = lo; + } +} + +int <T>FPlex::OK () const +{ + int v = hd != 0; // hd exists + v &= hd-><T>IChunk::OK(); // and is OK + v &= fnc - lo <= hd->size(); // and has enough space + v &= lo <= fnc; // plex indices consistent + v &= lo == hd->low_index(); // and match those + v &= fnc == hd->fence_index(); // of chunk + v &= one_chunk(); // and only one chunk + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/FPlex.hP b/gnu/lib/libg++/g++-include/gen/FPlex.hP new file mode 100644 index 000000000000..eb93a0c37281 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/FPlex.hP @@ -0,0 +1,253 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _<T>FPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>FPlex_h 1 + +#include "<T>.Plex.h" + +class <T>FPlex : public <T>Plex +{ +public: + <T>FPlex(); // set low = 0; + // fence = 0; + // csize = default + + <T>FPlex(int maxsize); // low = 0; + // fence = 0; + // csize = maxsize + + <T>FPlex(int lo, // low = lo; + int maxsize); // fence=lo + // csize = maxsize + + <T>FPlex(int lo, // low = lo + int hi, // fence = hi+1 + const <T&> initval,// fill with initval, + int maxsize = 0); // csize = maxsize + // or fence - lo if 0 + + <T>FPlex(const <T>FPlex&); // X(X&) + + ~<T>FPlex(); + + void operator= (const <T>FPlex&); + +// virtuals + + <T>& high_element (); + <T>& low_element (); + + const <T>& high_element () const; + const <T>& low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + <T>& operator () (Pix p); + const <T>& operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + <T>& operator [] (int index); + const <T>& operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const <T&> elem); + int del_high (); + int add_low (const <T&> elem); + int del_low (); + + void fill(const <T&> x); + void fill(const <T&> x, int from, int to); + void clear(); + void reverse(); + + int OK () const; +}; + + +inline int <T>FPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int <T>FPlex::low() const +{ + return lo; +} + +inline int <T>FPlex::high() const +{ + return fnc - 1; +} + +inline Pix <T>FPlex::first() const +{ + return (Pix)(hd-><T>IChunk::first_pointer()); +} + +inline void <T>FPlex::prev(Pix& p) const +{ + p = Pix(hd-><T>IChunk::pred((<T>*) p)); +} + +inline void <T>FPlex::next(Pix& p) const +{ + p = Pix(hd-><T>IChunk::succ((<T>*) p)); +} + +inline Pix <T>FPlex::last() const +{ + return Pix(hd-><T>IChunk::last_pointer()); +} + +inline int <T>FPlex::full () const +{ + return fnc - lo == csize; +} + +inline void <T>FPlex::prev(int& idx) const +{ + --idx; +} + +inline void <T>FPlex::next(int& idx) const +{ + ++idx; +} + +inline <T>& <T>FPlex:: operator [] (int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + return *(hd->pointer_to(idx)); +} + +inline <T>& <T>FPlex:: operator () (Pix p) +{ + return *((<T>*)p); +} + +inline <T>& <T>FPlex::low_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline <T>& <T>FPlex::high_element () +{ + if (empty()) index_error(); + return *(hd->pointer_to(fnc - 1)); +} + +inline const <T>& <T>FPlex:: operator [] (int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + return *(hd->pointer_to(idx)); +} + +inline const <T>& <T>FPlex:: operator () (Pix p) const +{ + return *((const <T>*)p); +} + +inline const <T>& <T>FPlex::low_element () const +{ + if (empty()) index_error(); + return *(hd->pointer_to(lo)); +} + +inline const <T>& <T>FPlex::high_element () const +{ + if (empty()) index_error(); + return *(hd->pointer_to(fnc - 1)); +} + +inline int <T>FPlex::can_add_high() const +{ + return hd->can_grow_high(); +} + +inline int <T>FPlex::can_add_low() const +{ + return hd->can_grow_low(); +} + +inline int <T>FPlex::add_high(const <T&> elem) +{ + if (!can_add_high()) full_error(); + *((hd-><T>IChunk::grow_high())) = elem; + return fnc++; +} + +inline int <T>FPlex::del_high () +{ + if (empty()) empty_error(); + hd-><T>IChunk::shrink_high(); + return --fnc - 1; +} + +inline int <T>FPlex::add_low (const <T&> elem) +{ + if (!can_add_low()) full_error(); + *((hd-><T>IChunk::grow_low())) = elem; + return --lo; +} + +inline int <T>FPlex::del_low () +{ + if (empty()) empty_error(); + hd-><T>IChunk::shrink_low(); + return ++lo; +} + +inline int <T>FPlex::owns (Pix p) const +{ + return hd->actual_pointer((<T>*)p); +} + +inline int <T>FPlex::Pix_to_index(Pix p) const +{ + if (!hd->actual_pointer((const <T>*)p)) index_error(); + return hd->index_of((const <T>*)p); +} + +inline Pix <T>FPlex::index_to_Pix(int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + return Pix(hd->pointer_to(idx)); +} + +inline <T>FPlex::~<T>FPlex() {} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/List.ccP b/gnu/lib/libg++/g++-include/gen/List.ccP new file mode 100644 index 000000000000..2afbdaf97215 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/List.ccP @@ -0,0 +1,956 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <builtin.h> +#include "<T>.List.h" + +<T>ListNode Nil<T>ListNode; + +class init_Nil<T>ListNode +{ +public: + init_Nil<T>ListNode() + { + Nil<T>ListNode.tl = &Nil<T>ListNode; + Nil<T>ListNode.ref = -1; + } +}; + +static init_Nil<T>ListNode Nil<T>ListNode_initializer; + +<T>List& <T>List::operator = (<T>List& a) +{ + reference(a.P); + dereference(P); + P = a.P; + return *this; +} + +<T> <T>List::pop() +{ + <T> res = P->hd; + <T>ListNode* tail = P->tl; + reference(tail); + dereference(P); + P = tail; + return res; +} + +void <T>List::set_tail(<T>List& a) +{ + reference(a.P); + dereference(P->tl); + P->tl = a.P; +} + +<T>List <T>List::nth(int n) +{ + for (<T>ListNode* p = P; n-- > 0; p = p->tl); + reference(p); + return <T>List(p); +} + +<T>List <T>List::last() +{ + <T>ListNode* p = P; + if (p != &Nil<T>ListNode) while (p->tl != &Nil<T>ListNode) p = p->tl; + reference(p); + return <T>List(p); +} + +void <T>List::append(<T>List& l) +{ + <T>ListNode* p = P; + <T>ListNode* a = l.P; + reference(a); + if (p != &Nil<T>ListNode) + { + while (p->tl != &Nil<T>ListNode) p = p->tl; + p->tl = a; + } + else + P = a; +} + +int <T>List::length() +{ + int l = 0; + for (<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl) ++l; + return l; +} + +<T>& <T>List::operator [] (int n) +{ + for (<T>ListNode* p = P; n-- > 0; p = p->tl); + return (p->hd); +} + +int operator == (<T>List& x, <T>List& y) +{ + <T>ListNode* a = x.P; + <T>ListNode* b = y.P; + + for (;;) + { + if (a == &Nil<T>ListNode) + return b == &Nil<T>ListNode; + else if (b == &Nil<T>ListNode) + return 0; + else if (<T>EQ(a->hd, b->hd)) + { + a = a->tl; + b = b->tl; + } + else + return 0; + } +} + + +void <T>List::apply(<T>Procedure f) +{ + for(<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl) + (*f)((p->hd)); +} + +void <T>List::subst(<T&> old, <T&> repl) +{ + for(<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl) + if (<T>EQ(p->hd, old)) + p->hd = repl; +} + +<T> <T>List::reduce(<T>Combiner f, <T&> base) +{ + <T> r = base; + for(<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl) + r = (*f)(r, (p->hd)); + return r; +} + +int <T>List::position(<T&> targ) +{ + int l = 0; + <T>ListNode* p = P; + for (;;) + { + if (p == &Nil<T>ListNode) + return -1; + else if (<T>EQ(p->hd, targ)) + return l; + else + { + ++l; + p = p->tl; + } + } +} + +int <T>List::contains(<T&> targ) +{ + <T>ListNode* p = P; + for (;;) + { + if (p == &Nil<T>ListNode) + return 0; + else if (<T>EQ(p->hd, targ)) + return 1; + else + p = p->tl; + } +} + +<T>List <T>List::find(<T&> targ) +{ + <T>ListNode* p = P; + while (p != &Nil<T>ListNode && !<T>EQ(p->hd, targ)) + p=p->tl; + reference(p); + return <T>List(p); +} + +Pix <T>List::seek(<T&> targ) +{ + <T>ListNode* p = P; + for (;;) + { + if (p == &Nil<T>ListNode) + return 0; + else if (<T>EQ(p->hd, targ)) + return Pix(p); + else + p = p->tl; + } +} + +int <T>List::owns(Pix i) +{ + <T>ListNode* p = P; + for (;;) + { + if (p == &Nil<T>ListNode) + return 0; + else if (Pix(p) == i) + return 1; + else + p = p->tl; + } +} + +<T>List <T>List::find(<T>List& target) +{ + <T>ListNode* targ = target.P; + if (targ == &Nil<T>ListNode) + return <T>List(targ); + + <T>ListNode* p = P; + while (p != &Nil<T>ListNode) + { + if (<T>EQ(p->hd, targ->hd)) + { + <T>ListNode* a = p->tl; + <T>ListNode* t = targ->tl; + for(;;) + { + if (t == &Nil<T>ListNode) + { + reference(p); + return <T>List(p); + } + else if (a == &Nil<T>ListNode || !<T>EQ(a->hd, t->hd)) + break; + else + { + a = a->tl; + t = t->tl; + } + } + } + p = p->tl; + } + return <T>List(&Nil<T>ListNode); +} + +int <T>List::contains(<T>List& target) +{ + <T>ListNode* targ = target.P; + if (targ == &Nil<T>ListNode) + return 0; + + <T>ListNode* p = P; + while (p != &Nil<T>ListNode) + { + if (<T>EQ(p->hd, targ->hd)) + { + <T>ListNode* a = p->tl; + <T>ListNode* t = targ->tl; + for(;;) + { + if (t == &Nil<T>ListNode) + return 1; + else if (a == &Nil<T>ListNode || !<T>EQ(a->hd, t->hd)) + break; + else + { + a = a->tl; + t = t->tl; + } + } + } + p = p->tl; + } + return 0; +} + +void <T>List::del(<T&> targ) +{ + <T>ListNode* h = P; + + for (;;) + { + if (h == &Nil<T>ListNode) + { + P = h; + return; + } + else if (<T>EQ(h->hd, targ)) + { + <T>ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + + <T>ListNode* trail = h; + <T>ListNode* p = h->tl; + while (p != &Nil<T>ListNode) + { + if (<T>EQ(p->hd, targ)) + { + <T>ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void <T>List::del(<T>Predicate f) +{ + <T>ListNode* h = P; + for (;;) + { + if (h == &Nil<T>ListNode) + { + P = h; + return; + } + else if ((*f)(h->hd)) + { + <T>ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + + <T>ListNode* trail = h; + <T>ListNode* p = h->tl; + while (p != &Nil<T>ListNode) + { + if ((*f)(p->hd)) + { + <T>ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void <T>List::select(<T>Predicate f) +{ + <T>ListNode* h = P; + for (;;) + { + if (h == &Nil<T>ListNode) + { + P = h; + return; + } + else if (!(*f)(h->hd)) + { + <T>ListNode* nxt = h->tl; + reference(nxt); + dereference(h); + h = nxt; + } + else + break; + } + <T>ListNode* trail = h; + <T>ListNode* p = h->tl; + while (p != &Nil<T>ListNode) + { + if (!(*f)(p->hd)) + { + <T>ListNode* nxt = p->tl; + reference(nxt); + dereference(p); + trail->tl = nxt; + p = nxt; + } + else + { + trail = p; + p = p->tl; + } + } + P = h; +} + +void <T>List::reverse() +{ + <T>ListNode* l = &Nil<T>ListNode; + <T>ListNode* p = P; + while (p != &Nil<T>ListNode) + { + <T>ListNode* nxt = p->tl; + p->tl = l; + l = p; + p = nxt; + } + P = l; +} + + +<T>List copy(<T>List& x) +{ + <T>ListNode* a = x.P; + if (a == &Nil<T>ListNode) + return <T>List(a); + else + { + <T>ListNode* h = new<T>ListNode(a->hd); + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + <T>ListNode* n = new<T>ListNode(a->hd); + trail->tl = n; + trail = n; + } + trail->tl = &Nil<T>ListNode; + return <T>List(h); + } +} + + +<T>List subst(<T&> old, <T&> repl, <T>List& x) +{ + <T>ListNode* a = x.P; + if (a == &Nil<T>ListNode) + return <T>List(a); + else + { + <T>ListNode* h = new <T>ListNode; + h->ref = 1; + if (<T>EQ(a->hd, old)) + h->hd = repl; + else + h->hd = a->hd; + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + <T>ListNode* n = new <T>ListNode; + n->ref = 1; + if (<T>EQ(a->hd, old)) + n->hd = repl; + else + n->hd = a->hd; + trail->tl = n; + trail = n; + } + trail->tl = &Nil<T>ListNode; + return <T>List(h); + } +} + +<T>List combine(<T>Combiner f, <T>List& x, <T>List& y) +{ + <T>ListNode* a = x.P; + <T>ListNode* b = y.P; + if (a == &Nil<T>ListNode || b == &Nil<T>ListNode) + return <T>List(&Nil<T>ListNode); + else + { + <T>ListNode* h = new<T>ListNode((*f)(a->hd, b->hd)); + <T>ListNode* trail = h; + a = a->tl; + b = b->tl; + while (a != &Nil<T>ListNode && b != &Nil<T>ListNode) + { + <T>ListNode* n = new<T>ListNode((*f)(a->hd, b->hd)); + trail->tl = n; + trail = n; + a = a->tl; + b = b->tl; + } + trail->tl = &Nil<T>ListNode; + return <T>List(h); + } +} + +<T>List reverse(<T>List& x) +{ + <T>ListNode* a = x.P; + if (a == &Nil<T>ListNode) + return <T>List(a); + else + { + <T>ListNode* l = new<T>ListNode(a->hd); + l->tl = &Nil<T>ListNode; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + <T>ListNode* n = new<T>ListNode(a->hd); + n->tl = l; + l = n; + } + return <T>List(l); + } +} + +<T>List append(<T>List& x, <T>List& y) +{ + <T>ListNode* a = x.P; + <T>ListNode* b = y.P; + reference(b); + if (a != &Nil<T>ListNode) + { + <T>ListNode* h = new<T>ListNode(a->hd); + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + <T>ListNode* n = new<T>ListNode(a->hd); + trail->tl = n; + trail = n; + } + trail->tl = b; + return <T>List(h); + } + else + return <T>List(b); +} + +void <T>List::prepend(<T>List& y) +{ + <T>ListNode* b = y.P; + if (b != &Nil<T>ListNode) + { + <T>ListNode* h = new<T>ListNode(b->hd); + <T>ListNode* trail = h; + for(b = b->tl; b != &Nil<T>ListNode; b = b->tl) + { + <T>ListNode* n = new<T>ListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = P; + P = h; + } +} + +<T>List concat(<T>List& x, <T>List& y) +{ + <T>ListNode* a = x.P; + <T>ListNode* b = y.P; + if (a != &Nil<T>ListNode) + { + <T>ListNode* h = new<T>ListNode(a->hd); + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + <T>ListNode* n = new<T>ListNode(a->hd); + trail->tl = n; + trail = n; + }; + for(;b != &Nil<T>ListNode; b = b->tl) + { + <T>ListNode* n = new<T>ListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = &Nil<T>ListNode; + return <T>List(h); + } + else if (b != &Nil<T>ListNode) + { + <T>ListNode* h = new<T>ListNode(b->hd); + <T>ListNode* trail = h; + for(b = b->tl; b != &Nil<T>ListNode; b = b->tl) + { + <T>ListNode* n = new<T>ListNode(b->hd); + trail->tl = n; + trail = n; + } + trail->tl = &Nil<T>ListNode; + return <T>List(h); + } + else + return <T>List(&Nil<T>ListNode); +} + +<T>List select(<T>Predicate f, <T>List& x) +{ + <T>ListNode* a = x.P; + <T>ListNode* h = &Nil<T>ListNode; + while (a != &Nil<T>ListNode) + { + if ((*f)(a->hd)) + { + h = new<T>ListNode(a->hd); + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + if ((*f)(a->hd)) + { + <T>ListNode* n = new<T>ListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &Nil<T>ListNode; + break; + } + else + a = a->tl; + } + return <T>List(h); +} + +<T>List remove(<T>Predicate f, <T>List& x) +{ + <T>ListNode* a = x.P; + <T>ListNode* h = &Nil<T>ListNode; + while (a != &Nil<T>ListNode) + { + if (!(*f)(a->hd)) + { + h = new<T>ListNode(a->hd); + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + if (!(*f)(a->hd)) + { + <T>ListNode* n = new<T>ListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &Nil<T>ListNode; + break; + } + else + a = a->tl; + } + return <T>List(h); +} + +<T>List remove(<T&> targ, <T>List& x) +{ + <T>ListNode* a = x.P; + <T>ListNode* h = &Nil<T>ListNode; + while (a != &Nil<T>ListNode) + { + if (!(<T>EQ(a->hd, targ))) + { + h = new<T>ListNode(a->hd); + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + if (!<T>EQ(a->hd, targ)) + { + <T>ListNode* n = new<T>ListNode(a->hd); + trail->tl = n; + trail = n; + } + } + trail->tl = &Nil<T>ListNode; + break; + } + else + a = a->tl; + } + return <T>List(h); +} + +<T>List map(<T>Mapper f, <T>List& x) +{ + <T>ListNode* a = x.P; + <T>ListNode* h = &Nil<T>ListNode; + if (a != &Nil<T>ListNode) + { + h = new<T>ListNode((*f)(a->hd)); + <T>ListNode* trail = h; + for(a = a->tl; a != &Nil<T>ListNode; a = a->tl) + { + <T>ListNode* n = new<T>ListNode((*f)(a->hd)); + trail->tl = n; + trail = n; + } + trail->tl = &Nil<T>ListNode; + } + return <T>List(h); +} + + +<T>List merge(<T>List& x, <T>List& y, <T>Comparator f) +{ + <T>ListNode* a = x.P; + <T>ListNode* b = y.P; + + if (a == &Nil<T>ListNode) + { + if (b == &Nil<T>ListNode) + return <T>List(&Nil<T>ListNode); + else + return copy(y); + } + else if (b == &Nil<T>ListNode) + return copy(x); + + <T>ListNode* h = new <T>ListNode; + h->ref = 1; + if ((*f)(a->hd, b->hd) <= 0) + { + h->hd = a->hd; + a = a->tl; + } + else + { + h->hd = b->hd; + b = b->tl; + } + + <T>ListNode* r = h; + + for(;;) + { + if (a == &Nil<T>ListNode) + { + while (b != &Nil<T>ListNode) + { + <T>ListNode* n = new <T>ListNode; + n->ref = 1; + n->hd = b->hd; + r->tl = n; + r = n; + b = b->tl; + } + r->tl = &Nil<T>ListNode; + return <T>List(h); + } + else if (b == &Nil<T>ListNode) + { + while (a != &Nil<T>ListNode) + { + <T>ListNode* n = new <T>ListNode; + n->ref = 1; + n->hd = a->hd; + r->tl = n; + r = n; + a = a->tl; + } + r->tl = &Nil<T>ListNode; + return <T>List(h); + } + else if ((*f)(a->hd, b->hd) <= 0) + { + <T>ListNode* n = new <T>ListNode; + n->ref = 1; + n->hd = a->hd; + r->tl = n; + r = n; + a = a->tl; + } + else + { + <T>ListNode* n = new <T>ListNode; + n->ref = 1; + n->hd = b->hd; + r->tl = n; + r = n; + b = b->tl; + } + } +} + +void <T>List::sort(<T>Comparator f) +{ + // strategy: place runs in queue, merge runs until done + // This is often very fast + + if (P == &Nil<T>ListNode || P->tl == &Nil<T>ListNode) + return; + + int qlen = 250; // guess a good queue size, realloc if necessary + + <T>ListNode** queue = (<T>ListNode**)malloc(qlen * sizeof(<T>ListNode*)); + + <T>ListNode* h = P; + <T>ListNode* a = h; + <T>ListNode* b = a->tl; + int qin = 0; + + while (b != &Nil<T>ListNode) + { + if ((*f)(a->hd, b->hd) > 0) + { + if (h == a) // minor optimization: ensure runlen >= 2 + { + h = b; + a->tl = b->tl; + b->tl = a; + b = a->tl; + } + else + { + if (qin >= qlen) + { + qlen *= 2; + queue = (<T>ListNode**)realloc(queue, qlen * sizeof(<T>ListNode*)); + } + queue[qin++] = h; + a->tl = &Nil<T>ListNode; + h = a = b; + b = b->tl; + } + } + else + { + a = b; + b = b->tl; + } + } + + int count = qin; + queue[qin] = h; + if (++qin >= qlen) qin = 0; + int qout = 0; + + while (count-- > 0) + { + a = queue[qout]; + if (++qout >= qlen) qout = 0; + b = queue[qout]; + if (++qout >= qlen) qout = 0; + + if ((*f)(a->hd, b->hd) <= 0) + { + h = a; + a = a->tl; + } + else + { + h = b; + b = b->tl; + } + queue[qin] = h; + if (++qin >= qlen) qin = 0; + + for (;;) + { + if (a == &Nil<T>ListNode) + { + h->tl = b; + break; + } + else if (b == &Nil<T>ListNode) + { + h->tl = a; + break; + } + else if ((*f)(a->hd, b->hd) <= 0) + { + h->tl = a; + h = a; + a = a->tl; + } + else + { + h->tl = b; + h = b; + b = b->tl; + } + } + } + P = queue[qout]; + free(queue); +} + +int <T>List::list_length() +{ + <T>ListNode* fast = P; + if (fast == &Nil<T>ListNode) + return 0; + + <T>ListNode* slow = fast->tl; + if (slow == &Nil<T>ListNode) + return 1; + + fast = slow->tl; + int n = 2; + + for (;;) + { + if (fast == &Nil<T>ListNode) + return n; + else if (fast->tl == &Nil<T>ListNode) + return n+1; + else if (fast == slow) + return -1; + else + { + n += 2; + fast = fast->tl->tl; + slow = slow->tl; + } + } +} + +void <T>List::error(const char* msg) +{ + (*lib_error_handler)("List", msg); +} + +int <T>List::OK() +{ + int v = P != 0; // have a node + // check that all nodes OK, even if circular: + + <T>ListNode* fast = P; + if (fast != &Nil<T>ListNode) + { + v &= fast->ref != 0; + <T>ListNode* slow = fast->tl; + v &= slow->ref != 0; + if (v && slow != &Nil<T>ListNode) + { + fast = slow->tl; + v &= fast->ref != 0; + while (v) + { + if (fast == &Nil<T>ListNode) + break; + else if (fast->tl == &Nil<T>ListNode) + break; + else if (fast == slow) + break; + else + { + v &= fast->ref != 0 && slow->ref != 0; + fast = fast->tl->tl; + slow = slow->tl; + } + } + } + } + if (!v) error ("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/List.hP b/gnu/lib/libg++/g++-include/gen/List.hP new file mode 100644 index 000000000000..7ccdbc3bc41f --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/List.hP @@ -0,0 +1,273 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>List_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>List_h 1 + +#ifndef _<T>_typedefs +#define _<T>_typedefs 1 +typedef void (*<T>Procedure)(<T&>); +typedef <T> (*<T>Mapper)(<T&>); +typedef <T> (*<T>Combiner)(<T&>, <T&>); +typedef int (*<T>Predicate)(<T&>); +typedef int (*<T>Comparator)(<T&>, <T&>); +#endif + +#include <Pix.h> +#include "<T>.defs.h" + +struct <T>ListNode +{ + <T>ListNode* tl; + short ref; + <T> hd; +}; + +extern <T>ListNode Nil<T>ListNode; + +class <T>List +{ +protected: + <T>ListNode* P; + + <T>List(<T>ListNode* p); +public: + <T>List(); + <T>List(<T&> head); + <T>List(<T&> head, <T>List& tl); + <T>List(<T>List& a); + <T>List(Pix p); + ~<T>List(); + + <T>List& operator = (<T>List& a); + + int null(); + int valid(); + operator const void* (); + int operator ! (); + + int length(); + int list_length(); + + <T>& get(); + <T>& head(); + <T>& operator [] (int n); + + <T>List nth(int n); + <T>List tail(); + <T>List last(); + + <T>List find(<T&> targ); + <T>List find(<T>List& targ); + int contains(<T&> targ); + int contains(<T>List& targ); + int position(<T&> targ); + + friend <T>List copy(<T>List& a); + friend <T>List concat(<T>List& a, <T>List& b); + friend <T>List append(<T>List& a, <T>List& b); + friend <T>List map(<T>Mapper f, <T>List& a); + friend <T>List merge(<T>List& a, <T>List& b, <T>Comparator f); + friend <T>List combine(<T>Combiner f, <T>List& a, <T>List& b); + friend <T>List reverse(<T>List& a); + friend <T>List select(<T>Predicate f, <T>List& a); +#undef remove + friend <T>List remove(<T&> targ, <T>List& a); + friend <T>List remove(<T>Predicate f, <T>List& a); + friend <T>List subst(<T&> old, <T&> repl, <T>List& a); + + void push(<T&> x); + <T> pop(); + + void set_tail(<T>List& p); + void append(<T>List& p); + void prepend(<T>List& p); + void del(<T&> targ); + void del(<T>Predicate f); + void select(<T>Predicate f); + void subst(<T&> old, <T&> repl); + void reverse(); + void sort(<T>Comparator f); + + void apply(<T>Procedure f); + <T> reduce(<T>Combiner f, <T&> base); + + friend int operator == (<T>List& a, <T>List& b); + friend int operator != (<T>List& a, <T>List& b); + + Pix first(); + void next(Pix& p); + Pix seek(<T&> item); + <T>& operator () (Pix p); + int owns(Pix p); + + void error(const char*); + int OK(); +}; + + +inline void reference(<T>ListNode* p) +{ + if (p->ref >= 0) ++p->ref; +} + +inline void dereference(<T>ListNode* p) +{ + while (p->ref > 0 && --p->ref == 0) + { + <T>ListNode* n = p->tl; + delete(p); + p = n; + } +} + + +inline <T>ListNode* new<T>ListNode(<T&> h) +{ + <T>ListNode* p = new <T>ListNode; + p->ref = 1; + p->hd = h; + return p; +} + +inline <T>ListNode* new<T>ListNode(<T&> h, <T>ListNode* t) +{ + <T>ListNode* p = new <T>ListNode; + p->ref = 1; + p->hd = h; + p->tl = t; + return p; +} + + +inline <T>List::~<T>List() +{ + dereference(P); +} + +inline <T>List::<T>List() +{ + P = &Nil<T>ListNode; +} + +inline <T>List::<T>List(<T>ListNode* p) +{ + P = p; +} + +inline <T>List::<T>List(<T&> head) +{ + P = new<T>ListNode(head); + P->tl = &Nil<T>ListNode; +} + +inline <T>List::<T>List(<T&> head, <T>List& tl) +{ + P = new<T>ListNode(head, tl.P); + reference(P->tl); +} + +inline <T>List::<T>List(<T>List& a) +{ + reference(a.P); + P = a.P; +} + + +inline <T>& <T>List::get() +{ + return P->hd; +} + +inline <T>& <T>List::head() +{ + return P->hd; +} + + +inline <T>List <T>List::tail() +{ + reference(P->tl); + return <T>List(P->tl); +} + + + +inline int <T>List::null() +{ + return P == &Nil<T>ListNode; +} + +inline int <T>List::valid() +{ + return P != &Nil<T>ListNode; +} + +inline <T>List::operator const void* () +{ + return (P == &Nil<T>ListNode)? 0 : this; +} + +inline int <T>List::operator ! () +{ + return (P == &Nil<T>ListNode); +} + + +inline void <T>List::push(<T&> head) +{ + <T>ListNode* oldp = P; + P = new<T>ListNode(head, oldp); +} + + +inline int operator != (<T>List& x, <T>List& y) +{ + return !(x == y); +} + +inline Pix <T>List::first() +{ + return (P == &Nil<T>ListNode)? 0 : Pix(P); +} + +inline <T>& <T>List::operator () (Pix p) +{ + return ((<T>ListNode*)p)->hd; +} + +inline void <T>List::next(Pix& p) +{ + if (p != 0) + { + p = Pix(((<T>ListNode*)p)->tl); + if (p == &Nil<T>ListNode) p = 0; + } +} + +inline <T>List::<T>List(Pix p) +{ + P = (<T>ListNode*)p; + reference(P); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/MPlex.ccP b/gnu/lib/libg++/g++-include/gen/MPlex.ccP new file mode 100644 index 000000000000..89a1bcf9e600 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/MPlex.ccP @@ -0,0 +1,845 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.MPlex.h" + +// <T>MChunk support + + +<T>MChunk::<T>MChunk(<T>* d, + int baseidx, + int lowidx, + int fenceidx, + int topidx) + : <T>IChunk(d, baseidx, lowidx, fenceidx, topidx) +{ + unused = fence - low; + unsigned msize = (top - base)/_MAP_BITS + 1; + map = (unsigned long *) (new long[msize]); + memset((void*)map, 0, msize * sizeof(long)); +} + +void <T>MChunk:: shrink_high () +{ + if (fence <= low) empty_error(); + --fence; + if (!valid(fence)) + --unused; + else + free(fence); + reset_high(); +} + +void <T>MChunk:: shrink_low () +{ + if (fence <= low) empty_error(); + if (!valid(low)) + --unused; + else + free(low); + ++low; + reset_low(); +} + +void <T>MChunk::clear(int lo) +{ + int s = top - base; + low = base = fence = lo; + top = base + s; + unused = 0; + memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long)); +} + +void <T>MChunk::cleardown(int hi) +{ + int s = top - base; + low = top = fence = hi; + base = top - s; + unused = 0; + memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long)); +} + +int <T>MChunk::del(int idx) +{ + if (idx < low || idx >= fence) index_error(); + int v = valid(idx); + if (v) + { + free(idx); + ++unused; + } + return v; +} + + +int <T>MChunk::undel(int idx) +{ + if (idx < low || idx >= fence) index_error(); + int v = valid(idx); + if (!v) + { + mark(idx); + --unused; + } + return v; +} + +int <T>MChunk::unused_index() const +{ + if (unused_indices() == 0) index_error(); + int slot; + if (low == base) // can traverse 32 slots at a time + { + int blk = 0; + while (map[blk] == ~0L) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(valid(slot)) ++slot; + return slot; +} + +int <T>MChunk::first_index() const +{ + if (empty()) return fence; + int slot; + if (low == base) + { + int blk = 0; + while (map[blk] == 0) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(!valid(slot)) ++slot; + return slot; +} + +int <T>MChunk::last_index() const +{ + if (empty()) return low - 1; + int slot; + if (top == fence) + { + int blk = (top - base) / _MAP_BITS; + while (map[blk] == 0) --blk; + slot = blk * _MAP_BITS + base + _MAP_BITS - 1; + } + else + slot = fence - 1; + + while(!valid(slot)) --slot; + return slot; +} + + +int <T>MChunk:: OK() const +{ + int v = data != 0; // have some data + v &= map != 0; // and a map + v &= base <= low; // ok, index-wise + v &= low <= fence; + v &= fence <= top; + + v &= ((<T>MChunk*)(nxt->prev())) == this; // and links are OK + v &= ((<T>MChunk*)(prv->next())) == this; + + int bitcount = 0; // and unused count correct + for (int i = low; i < fence; ++i) if (!valid(i)) ++bitcount; + v &= unused == bitcount; + + if (!v) error("invariant failure"); + return(v); +} + +<T>* <T>MChunk::succ(<T>* p) const +{ + int i = ((int) p - (int) data) / sizeof(<T>) + base + 1; + if (p == 0 || i < low) return 0; + while (i < fence && !valid(i)) ++i; + if (i >= fence) return 0; + return pointer_to(i); +} + +<T>* <T>MChunk::pred(<T>* p) const +{ + int i = ((int) p - (int) data) / sizeof(<T>) + base - 1; + if (p == 0 || i >= fence) return 0; + while (i >= low && !valid(i)) --i; + if (i < low) return 0; + return pointer_to(i); +} + +<T>* <T>MChunk::first_pointer() const +{ + if (empty()) return 0; + int slot; + if (low == base) + { + int blk = 0; + while (map[blk] == 0) ++blk; + slot = blk * _MAP_BITS + base; + } + else + slot = low; + + while(!valid(slot)) ++slot; + return pointer_to(slot); +} + +<T>* <T>MChunk::last_pointer() const +{ + if (empty()) return 0; + int slot; + if (top == fence) + { + int blk = (top - base) / _MAP_BITS; + while (map[blk] == 0) --blk; + slot = blk * _MAP_BITS + base + _MAP_BITS - 1; + } + else + slot = fence - 1; + + while(!valid(slot)) --slot; + return pointer_to(slot); +} + +<T>MPlex:: <T>MPlex() +{ + unused = 0; + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + <T>* data = new <T>[csize]; + hd = ch = new <T>MChunk(data, lo, lo, fnc, lo+csize); +} + +<T>MPlex:: <T>MPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + unused = 0; + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + <T>* data = new <T>[csize]; + hd = ch = new <T>MChunk(data, lo, lo, fnc, csize); + } + else + { + csize = -chunksize; + <T>* data = new <T>[csize]; + hd = ch = new <T>MChunk(data, chunksize, lo, fnc, fnc); + } +} + + +<T>MPlex:: <T>MPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + unused = 0; + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + <T>* data = new <T>[csize]; + hd = ch = new <T>MChunk(data, lo, lo, fnc, csize+lo); + } + else + { + csize = -chunksize; + <T>* data = new <T>[csize]; + hd = ch = new <T>MChunk(data, chunksize+lo, lo, fnc, fnc); + } +} + + +void <T>MPlex::make_initial_chunks(int up) +{ + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + <T>* data = new <T> [csize]; + <T>MChunk* h = new <T>MChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + <T>* data = new <T> [csize]; + <T>MChunk* h = new <T>MChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + ch = (<T>MChunk*) hd; +} + +<T>MPlex:: <T>MPlex(int l, int hi, const <T&> initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + unused = fnc - lo; + for (int i=lo; i<fnc; ++i) + undel_index(i); + fill(initval); +} + +<T>MPlex::<T>MPlex(const <T>MPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + unused = fnc - lo; + hd = 0; + const <T>IChunk* p = a.hd; + do + { + <T>* data = new <T> [p->size()]; + <T>MChunk* h = new <T>MChunk(data, p->base_index(), + p->low_index(), p->fence_index(), p->top_index()); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + p = p->next(); + } while (p != a.hd); + ch = (<T>MChunk*) hd; + for (int i = a.low(); i < a.fence(); a.next(i)) + { + undel_index(i); + (*this)[i] = a[i]; + } +} + +void <T>MPlex::operator= (const <T>MPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + unused = fnc - lo; + hd = 0; + const <T>IChunk* p = a.hd; + do + { + <T>* data = new <T> [p->size()]; + <T>MChunk* h = new <T>MChunk(data, p->base_index(), + p->low_index(), p->fence_index(), + p->top_index()); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + p = p->next(); + } while (p != a.hd); + ch = (<T>MChunk*) hd; + for (int i = a.low(); i < a.fence(); a.next(i)) + { + undel_index(i); + (*this)[i] = a[i]; + } + } +} + +int <T>MPlex::valid(int idx) const +{ + const <T>MChunk* tail = (<T>MChunk*)tl(); + const <T>MChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) return 0; + t = ((<T>MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + if (t == (<T>MChunk*)(hd)) return 0; + t = ((<T>MChunk*)(t->prev())); + } + set_cache(t); + return t-><T>MChunk::valid_index(idx); +} + +void <T>MPlex::cache(int idx) const +{ + const <T>MChunk* tail = (<T>MChunk*)tl(); + const <T>MChunk* t = ch; + while (idx >= t->fence_index()) + { + if (t == tail) index_error(); + t = ((<T>MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + if (t == (<T>MChunk*)hd) index_error(); + t = ((<T>MChunk*)(t->prev())); + } + if (!t-><T>MChunk::valid_index(idx)) index_error(); + set_cache(t); +} + +void <T>MPlex::cache(const <T>* p) const +{ + const <T>MChunk* old = ch; + const <T>MChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = ((<T>MChunk*)(t->next())); + if (t == old) index_error(); + } + if (!t-><T>MChunk::valid_pointer(p)) index_error(); + set_cache(t); +} + +int <T>MPlex::owns(Pix px) const +{ + <T>* p = (<T>*)px; + const <T>MChunk* old = ch; + const <T>MChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = ((<T>MChunk*)(t->next())); + if (t == old) return 0; + } + set_cache(t); + return t-><T>MChunk::valid_pointer(p); +} + +int <T>MPlex::add_high(const <T&> elem) +{ + <T>MChunk* t = ((<T>MChunk*) tl()); + + if (!t->can_grow_high()) + { + <T>* data = new <T> [csize]; + t = (new <T>MChunk(data, fnc,fnc,fnc,fnc+csize)); + t->link_to_prev(tl()); + } + + *((t-><T>MChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int <T>MPlex::add_low (const <T&> elem) +{ + <T>MChunk* t = ((<T>MChunk*) hd); + if (!t->can_grow_low()) + { + <T>* data = new <T> [csize]; + hd = new <T>MChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = ((<T>MChunk*) hd); + } + + *((t-><T>MChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + +void <T>MPlex::adjust_bounds() +{ + <T>MChunk* t = ((<T>MChunk*) tl()); + + // clean up tail + + t->reset_high(); + while (t-><T>MChunk::empty() && !one_chunk()) + { + <T>MChunk* pred = (<T>MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + if (one_chunk()) + t->reset_high(); + + int oldfnc = fnc; + fnc = t->fence_index(); + unused -= oldfnc - fnc; + + // and head.. + t = ((<T>MChunk*) hd); + t->reset_low(); + while (t-><T>MChunk::empty() && !one_chunk()) + { + hd = (<T>MChunk*)(t->next()); + del_chunk(t); + t = ((<T>MChunk*) hd); + t->reset_low(); + } + + int oldlo = lo; + lo = t->low_index(); + unused -= lo - oldlo; + + + set_cache(t); +} + +int <T>MPlex::del_high () +{ + if (empty()) empty_error(); + <T>MChunk* t = ((<T>MChunk*) tl()); + while (t-><T>MChunk::empty() && !one_chunk()) // possible stragglers + { + <T>MChunk* pred = (<T>MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + t-><T>MChunk::shrink_high(); + while (t-><T>MChunk::empty() && !one_chunk()) + { + <T>MChunk* pred = (<T>MChunk*)(t->prev()); + del_chunk(t); + pred->reset_high(); + t = (pred); + } + int oldfnc = fnc; + fnc = t->fence_index(); + unused -= oldfnc - fnc - 1; + set_cache(t); + return fnc - 1; +} + +int <T>MPlex::del_low () +{ + if (empty()) empty_error(); + <T>MChunk* t = ((<T>MChunk*) hd); + while (t-><T>MChunk::empty() && !one_chunk()) + { + hd = (<T>MChunk*)(t->next()); + del_chunk(t); + t = ((<T>MChunk*) hd); + t->reset_low(); + } + t-><T>MChunk::shrink_low(); + while (t-><T>MChunk::empty() && !one_chunk()) + { + hd = (<T>MChunk*)(t->next()); + del_chunk(t); + t = ((<T>MChunk*) hd); + t->reset_low(); + } + int oldlo = lo; + lo = t->low_index(); + unused -= lo - oldlo - 1; + set_cache(t); + return lo; +} + +int <T>MPlex::add(const <T&> elem) +{ + if (unused == 0) + return add_high(elem); + + for(<T>MChunk* t = ch; + t->unused_indices() == 0; + t = (<T>MChunk*)(t->prev())) + ; + + int i = t->unused_index(); + set_cache(t); + undel_index(i); + (*this)[i] = elem; + return i; +} + +int <T>MPlex::unused_index() const +{ + if (unused == 0) index_error(); + + for(<T>MChunk* t = ch; + t->unused_indices() == 0; + t = (<T>MChunk*)(t->prev())) + ; + + set_cache(t); + return t->unused_index(); +} + +Pix <T>MPlex::unused_Pix() const +{ + if (unused == 0) return 0; + + for(<T>MChunk* t = ch; + t->unused_indices() == 0; + t = (<T>MChunk*)(t->prev())) + ; + + set_cache(t); + return t->pointer_to(t->unused_index()); +} + +int <T>MPlex::del_index(int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + if (<T>MPlex::valid(idx)) + { + ++unused; + ch-><T>MChunk::del(idx); + return 1; + } + else + return 0; +} + +int <T>MPlex::dopred(int idx) const +{ + + if (idx >= fnc) idx = fnc; + if (idx <= lo) return lo - 1; + + const <T>MChunk* t = ch; + + while (idx > t->fence_index()) + { + t = ((<T>MChunk*)(t->next())); + } + while (idx <= t->low_index()) + { + t = ((<T>MChunk*)(t->prev())); + } + int i = t-><T>MChunk::pred(idx); + while (i < t->low_index() && i >= lo) + { + t = ((<T>MChunk*)(t->prev())); + i = t-><T>MChunk::last_index(); + } + set_cache(t); + return i; +} + + +int <T>MPlex::dosucc(int idx) const +{ + if (idx < lo) idx = lo; + if (idx >= fnc - 1) return fnc; + + const <T>MChunk* t = ch; + while (idx >= t->fence_index()) + { + t = ((<T>MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + t = ((<T>MChunk*)(t->prev())); + } + int i = t-><T>MChunk::succ(idx); + while (i >= t->fence_index() && i < fnc) + { + t = (<T>MChunk*)(t->next()); + i = t-><T>MChunk::first_index(); + } + set_cache(t); + return i; +} + +void <T>MPlex::prev(Pix& i) const +{ + if (i == 0) return; + + <T>* p = (<T>*) i; + const <T>MChunk* old = ch; + const <T>MChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = ((<T>MChunk*)(t->prev())); + if (t == old) + { + i = 0; + return; + } + } + <T>* q = t-><T>MChunk::pred(p); + while (q == 0 && t != (<T>MChunk*)hd) + { + t = ((<T>MChunk*)(t->prev())); + q = t-><T>MChunk::last_pointer(); + } + + i = Pix(q); + set_cache(t); + return; +} + +void <T>MPlex::next(Pix& i) const +{ + if (i == 0) return; + + <T>* p = (<T>*) i; + const <T>MChunk* tail = (<T>MChunk*)(tl()); + const <T>MChunk* old = ch; + const <T>MChunk* t = ch; + + while (!t->actual_pointer(p)) + { + t = ((<T>MChunk*)(t->next())); + if (t == old) + { + i = 0; + return; + } + } + <T>* q = t-><T>MChunk::succ(p); + while (q == 0 && t != tail) + { + t = ((<T>MChunk*)(t->next())); + q = t-><T>MChunk::first_pointer(); + } + + i = Pix(q); + set_cache(t); + return; +} + + +void <T>MPlex::undel_index(int idx) +{ + if (idx < lo || idx >= fnc) index_error(); + + <T>MChunk* t = ch; + while (idx >= t->fence_index()) + { + t = ((<T>MChunk*)(t->next())); + } + while (idx < t->low_index()) + { + t = ((<T>MChunk*)(t->prev())); + } + int was_present = t-><T>MChunk::undel(idx); + if (!was_present) + { + --unused; + } + set_cache(t); + return; +} + +void <T>MPlex::clear() +{ + if (fnc != lo) + { + <T>MChunk* t = ((<T>MChunk*)tl()); + while (t != hd) + { + <T>MChunk* prv = (<T>MChunk*)(t->prev()); + del_chunk(t); + t = prv; + } + t-><T>MChunk::clear(lo); + set_cache(t); + fnc = lo; + unused = 0; + } +} + +int <T>MPlex::OK () const +{ + int v = hd != 0; // at least one chunk + + int found_ch = 0; // to make sure ch is in list; + + int count = 0; // to count unused slots + + const <T>MChunk* t = (<T>MChunk*)(hd); + + int gap = t->low_index() - lo; + v &= gap == 0; // hd lo not less than lo. + count += gap; + + for (;;) + { + if (t == ch) ++found_ch; + v &= t-><T>MChunk::OK(); // each chunk is OK + count += t->unused_indices(); + if (t == (<T>MChunk*)(tl())) + break; + else // and has indices less than succ + { + gap = t->next()->base_index() - t->top_index(); + v &= gap == 0; + count += gap; + + if (t != (<T>MChunk*)hd) // internal chunks can't grow + v &= !t->can_grow_low() && !t->can_grow_high(); + + t = (const <T>MChunk*)(t->next()); + } + } + gap = fnc - t->fence_index(); + v &= gap == 0; + count += gap; + + v &= count == unused; // chunk counts agree with plex + + v &= found_ch == 1; + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/MPlex.hP b/gnu/lib/libg++/g++-include/gen/MPlex.hP new file mode 100644 index 000000000000..8bf78d13a135 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/MPlex.hP @@ -0,0 +1,414 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _<T>MPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>MPlex_h 1 + + +#include "<T>.Plex.h" + + +// Number of bits per long, used in MChunk bit map operations + +#define _MAP_BITS 32 + + +class <T>MChunk : public <T>IChunk +{ +protected: + + unsigned long* map; // bitmap of slots + int unused; // number of unused internal slots + + void mark(int); // bitmap operations + void free(int); + int valid(int) const; + +public: + + <T>MChunk(<T>* d, // ptr to array of elements + int base_idx, // initial indices + int low_idx, // & initially clear map + int fence_idx, + int top_idx); + + ~<T>MChunk(); + +// virtuals + + int first_index() const; + int last_index() const; + int succ(int idx) const; + int pred(int idx) const; + <T>* first_pointer() const; + <T>* last_pointer() const; + <T>* succ(<T>*) const; + <T>* pred(<T>*) const; + int empty() const; + int full() const; + int valid_index(int i) const; + int valid_pointer(const <T>* p) const; + <T>* grow_high (); + <T>* grow_low (); + void shrink_high (); + void shrink_low (); + void clear(int); + void cleardown(int); + int OK() const; + +// extensions + + int unused_indices() const; // how many free slot in low..fence? + + int unused_index() const; // return index of free slot + + int del(int i); // delete data indexed by i + // return true if was present + int undel(int idx); // un-delete data indexed by i + // return true if already present + + void reset_low(); // reset low = lowest valid index; + void reset_high(); // same for high + +}; + + +class <T>MPlex: public <T>Plex +{ + <T>MChunk* ch; // cached chunk + int unused; // # of free slots between low & fence + + void make_initial_chunks(int up = 1); + void cache(int idx) const; + void cache(const <T>* p) const; + int dopred(int) const; + int dosucc(int) const; + + void set_cache(const <T>MChunk* t) const; // logically, + // not physically const + +public: + <T>MPlex(); // set low = 0; + // fence = 0; + // csize = default + + <T>MPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + <T>MPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + <T>MPlex(int lo, // low = lo + int hi, // fence = hi+1 + const <T&> initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + <T>MPlex(const <T>MPlex&); + + void operator= (const <T>MPlex&); + +// virtuals + + <T>& high_element (); + <T>& low_element (); + const <T>& high_element () const; + const <T>& low_element () const; + + Pix first() const; + Pix last() const ; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + <T>& operator () (Pix p); + const <T>& operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + <T>& operator [] (int index); + const <T>& operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const <T&> elem); + int del_high (); + int add_low (const <T&> elem); + int del_low (); + void clear(); + + int OK () const; + +// extensions + + int count() const; // # valid elements + int available() const; // # deleted elements + + int unused_index()const; // return index of a deleted elem + Pix unused_Pix() const; // return Pix of a deleted elem + + int del_index(int idx); // logically delete at idx; + // return true if was present + int del_Pix(Pix p); // delete at p + + void undel_index(int idx); // undelete at idx; + void undel_Pix(Pix p); // undelete at p; + + void adjust_bounds(); // reset lo, hi to lowest & + // highest valid indices + + int add(const <T&> elem); // add anywhere +}; + + +inline <T>MChunk:: ~<T>MChunk() +{ + delete map; +} + +inline void <T>MChunk::mark(int idx) +{ + unsigned int i = idx - base; + map[i / _MAP_BITS] |= 1 << (i & (_MAP_BITS - 1)); +} + +inline void <T>MChunk::free(int idx) +{ + unsigned int i = idx - base; + map[i / _MAP_BITS] &= ~(1 << (i & (_MAP_BITS - 1))); +} + +inline int <T>MChunk::valid(int idx) const +{ + unsigned int i = idx - base; + return map[i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1))); +} + +inline int <T>MChunk:: valid_index(int i) const +{ + return i >= low && i < fence && valid(i); +} + +inline int <T>MChunk:: valid_pointer(const <T>* p) const +{ + int i = ((int)p - (int)data) / sizeof(<T>); + return i >= 0 && i < (fence - base) && + (map[(unsigned)i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1)))); +} + +inline int <T>MChunk::empty() const +{ + return fence - low - unused == 0; +} + +inline int <T>MChunk::full() const +{ + return unused + (top - fence) + (low - base) == 0; +} + +inline int <T>MChunk::succ(int idx) const +{ + int i = (idx < low)? low : idx + 1; + while (i < fence && !valid(i)) ++i; + return i; +} + +inline int <T>MChunk::pred(int idx) const +{ + int i = (idx > fence)? (fence - 1) : idx - 1; + while (i >= low && !valid(i)) --i; + return i; +} + +inline int <T>MChunk::unused_indices() const +{ + return unused; +} + +inline <T>* <T>MChunk:: grow_high () +{ + if (!can_grow_high()) full_error(); + mark(fence); + return &(data[fence++ - base]); +} + +inline <T>* <T>MChunk:: grow_low () +{ + if (!can_grow_low()) full_error(); + mark(--low); + return &(data[low - base]); +} + +inline void <T>MChunk::reset_low() +{ + while (low < fence && !valid(low)) + { + --unused; + ++low; + } +} + +inline void <T>MChunk::reset_high() +{ + while (fence > low && !valid(fence - 1)) + { + --unused; + --fence; + } +} + +inline int <T>MPlex::full () const +{ + return 0; +} + +inline int <T>MPlex::can_add_high() const +{ + return 1; +} + +inline int <T>MPlex::can_add_low() const +{ + return 1; +} + +inline int <T>MPlex::available() const +{ + return unused; +} + +inline int <T>MPlex::count() const +{ + return fnc - lo - unused; +} + +inline void <T>MPlex::set_cache(const <T>MChunk* t) const +{ + ((<T>MPlex*)(this))->ch = (<T>MChunk*)t; +} + +inline <T>& <T>MPlex:: operator [] (int idx) +{ + if (!ch-><T>MChunk::valid_index(idx)) cache(idx); + return * (ch->pointer_to(idx)); +} + +inline const <T>& <T>MPlex:: operator [] (int idx) const +{ + if (!ch-><T>MChunk::valid_index(idx)) cache(idx); + return * ((const <T>*)(ch->pointer_to(idx))); +} + +inline int <T>MPlex::Pix_to_index(Pix p) const +{ + if (!ch-><T>MChunk::valid_pointer((<T>*)p)) cache((<T>*)p); + return ch->index_of((<T>*)p); +} + +inline int <T>MPlex::high() const +{ + return (((const <T>MChunk*)tl())-><T>MChunk::valid_index(fnc-1)) ? + fnc-1 : dopred(fnc-1); +} + +inline int <T>MPlex::low() const +{ + return (((const <T>MChunk*)hd)-><T>MChunk::valid_index(lo))? lo : dosucc(lo); +} + +inline <T>& <T>MPlex::low_element () +{ + return (*this)[low()]; +} + +inline const <T>& <T>MPlex::low_element () const +{ + return (*this)[low()]; +} + +inline <T>& <T>MPlex::high_element () +{ + return (*this)[high()]; +} + +inline const <T>& <T>MPlex::high_element () const +{ + return (*this)[high()]; +} + +inline Pix <T>MPlex::index_to_Pix(int idx) const +{ + if (!ch-><T>MChunk::valid_index(idx)) cache(idx); + return Pix(ch->pointer_to(idx)); +} + +inline void <T>MPlex::next(int& idx) const +{ + idx = (ch-><T>MChunk::valid_index(idx+1))? idx+1 : dosucc(idx); +} + +inline void <T>MPlex::prev(int& idx) const +{ + idx = (ch-><T>MChunk::valid_index(idx-1))? idx-1 : dopred(idx); +} + +inline Pix <T>MPlex::first() const +{ + return index_to_Pix(low()); +} + +inline Pix <T>MPlex::last() const +{ + return index_to_Pix(high()); +} + + +inline void <T>MPlex::undel_Pix(Pix p) +{ + undel_index(Pix_to_index(p)); +} + +inline int <T>MPlex::del_Pix(Pix p) +{ + return del_index(Pix_to_index(p)); +} + +inline <T>& <T>MPlex:: operator () (Pix p) +{ + return *((<T>*)p); +} + +inline const <T>& <T>MPlex:: operator () (Pix p) const +{ + return *((const <T>*)p); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Map.ccP b/gnu/lib/libg++/g++-include/gen/Map.ccP new file mode 100644 index 000000000000..03bb4b84f0fd --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Map.ccP @@ -0,0 +1,58 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <builtin.h> +#include "<T>.<C>.Map.h" + + +Pix <T><C>Map::seek(<T&> item) +{ + for (Pix i = first(); i != 0 && !(<T>EQ(key(i), item)); next(i)); + return i; +} + +int <T><C>Map::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void <T><C>Map::clear() +{ + Pix i = first(); + while (i != 0) + { + del(key(i)); + i = first(); + } +} + +int <T><C>Map::contains (<T&> item) +{ + return seek(item) != 0; +} + + +void <T><C>Map::error(const char* msg) +{ + (*lib_error_handler)("Map", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Map.hP b/gnu/lib/libg++/g++-include/gen/Map.hP new file mode 100644 index 000000000000..716a17fdd9ee --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Map.hP @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T><C>Map_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T><C>Map_h 1 + +#include <Pix.h> +#include "<T>.defs.h" + +class <T><C>Map +{ +protected: + int count; + <C> def; + +public: + <T><C>Map(<C&> dflt); + virtual ~<T><C>Map(); + + int length(); // current number of items + int empty(); + + virtual int contains(<T&> key); // is key mapped? + + virtual void clear(); // delete all items + + virtual <C>& operator [] (<T&> key) = 0; // access contents by key + + virtual void del(<T&> key) = 0; // delete entry + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual <T>& key(Pix i) = 0; // access key at i + virtual <C>& contents(Pix i) = 0; // access contents at i + + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek(<T&> key); // Pix of key + + <C>& dflt(); // access default val + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + + +inline <T><C>Map::~<T><C>Map() {} + +inline int <T><C>Map::length() +{ + return count; +} + +inline int <T><C>Map::empty() +{ + return count == 0; +} + +inline <C>& <T><C>Map::dflt() +{ + return def; +} + +inline <T><C>Map::<T><C>Map(<C&> dflt) :def(dflt) +{ + count = 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OSLBag.ccP b/gnu/lib/libg++/g++-include/gen/OSLBag.ccP new file mode 100644 index 000000000000..78398192bcef --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLBag.ccP @@ -0,0 +1,196 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.OSLBag.h" + + +Pix <T>OSLBag::seek(<T&> item, Pix i) +{ + if (i == 0) i = p.first(); else next(i); + for (; i != 0; p.next(i)) + { + int cmp = <T>CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + return 0; + } + return 0; +} + +int <T>OSLBag::nof(<T&> item) +{ + int n = 0; + for (Pix i = p.first(); i != 0; p.next(i)) + { + int cmp = <T>CMP(item, p(i)); + if (cmp == 0) + ++n; + else if (cmp < 0) + break; + } + return n; +} + +Pix <T>OSLBag::add(<T&> item) +{ + Pix i = p.first(); + if (i == 0) + { + ++count; + return p.prepend(item); + } + int cmp = <T>CMP(item, p(i)); + if (cmp <= 0) + { + ++count; + return p.prepend(item); + } + else + { + Pix trail = i; + p.next(i); + for (;;) + { + if (i == 0) + { + ++count; + return p.append(item); + } + cmp = <T>CMP(item, p(i)); + if (cmp <= 0) + { + ++count; + return p.ins_after(trail, item); + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void <T>OSLBag::del(<T&> item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = <T>CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = <T>CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_after(trail); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void <T>OSLBag::remove(<T&> item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = <T>CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + do + { + --count; + p.del_front(); + i = p.first(); + } while (i != 0 && <T>EQ(item, p(i))); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = <T>CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + do + { + --count; + p.del_after(trail); + i = trail; + next(i); + } while (i != 0 && <T>EQ(item, p(i))); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + +int <T>OSLBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + Pix trail = p.first(); + if (trail == 0) + v &= count == 0; + else + { + Pix i = trail; next(i); + while (i != 0) + { + v &= <T>CMP(p(trail), p(i)) <= 0; + trail = i; + next(i); + } + } + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/OSLBag.hP b/gnu/lib/libg++/g++-include/gen/OSLBag.hP new file mode 100644 index 000000000000..de4d67cf9a5d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLBag.hP @@ -0,0 +1,91 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>OSLBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>OSLBag_h 1 + +#include "<T>.Bag.h" +#include "<T>.SLList.h" + +class <T>OSLBag : public <T>Bag +{ +protected: + <T>SLList p; + +public: + <T>OSLBag(); + <T>OSLBag(const <T>OSLBag&); + + Pix add(<T&> item); + void del(<T&> item); + void remove(<T&>item); + + int contains(<T&> item); + int nof(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + int owns(Pix i); + Pix seek(<T&> item, Pix from = 0); + + int OK(); +}; + + +inline <T>OSLBag::<T>OSLBag() : p() { count = 0; } + +inline <T>OSLBag::<T>OSLBag(const <T>OSLBag& s) : p(s.p) { count = s.count; } + +inline Pix <T>OSLBag::first() +{ + return p.first(); +} + +inline void <T>OSLBag::next(Pix & idx) +{ + p.next(idx); +} + +inline <T>& <T>OSLBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void <T>OSLBag::clear() +{ + count = 0; p.clear(); +} + +inline int <T>OSLBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int <T>OSLBag::contains(<T&> item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OSLSet.ccP b/gnu/lib/libg++/g++-include/gen/OSLSet.ccP new file mode 100644 index 000000000000..bfd32ae954ce --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLSet.ccP @@ -0,0 +1,321 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.OSLSet.h" + + +Pix <T>OSLSet::seek(<T&> item) +{ + for (Pix i = p.first(); i != 0; p.next(i)) + { + int cmp = <T>CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + return 0; + } + return 0; +} + +Pix <T>OSLSet::add(<T&> item) +{ + Pix i = p.first(); + if (i == 0) + { + ++count; + return p.prepend(item); + } + int cmp = <T>CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + { + ++count; + return p.prepend(item); + } + else + { + Pix trail = i; + p.next(i); + for (;;) + { + if (i == 0) + { + ++count; + return p.append(item); + } + cmp = <T>CMP(item, p(i)); + if (cmp == 0) + return i; + else if (cmp < 0) + { + ++count; + return p.ins_after(trail, item); + } + else + { + trail = i; + p.next(i); + } + } + } +} + +void <T>OSLSet::del(<T&> item) +{ + Pix i = p.first(); + if (i == 0) + return; + int cmp = <T>CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + cmp = <T>CMP(item, p(i)); + if (cmp < 0) + return; + else if (cmp == 0) + { + --count; + p.del_after(trail); + return; + } + else + { + trail = i; + p.next(i); + } + } + } +} + + +int <T>OSLSet::operator <= (<T>OSLSet& b) +{ + if (count > b.count) return 0; + Pix i = first(); + Pix j = b.first(); + for (;;) + { + if (i == 0) + return 1; + else if (j == 0) + return 0; + int cmp = <T>CMP(p(i), b.p(j)); + if (cmp == 0) + { + next(i); b.next(j); + } + else if (cmp < 0) + return 0; + else + b.next(j); + } +} + +int <T>OSLSet::operator == (<T>OSLSet& b) +{ + if (count != b.count) return 0; + if (count == 0) return 1; + Pix i = p.first(); + Pix j = b.p.first(); + while (i != 0) + { + if (!<T>EQ(p(i),b.p(j))) return 0; + next(i); + b.next(j); + } + return 1; +} + + +void <T>OSLSet::operator |= (<T>OSLSet& b) +{ + if (&b == this || b.count == 0) + return; + else + { + Pix j = b.p.first(); + Pix i = p.first(); + Pix trail = 0; + for (;;) + { + if (j == 0) + return; + else if (i == 0) + { + for (; j != 0; b.next(j)) + { + ++count; + p.append(b.p(j)); + } + return; + } + int cmp = <T>CMP(p(i), b.p(j)); + if (cmp <= 0) + { + if (cmp == 0) b.next(j); + trail = i; + next(i); + } + else + { + ++count; + if (trail == 0) + trail = p.prepend(b.p(j)); + else + trail = p.ins_after(trail, b.p(j)); + b.next(j); + } + } + } +} + + +void <T>OSLSet::operator -= (<T>OSLSet& b) +{ + if (&b == this) + clear(); + else if (count != 0 && b.count != 0) + { + Pix i = p.first(); + Pix j = b.p.first(); + Pix trail = 0; + for (;;) + { + if (j == 0 || i == 0) + return; + int cmp = <T>CMP(p(i), b.p(j)); + if (cmp == 0) + { + --count; + b.next(j); + if (trail == 0) + { + p.del_front(); + i = p.first(); + } + else + { + next(i); + p.del_after(trail); + } + } + else if (cmp < 0) + { + trail = i; + next(i); + } + else + b.next(j); + } + } +} + +void <T>OSLSet::operator &= (<T>OSLSet& b) +{ + if (b.count == 0) + clear(); + else if (&b != this && count != 0) + { + Pix i = p.first(); + Pix j = b.p.first(); + Pix trail = 0; + for (;;) + { + if (i == 0) + return; + else if (j == 0) + { + if (trail == 0) + { + p.clear(); + count = 0; + } + else + { + while (i != 0) + { + --count; + next(i); + p.del_after(trail); + } + } + return; + } + int cmp = <T>CMP(p(i), b.p(j)); + + if (cmp == 0) + { + trail = i; + next(i); + b.next(j); + } + else if (cmp < 0) + { + --count; + if (trail == 0) + { + p.del_front(); + i = p.first(); + } + else + { + next(i); + p.del_after(trail); + } + } + else + b.next(j); + } + } +} + + +int <T>OSLSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + Pix trail = p.first(); + if (trail == 0) + v &= count == 0; + else + { + Pix i = trail; next(i); + while (i != 0) + { + v &= <T>CMP(p(trail), p(i)) < 0; + trail = i; + next(i); + } + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/OSLSet.hP b/gnu/lib/libg++/g++-include/gen/OSLSet.hP new file mode 100644 index 000000000000..bf3707f6c7b0 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OSLSet.hP @@ -0,0 +1,101 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>OSLSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>OSLSet_h 1 + +#include "<T>.Set.h" +#include "<T>.SLList.h" + +class <T>OSLSet : public <T>Set +{ +protected: + <T>SLList p; + +public: + <T>OSLSet(); + <T>OSLSet(const <T>OSLSet&); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + int owns(Pix i); + Pix seek(<T&> item); + + void operator |= (<T>OSLSet& b); + void operator -= (<T>OSLSet& b); + void operator &= (<T>OSLSet& b); + + int operator == (<T>OSLSet& b); + int operator != (<T>OSLSet& b); + int operator <= (<T>OSLSet& b); + + int OK(); +}; + + +inline <T>OSLSet::<T>OSLSet() : p() { count = 0; } + +inline <T>OSLSet::<T>OSLSet(const <T>OSLSet& s) : p(s.p) { count = s.count; } + +inline Pix <T>OSLSet::first() +{ + return p.first(); +} + +inline void <T>OSLSet::next(Pix & idx) +{ + p.next(idx); +} + +inline <T>& <T>OSLSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void <T>OSLSet::clear() +{ + count = 0; p.clear(); +} + +inline int <T>OSLSet::contains (<T&> item) +{ + return seek(item) != 0; +} + +inline int <T>OSLSet::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int <T>OSLSet::operator != (<T>OSLSet& b) +{ + return !(*this == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OXPBag.ccP b/gnu/lib/libg++/g++-include/gen/OXPBag.ccP new file mode 100644 index 000000000000..6619e25ea191 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPBag.ccP @@ -0,0 +1,221 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.OXPBag.h" + + +Pix <T>OXPBag::seek(<T&> item, Pix i) +{ + if (i == 0) + { + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + { + while (mid > p.low() && <T>EQ(item, p[mid - 1])) --mid; + return p.index_to_Pix(mid); + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; + } + int cmp = <T>CMP(item, p(i)); + if (cmp == 0) + { + next(i); + return (<T>EQ(item, p(i)))? i : 0; + } + else if (cmp < 0) + { + int ind = p.Pix_to_index(i); + int l = ind; + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + { + while (mid > ind && <T>EQ(item, p[mid - 1])) --mid; + return p.index_to_Pix(mid); + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; + } + else + return 0; +} + +int <T>OXPBag::nof(<T&> item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + { + l = h = mid; + while (l > p.low() && <T>EQ(item, p[l - 1])) --l; + while (h < p.high() && <T>EQ(item, p[h + 1])) ++h; + return h - l + 1; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; +} + +Pix <T>OXPBag::add(<T&> item) +{ + if (count == 0) + { + ++count; + return p.index_to_Pix(p.add_high(item)); + } + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + { + l = mid; + break; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + // add on whichever side is shortest + ++count; + if (l == p.fence()) + return p.index_to_Pix(p.add_high(item)); + else if (l == p.low()) + return p.index_to_Pix(p.add_low(item)); + else + { + if (p.high() - l < l - p.low()) + { + h = p.add_high(p.high_element()); + for (int i = h - 1; i > l; --i) p[i] = p[i-1]; + } + else + { + --l; + h = p.add_low(p.low_element()); + for (int i = h + 1; i < l; ++i) p[i] = p[i+1]; + } + p[l] = item; + return p.index_to_Pix(l); + } +} + +void <T>OXPBag::del(<T&> item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + { + --count; + if (p.high() - mid < mid - p.low()) + { + for (int i = mid; i < p.high(); ++i) p[i] = p[i+1]; + p.del_high(); + } + else + { + for (int i = mid; i > p.low(); --i) p[i] = p[i-1]; + p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +void <T>OXPBag::remove(<T&> item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + { + l = h = mid; + while (l > p.low() && <T>EQ(item, p[l - 1])) --l; + while (h < p.high() && <T>EQ(item, p[h + 1])) ++h; + int n = h - l + 1; + count -= n; + if (p.high() - h < l - p.low()) + { + h = p.high() - n; + for (int i = l; i <= h; ++i) p[i] = p[i+n]; + while (n-- > 0) p.del_high(); + } + else + { + l = p.low() + n; + for (int i = h; i >= l; --i) p[i] = p[i-n]; + while (n-- > 0) p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +int <T>OXPBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + for (int i = p.low(); i < p.high(); ++i) v &= <T>CMP(p[i], p[i+1]) <= 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/OXPBag.hP b/gnu/lib/libg++/g++-include/gen/OXPBag.hP new file mode 100644 index 000000000000..128d4a20e401 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPBag.hP @@ -0,0 +1,73 @@ +#ifndef _<T>OXPBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>OXPBag_h 1 + +#include "<T>.Bag.h" +#include "<T>.XPlex.h" + +class <T>OXPBag : public <T>Bag +{ +protected: + <T>XPlex p; + +public: + <T>OXPBag(int chunksize = DEFAULT_INITIAL_CAPACITY); + <T>OXPBag(const <T>OXPBag&); + + Pix add(<T&> item); + void del(<T&> item); +#undef remove + void remove(<T&>item); + int nof(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + int owns(Pix i); + Pix seek(<T&> item, Pix from = 0); + + int OK(); +}; + + +inline <T>OXPBag::<T>OXPBag(int chunksize) + : p(chunksize) { count = 0; } + +inline <T>OXPBag::<T>OXPBag(const <T>OXPBag& s) : p(s.p) { count = s.count; } + +inline Pix <T>OXPBag::first() +{ + return p.first(); +} + +inline void <T>OXPBag::next(Pix & idx) +{ + p.next(idx); +} + +inline <T>& <T>OXPBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void <T>OXPBag::clear() +{ + count = 0; p.clear(); +} + +inline int <T>OXPBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int <T>OXPBag::contains(<T&> item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/OXPSet.ccP b/gnu/lib/libg++/g++-include/gen/OXPSet.ccP new file mode 100644 index 000000000000..14611954511e --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPSet.ccP @@ -0,0 +1,280 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.OXPSet.h" + + +Pix <T>OXPSet::seek(<T&> item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + return p.index_to_Pix(mid); + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + return 0; +} + +Pix <T>OXPSet::add(<T&> item) +{ + if (count == 0) + { + ++count; + return p.index_to_Pix(p.add_high(item)); + } + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + return p.index_to_Pix(mid); + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } + // add on whichever side is shortest + ++count; + if (l == p.fence()) + return p.index_to_Pix(p.add_high(item)); + else if (l == p.low()) + return p.index_to_Pix(p.add_low(item)); + else + { + if (p.fence() - l < l - p.low()) + { + h = p.add_high(p.high_element()); + for (int i = h - 1; i > l; --i) p[i] = p[i-1]; + } + else + { + --l; + h = p.add_low(p.low_element()); + for (int i = h + 1; i < l; ++i) p[i] = p[i+1]; + } + p[l] = item; + return p.index_to_Pix(l); + } +} + +void <T>OXPSet::del(<T&> item) +{ + int l = p.low(); + int h = p.high(); + while (l <= h) + { + int mid = (l + h) / 2; + int cmp = <T>CMP(item, p[mid]); + if (cmp == 0) + { + --count; + if (p.high() - mid < mid - p.low()) + { + for (int i = mid; i < p.high(); ++i) p[i] = p[i+1]; + p.del_high(); + } + else + { + for (int i = mid; i > p.low(); --i) p[i] = p[i-1]; + p.del_low(); + } + return; + } + else if (cmp < 0) + h = mid - 1; + else + l = mid + 1; + } +} + +int <T>OXPSet::operator <= (<T>OXPSet& b) +{ + if (count > b.count) return 0; + int i = p.low(); + int j = b.p.low(); + for (;;) + { + if (i >= p.fence()) + return 1; + else if (j >= b.p.fence()) + return 0; + int cmp = <T>CMP(p[i], b.p[j]); + if (cmp == 0) + { + ++i; ++j; + } + else if (cmp < 0) + return 0; + else + ++j; + } +} + +int <T>OXPSet::operator == (<T>OXPSet& b) +{ + int n = count; + if (n != b.count) return 0; + if (n == 0) return 1; + int i = p.low(); + int j = b.p.low(); + while (n-- > 0) if (!<T>EQ(p[i++], b.p[j++])) return 0; + return 1; +} + + +void <T>OXPSet::operator |= (<T>OXPSet& b) +{ + if (&b == this || b.count == 0) + return; + else if (b.count <= 2) // small b -- just add + for (Pix i = b.first(); i; b.next(i)) add(b(i)); + else + { + // strategy: merge into top of p, simultaneously killing old bottom + int oldfence = p.fence(); + int i = p.low(); + int j = b.p.low(); + for (;;) + { + if (i == oldfence) + { + while (j < b.p.fence()) p.add_high(b.p[j++]); + break; + } + else if (j == b.p.fence()) + { + while (i++ < oldfence) + { + p.add_high(p.low_element()); + p.del_low(); + } + break; + } + int cmp = <T>CMP(p[i], b.p[j]); + if (cmp <= 0) + { + ++i; + if (cmp == 0) ++j; + p.add_high(p.low_element()); + p.del_low(); + } + else + p.add_high(b.p[j++]); + } + count = p.length(); + } +} + + + +void <T>OXPSet::operator -= (<T>OXPSet& b) +{ + if (&b == this) + clear(); + else if (count != 0 && b.count != 0) + { + int i = p.low(); + int k = i; + int j = b.p.low(); + int oldfence = p.fence(); + for (;;) + { + if (i >= oldfence) + break; + else if (j >= b.p.fence()) + { + if (k != i) + while (i < oldfence) p[k++] = p[i++]; + else + k = oldfence; + break; + } + int cmp = <T>CMP(p[i], b.p[j]); + if (cmp == 0) + { + ++i; ++j; + } + else if (cmp < 0) + { + if (k != i) p[k] = p[i]; + ++i; ++k; + } + else + j++; + } + while (k++ < oldfence) + { + --count; + p.del_high(); + } + } +} + +void <T>OXPSet::operator &= (<T>OXPSet& b) +{ + if (b.count == 0) + clear(); + else if (&b != this && count != 0) + { + int i = p.low(); + int k = i; + int j = b.p.low(); + int oldfence = p.fence(); + for (;;) + { + if (i >= oldfence || j >= b.p.fence()) + break; + int cmp = <T>CMP(p[i], b.p[j]); + if (cmp == 0) + { + if (k != i) p[k] = p[i]; + ++i; ++k; ++j; + } + else if (cmp < 0) + ++i; + else + ++j; + } + while (k++ < oldfence) + { + --count; + p.del_high(); + } + } +} + +int <T>OXPSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + for (int i = p.low(); i < p.high(); ++i) v &= <T>CMP(p[i], p[i+1]) < 0; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/OXPSet.hP b/gnu/lib/libg++/g++-include/gen/OXPSet.hP new file mode 100644 index 000000000000..4e0c97712d2a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/OXPSet.hP @@ -0,0 +1,102 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>OXPSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>OXPSet_h 1 + +#include "<T>.Set.h" +#include "<T>.XPlex.h" + +class <T>OXPSet : public <T>Set +{ +protected: + <T>XPlex p; + +public: + <T>OXPSet(int chunksize = DEFAULT_INITIAL_CAPACITY); + <T>OXPSet(const <T>OXPSet&); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + int owns(Pix i); + Pix seek(<T&> item); + + void operator |= (<T>OXPSet& b); + void operator -= (<T>OXPSet& b); + void operator &= (<T>OXPSet& b); + + int operator == (<T>OXPSet& b); + int operator != (<T>OXPSet& b); + int operator <= (<T>OXPSet& b); + + int OK(); +}; + + +inline <T>OXPSet::<T>OXPSet(int chunksize) + : p(chunksize) { count = 0; } + +inline <T>OXPSet::<T>OXPSet(const <T>OXPSet& s) : p(s.p) { count = s.count; } + +inline Pix <T>OXPSet::first() +{ + return p.first(); +} + +inline void <T>OXPSet::next(Pix & idx) +{ + p.next(idx); +} + +inline <T>& <T>OXPSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void <T>OXPSet::clear() +{ + count = 0; p.clear(); +} + +inline int <T>OXPSet::contains (<T&> item) +{ + return seek(item) != 0; +} + +inline int <T>OXPSet::owns (Pix idx) +{ + return p.owns(idx); +} + +inline int <T>OXPSet::operator != (<T>OXPSet& b) +{ + return !(*this == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/PHPQ.ccP b/gnu/lib/libg++/g++-include/gen/PHPQ.ccP new file mode 100644 index 000000000000..764b11c5cf99 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PHPQ.ccP @@ -0,0 +1,339 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Dirk Grunwald (grunwald@cs.uiuc.edu) + adapted for libg++ by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <values.h> +#include "<T>.PHPQ.h" + +// +// This defines a Pairing Heap structure +// +// See ``The Pairing Heap: A New Form of Self-Adjusting Heap'' +// Fredman, Segdewick et al, +// Algorithmica (1986) 1:111-129 +// +// In particular, this implements the pairing heap using the circular +// list. +// +// + +<T>PHPQ::<T>PHPQ(int sz) +{ + storage = 0; + root = 0; + count = 0; + size = 0; + prealloc(sz); +} + +<T>PHPQ::<T>PHPQ(<T>PHPQ& a) +{ + storage = 0; + root = 0; + count = 0; + size = 0; + prealloc(a.size); + for (Pix i = a.first(); i != 0; a.next(i)) enq(a(i)); +} + + +void <T>PHPQ::prealloc(int newsize) +{ + ++newsize; // leave a spot for freelist + if (size != 0) + { + int news = size; + while (news <= newsize) news = (news * 3) / 2; + newsize = news; + } + // see if indices are OK + <T>PHPQNode test; + test.sibling = 0; + test.sibling = ~test.sibling; + if ((unsigned long)newsize > (unsigned long)(test.sibling)) + error("storage size exceeds index range"); + + if (storage == 0) + { + storage = new <T>PHPQNode[size = newsize]; + for (int i = 0; i < size; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[size-1].sibling = 0; + } + else + { + <T>PHPQNode* newstor = new <T>PHPQNode[newsize]; + for (int i = 1; i < size; ++i) + newstor[i] = storage[i]; + delete [] storage; + storage = newstor; + for (i = size; i < newsize; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[newsize-1].sibling = 0; + storage[0].sibling = size; + size = newsize; + } +} + + +void <T>PHPQ::clear() +{ + for (int i = 0; i < size; ++i) + { + storage[i].sibling = i + 1; + storage[i].valid = 0; + } + storage[size-1].sibling = 0; + root = 0; + count = 0; +} + +Pix <T>PHPQ::enq(<T&> item) +{ + ++count; + if (storage[0].sibling == 0) + prealloc(count); + + int cell = storage[0].sibling; + storage[0].sibling = storage[cell].sibling; + storage[cell].sibling = 0; + storage[cell].children = 0; + storage[cell].item = item; + storage[cell].valid = 1; + + if (root == 0) + { + root = cell; + return Pix(root); + } + else + { + int parent; + int child; + + if (<T>LE(storage[root].item, storage[cell].item)) + { + parent = root; child = cell; + } + else + { + parent = cell; child = root; + } + int popsKid = storage[parent].children; + + if (popsKid == 0) + { + storage[parent].children = child; + storage[child].sibling = child; + } + else + { + int temp = storage[popsKid].sibling; + storage[popsKid].sibling = child; + storage[child].sibling = temp; + storage[parent].children = child; + } + root = parent; + return Pix(cell); + } +} + +// +// Item removal is the most complicated routine. +// +// We remove the root (should there be one) and then select a new +// root. The siblings of the root are in a circular list. We continue +// to pair elements in this list until there is a single element. +// This element will be the new root. + +void <T>PHPQ::del_front() +{ + int valid = 0; + do + { + if (root == 0) return; + if (valid = storage[root].valid) + --count; + storage[root].valid = 0; + int child = storage[root].children; + storage[root].sibling = storage[0].sibling; + storage[0].sibling = root; + + if (child == 0) + { + root = 0; + return; + } + else + { + while(storage[child].sibling != child) + { + // We have at least two kids, but we may only have + // two kids. So, oneChild != child, but it is possible + // that twoChild == child. + + int oneChild = storage[child].sibling; + int twoChild = storage[oneChild].sibling; + + // Remove the two from the sibling list + + storage[child].sibling = storage[twoChild].sibling; + storage[oneChild].sibling = 0; + storage[twoChild].sibling = 0; + + int bestChild; + int worstChild; + + if (<T>LE(storage[oneChild].item, storage[twoChild].item)) + { + bestChild = oneChild; worstChild = twoChild; + } + else + { + bestChild = twoChild; worstChild = oneChild; + } + int popsKid = storage[bestChild].children; + + if (popsKid == 0) + { + storage[bestChild].children = worstChild; + storage[worstChild].sibling = worstChild; + } + else + { + int temp = storage[popsKid].sibling; + storage[popsKid].sibling = worstChild; + storage[worstChild].sibling = temp; + storage[bestChild].children = worstChild; + } + if (twoChild == child) + { + // We have reduced the two to one, so we'll be exiting. + child = bestChild; + storage[child].sibling = child; + } + else + { + // We've removed two siblings, now we need to insert + // the better of the two + storage[bestChild].sibling = storage[child].sibling; + storage[child].sibling = bestChild; + child = storage[bestChild].sibling; + } + } + root = child; + } + } while ( !valid ); +} + +void <T>PHPQ::del(Pix p) +{ + if (p == 0) error("null Pix"); + int i = int(p); + if (storage[i].valid) + { + if (i == root) + del_front(); + else + { + storage[i].valid = 0; + --count; + } + } +} + + +Pix <T>PHPQ::seek(<T&> key) +{ + for (int i = 1; i < size; ++i) + if (storage[i].valid && <T>EQ(storage[i].item, key)) + return Pix(i); + return 0; +} + +Pix <T>PHPQ::first() +{ + for (int i = 1; i < size; ++i) + if (storage[i].valid) + return Pix(i); + return 0; +} + + +void <T>PHPQ::next(Pix& p) +{ + if (p == 0) return; + for (int i = int(p)+1; i < size; ++i) + if (storage[i].valid) + { + p = Pix(i); + return; + } + p = 0; +} + +int <T>PHPQ::OK() +{ + int v = storage != 0; + int n = 0; + for (int i = 0; i < size; ++i) if (storage[i].valid) ++n; + v &= n == count; + v &= check_sibling_list(root); + int ct = MAXLONG; + n = 0; + int f = storage[0].sibling; + while (f != 0 && ct-- > 0) + { + f = storage[f].sibling; + ++n; + } + v &= ct > 0; + v &= n <= size - count; + if (!v) error("invariant failure"); + return v; +} + + +int <T>PHPQ::check_sibling_list(int t) +{ + if (t != 0) + { + int s = t; + long ct = MAXLONG; // Lots of chances to find self! + do + { + if (storage[s].valid && !check_sibling_list(storage[s].children)) + return 0; + s = storage[s].sibling; + } while (ct-- > 0 && s != t && s != 0); + if (ct <= 0) return 0; + } + return 1; +} + + diff --git a/gnu/lib/libg++/g++-include/gen/PHPQ.hP b/gnu/lib/libg++/g++-include/gen/PHPQ.hP new file mode 100644 index 000000000000..359c527c602c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PHPQ.hP @@ -0,0 +1,108 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Dirk Grunwald (grunwald@cs.uiuc.edu) + adapted for libg++ by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef <T>PHPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define <T>PHPQ_h 1 + +#include "<T>.PQ.h" + +#ifndef <T>PHPQIndex +#define <T>PHPQIndex unsigned short +#endif + +struct <T>PHPQNode +{ + <T>PHPQIndex sibling; + <T>PHPQIndex children; + <T> item; + char valid; +}; + + +class <T>PHPQ : public <T>PQ +{ + <T>PHPQNode* storage; // table -- freelist in storage[0].sibling + int root; + int size; + + void prealloc(int); + int check_sibling_list(int); + +public: + + <T>PHPQ(int sz = DEFAULT_INITIAL_CAPACITY); + <T>PHPQ(<T>PHPQ&); + ~<T>PHPQ(); + + Pix enq(<T&> item); + <T> deq(); + + <T>& front(); + void del_front(); + + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + void del(Pix i); + Pix seek(<T&> item); + + int OK(); // rep invariant +}; + + +inline <T>PHPQ::~<T>PHPQ() +{ + delete [] storage; +} + + +inline <T> <T>PHPQ::deq() +{ + if (count == 0) error("deq of empty PQ"); + <T> x = storage[root].item; + del_front(); + return x; +} + + +inline <T>& <T>PHPQ::front() +{ + if (count == 0) error("front of empty PQ"); + return storage[root].item; +} + +inline int <T>PHPQ::contains(<T&> item) +{ + return seek(item) != 0; +} + +inline <T>& <T>PHPQ::operator() (Pix p) +{ + if (p == 0) error("null Pix"); + return storage[int(p)].item; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/PQ.ccP b/gnu/lib/libg++/g++-include/gen/PQ.ccP new file mode 100644 index 000000000000..810240759cbf --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PQ.ccP @@ -0,0 +1,62 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <builtin.h> +#include "<T>.PQ.h" + + + +<T> <T>PQ::deq() +{ + <T> x = front(); + del_front(); + return x; +} + +Pix <T>PQ::seek(<T&> item) +{ + for (Pix i = first(); i != 0 && !(<T>EQ((*this)(i), item)); next(i)); + return i; +} + +int <T>PQ::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void <T>PQ::clear() +{ + while (count != 0) del_front(); +} + +int <T>PQ::contains (<T&> item) +{ + return seek(item) != 0; +} + + +void <T>PQ::error(const char* msg) +{ + (*lib_error_handler)("PQ", msg); +} + diff --git a/gnu/lib/libg++/g++-include/gen/PQ.hP b/gnu/lib/libg++/g++-include/gen/PQ.hP new file mode 100644 index 000000000000..981592ae856b --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PQ.hP @@ -0,0 +1,78 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>PQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>PQ_h 1 + +#include <Pix.h> +#include "<T>.defs.h" + +class <T>PQ +{ +protected: + + int count; + +public: + <T>PQ(); + virtual ~<T>PQ(); + + int length(); // current number of items + int empty(); + + virtual Pix enq(<T&> item) = 0; // add item; return Pix + virtual <T> deq(); // return & remove min + + virtual <T>& front() = 0; // access min item + virtual void del_front() = 0; // delete min item + + virtual int contains(<T&> item); // is item in PQ? + + virtual void clear(); // delete all items + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual <T>& operator () (Pix i) = 0; // access item at i + virtual void del(Pix i) = 0; // delete item at i + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek(<T&> item); // Pix of item + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + + +inline <T>PQ::<T>PQ() :count(0) {} + +inline <T>PQ::~<T>PQ() {} + +inline int <T>PQ::length() +{ + return count; +} + +inline int <T>PQ::empty() +{ + return count == 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/PSList.hP b/gnu/lib/libg++/g++-include/gen/PSList.hP new file mode 100644 index 000000000000..eacb34dbe354 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PSList.hP @@ -0,0 +1,32 @@ +/* : Light weight list: This will simply reuse code from a VoidP List, which +was genclassed from the SLList libg++ class. The classes generated from this file +will all be derived classes from class VoidSLList or intSLList. Note that class SLList does not +offer all the functionality of List classes, such as sharing of sub-lists. +However, no additional code is needed at all and no .cc file is generated. So it costs nothing +to use these type-safe lists. Only member functions needing type casting are re-defined */ + + +#ifndef _<T>SList_h +#define _<T>SList_h 1 + +#include "VoidP.SLList.h" +#include "<T>.defs.h" + +class <T>SList : public VoidPSLList +{ +public: + <T>SList() {} + <T>SList(<T>SList& a) : (a) {} + ~<T>SList() {} + + <T>SList& operator = (<T>SList& a) { + return (<T>SList&) VoidPSLList::operator= (a); } + + <T>& operator () (Pix p) { return (<T>&) (VoidPSLList::operator() (p)); } + <T>& front() { return (<T>&) VoidPSLList::front(); } + <T>& rear() { return (<T>&) VoidPSLList::rear(); } + <T> remove_front() { return (<T>) VoidPSLList::remove_front(); } + +}; + +#endif /* conditional include */ diff --git a/gnu/lib/libg++/g++-include/gen/PVec.hP b/gnu/lib/libg++/g++-include/gen/PVec.hP new file mode 100644 index 000000000000..de32482610b4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/PVec.hP @@ -0,0 +1,79 @@ +/* : light weight Vector: This will simply reuse code from */ +/* a VoidP Vec, which was genclassed from the Vec libg++ class. */ +/* The classes generated from this file will all be derived classes */ +/* from class VoidVec or intVec. No .cc file is generated. So */ +/* it costs nothing to use these type-safe Vectors. Only member */ +/* functions needing type casting are re-defined. */ +/* */ + +#ifndef _<T>Vec_h +#define _<T>Vec_h 1 + +#include "VoidP.Vec.h" +#include "<T>.defs.h" + + +#ifndef _<T>_typedefs +#define _<T>_typedefs 1 +typedef void (*<T>Procedure)(<T> ); +typedef <T> (*<T>Mapper)(<T> ); +typedef <T> (*<T>Combiner)(<T> , <T> ); +typedef int (*<T>Predicate)(<T> ); +typedef int (*<T>Comparator)(<T> , <T> ); +#endif + +class <T>Vec : public VoidPVec +{ +protected: + <T>Vec(int l, <T>* d) : (l, (VoidP*) d) {}; +public: + <T>Vec() {}; + <T>Vec(int l) : (l) {}; + <T>Vec(int l, <T&> fill_value) : (l, fill_value) {}; + <T>Vec(<T>Vec& v) : (v) {}; + <T>Vec(VoidPVec& v) {fake_copy(v, s, len);} + ~<T>Vec() {}; + + <T>Vec& operator = (<T>Vec& a) + {return (<T>Vec&) VoidPVec::operator= (a);} + <T>Vec at(int from, int n) {return (<T>Vec) VoidPVec::at(from, n);} + + <T>& operator [] (int n) {return (<T>&)VoidPVec::operator[] (n);} + <T>& elem(int n) {return (<T>&)VoidPVec::elem(n);} + + friend <T>Vec concat(<T>Vec& a, <T>Vec& b); + friend <T>Vec map(<T>Mapper f, <T>Vec & a); + friend <T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f); + friend <T>Vec combine(<T>Combiner f, <T>Vec & a, <T>Vec & b); + friend <T>Vec reverse(<T>Vec& a); + + void sort(<T>Comparator f); + void apply(<T>Procedure f); + <T> reduce(<T>Combiner f, <T> base); +}; + +inline <T>Vec concat(<T>Vec& a, <T>Vec& b) +{return (<T>Vec)concat((VoidPVec&)a, (VoidPVec&)b);} + +inline <T>Vec map(<T>Mapper f, <T>Vec & a) { + return (<T>Vec)map((VoidPMapper)f, (VoidPVec&)a); } + +inline <T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f) { + return (<T>Vec)merge((VoidPVec&)a, (VoidPVec&)b, (VoidPComparator)f); } + +inline <T>Vec combine(<T>Combiner f, <T>Vec & a, <T>Vec & b) { + return (<T>Vec)combine((VoidPCombiner)f, (VoidPVec&)a, (VoidPVec&)b); } + +inline <T>Vec reverse(<T>Vec& a) { + return (<T>Vec)reverse((VoidPVec&)a);} + +inline void <T>Vec::sort(<T>Comparator f) { + VoidPVec::sort((VoidPComparator) f); } + +inline void <T>Vec::apply(<T>Procedure f) { + VoidPVec::apply((VoidPProcedure) f); } + +inline <T> <T>Vec::reduce(<T>Combiner f, <T> base) { + return (<T>)VoidPVec::reduce((VoidPCombiner)f, base);} + +#endif /* conditional include */ diff --git a/gnu/lib/libg++/g++-include/gen/Plex.ccP b/gnu/lib/libg++/g++-include/gen/Plex.ccP new file mode 100644 index 000000000000..5eb13c85f488 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Plex.ccP @@ -0,0 +1,222 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include <builtin.h> +#include "<T>.Plex.h" + +// IChunk support + +void <T>IChunk::error(const char* msg) const +{ + (*lib_error_handler)("<T>IChunk", msg); +} + +void <T>IChunk::index_error() const +{ + error("attempt to use invalid index"); +} + +void <T>IChunk::empty_error() const +{ + error("invalid use of empty chunk"); +} + +void <T>IChunk::full_error() const +{ + error("attempt to extend chunk beyond bounds"); +} + +<T>IChunk:: ~<T>IChunk() {} + +<T>IChunk::<T>IChunk(<T>* d, + int baseidx, + int lowidx, + int fenceidx, + int topidx) +{ + if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx) + error("inconsistent specification"); + data = d; + base = baseidx; + low = lowidx; + fence = fenceidx; + top = topidx; + nxt = prv = this; +} + +void <T>IChunk:: re_index(int lo) +{ + int delta = lo - low; + base += delta; + low += delta; + fence += delta; + top += delta; +} + + +void <T>IChunk::clear(int lo) +{ + int s = top - base; + low = base = fence = lo; + top = base + s; +} + +void <T>IChunk::cleardown(int hi) +{ + int s = top - base; + low = top = fence = hi; + base = top - s; +} + +int <T>IChunk:: OK() const +{ + int v = data != 0; // have some data + v &= base <= low; // ok, index-wise + v &= low <= fence; + v &= fence <= top; + + v &= nxt->prv == this; // and links are OK + v &= prv->nxt == this; + if (!v) error("invariant failure"); + return(v); +} + + +// error handling + + +void <T>Plex::error(const char* msg) const +{ + (*lib_error_handler)("Plex", msg); +} + +void <T>Plex::index_error() const +{ + error("attempt to access invalid index"); +} + +void <T>Plex::empty_error() const +{ + error("attempted operation on empty plex"); +} + +void <T>Plex::full_error() const +{ + error("attempt to increase size of plex past limit"); +} + +// generic plex ops + +<T>Plex:: ~<T>Plex() +{ + invalidate(); +} + + +void <T>Plex::append (const <T>Plex& a) +{ + for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]); +} + +void <T>Plex::prepend (const <T>Plex& a) +{ + for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]); +} + +void <T>Plex::reverse() +{ + <T> tmp; + int l = low(); + int h = high(); + while (l < h) + { + tmp = (*this)[l]; + (*this)[l] = (*this)[h]; + (*this)[h] = tmp; + next(l); + prev(h); + } +} + + +void <T>Plex::fill(const <T&> x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void <T>Plex::fill(const <T&> x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + + +void <T>Plex::del_chunk(<T>IChunk* x) +{ + if (x != 0) + { + x->unlink(); + <T>* data = (<T>*)(x->invalidate()); + delete [] data; + delete x; + } +} + + +void <T>Plex::invalidate() +{ + <T>IChunk* t = hd; + if (t != 0) + { + <T>IChunk* tail = tl(); + while (t != tail) + { + <T>IChunk* nxt = t->next(); + del_chunk(t); + t = nxt; + } + del_chunk(t); + hd = 0; + } +} + +int <T>Plex::reset_low(int l) +{ + int old = lo; + int diff = l - lo; + if (diff != 0) + { + lo += diff; + fnc += diff; + <T>IChunk* t = hd; + do + { + t->re_index(t->low_index() + diff); + t = t->next(); + } while (t != hd); + } + return old; +} + + + + diff --git a/gnu/lib/libg++/g++-include/gen/Plex.hP b/gnu/lib/libg++/g++-include/gen/Plex.hP new file mode 100644 index 000000000000..f8af1b6ba7ca --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Plex.hP @@ -0,0 +1,494 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _<T>Plex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>Plex_h 1 + +#include <std.h> +#include <Pix.h> +#include "<T>.defs.h" + +// Plexes are made out of <T>IChunks + +#include <stddef.h> + +class <T>IChunk +{ +//public: // kludge until C++ `protected' policies settled +protected: + + <T>* data; // data, from client + + int base; // lowest possible index + int low; // lowest valid index + int fence; // highest valid index + 1 + int top; // highest possible index + 1 + + <T>IChunk* nxt; // circular links + <T>IChunk* prv; + +public: + +// constructors + + <T>IChunk(<T>* d, // ptr to array of elements + int base_idx, // initial indices + int low_idx, + int fence_idx, + int top_idx); + + virtual ~<T>IChunk(); + +// status reports + + int size() const; // number of slots + + virtual int empty() const ; + virtual int full() const ; + + int can_grow_high () const ; // there is space to add data + int can_grow_low () const; + + int base_index() const; // lowest possible index; + int low_index() const; // lowest actual index; + virtual int first_index() const; // lowest valid index or fence if none + virtual int last_index() const; // highest valid index or low-1 if none + int fence_index() const; // highest actual index + 1 + int top_index() const; // highest possible index + 1 + +// indexing conversion + + int possible_index(int i) const; // i between base and top + int actual_index(int i) const; // i between low and fence + virtual int valid_index(int i) const; // i not deleted (mainly for mchunks) + + int possible_pointer(const <T>* p) const; // same for ptr + int actual_pointer(const <T>* p) const; + virtual int valid_pointer(const <T>* p) const; + + <T>* pointer_to(int i) const ; // pointer to data indexed by i + // caution: i is not checked for validity + int index_of(const <T>* p) const; // index of data pointed to by p + // caution: p is not checked for validity + + virtual int succ(int idx) const; // next valid index or fence if none + virtual int pred(int idx) const; // previous index or low - 1 if none + + virtual <T>* first_pointer() const; // pointer to first valid pos or 0 + virtual <T>* last_pointer() const; // pointer to first valid pos or 0 + virtual <T>* succ(<T>* p) const; // next pointer or 0 + virtual <T>* pred(<T>* p) const; // previous pointer or 0 + +// modification + + virtual <T>* grow_high (); // return spot to add an element + virtual <T>* grow_low (); + + virtual void shrink_high (); // logically delete top index + virtual void shrink_low (); + + virtual void clear(int lo); // reset to empty ch with base = lo + virtual void cleardown(int hi); // reset to empty ch with top = hi + void re_index(int lo); // re-index so lo is new low + +// chunk traversal + + <T>IChunk* next() const; + <T>IChunk* prev() const; + + void link_to_prev(<T>IChunk* prev); + void link_to_next(<T>IChunk* next); + void unlink(); + +// state checks + + <T>* invalidate(); // mark self as invalid; return data + // for possible deletion + + virtual int OK() const; // representation invariant + + void error(const char*) const; + void empty_error() const; + void full_error() const; + void index_error() const; +}; + +// <T>Plex is a partly `abstract' class: few of the virtuals +// are implemented at the Plex level, only in the subclasses + +class <T>Plex +{ +protected: + + <T>IChunk* hd; // a chunk holding the data + int lo; // lowest index + int fnc; // highest index + 1 + int csize; // size of the chunk + + void invalidate(); // mark so OK() is false + void del_chunk(<T>IChunk*); // delete a chunk + + <T>IChunk* tl() const; // last chunk; + int one_chunk() const; // true if hd == tl() + +public: + +// constructors, etc. + + <T>Plex(); // no-op + + virtual ~<T>Plex(); + + +// Access functions + + virtual <T>& operator [] (int idx) = 0; // access by index; + virtual <T>& operator () (Pix p) = 0; // access by Pix; + + virtual <T>& high_element () = 0; // access high element + virtual <T>& low_element () = 0; // access low element + +// read-only versions for const Plexes + + virtual const <T>& operator [] (int idx) const = 0; // access by index; + virtual const <T>& operator () (Pix p) const = 0; // access by Pix; + + virtual const <T>& high_element () const = 0; // access high element + virtual const <T>& low_element () const = 0; // access low element + + +// Index functions + + virtual int valid (int idx) const = 0; // idx is an OK index + + virtual int low() const = 0; // lowest index or fence if none + virtual int high() const = 0; // highest index or low-1 if none + + int ecnef() const; // low limit index (low-1) + int fence() const; // high limit index (high+1) + + virtual void prev(int& idx) const= 0; // set idx to preceding index + // caution: pred may be out of bounds + + virtual void next(int& idx) const = 0; // set to next index + // caution: succ may be out of bounds + + virtual Pix first() const = 0; // Pix to low element or 0 + virtual Pix last() const = 0; // Pix to high element or 0 + virtual void prev(Pix& pix) const = 0; // preceding pix or 0 + virtual void next(Pix& pix) const = 0; // next pix or 0 + virtual int owns(Pix p) const = 0; // p is an OK Pix + +// index<->Pix + + virtual int Pix_to_index(Pix p) const = 0; // get index via Pix + virtual Pix index_to_Pix(int idx) const = 0; // Pix via index + +// Growth + + virtual int add_high(const <T&> elem) =0;// add new element at high end + // return new high + + virtual int add_low(const <T&> elem) = 0; // add new low element, + // return new low + +// Shrinkage + + virtual int del_high() = 0; // remove the element at high end + // return new high + virtual int del_low() = 0; // delete low element, return new lo + + // caution: del_low/high + // does not necessarily + // immediately call <T>::~<T> + + +// operations on multiple elements + + virtual void fill(const <T&> x); // set all elements = x + virtual void fill(const <T&> x, int from, int to); // fill from to to + virtual void clear() = 0; // reset to zero-sized Plex + virtual int reset_low(int newlow); // change low index,return old + virtual void reverse(); // reverse in-place + virtual void append(const <T>Plex& a); // concatenate a copy + virtual void prepend(const <T>Plex& a); // prepend a copy + +// status + + virtual int can_add_high() const = 0; + virtual int can_add_low() const = 0; + + int length () const; // number of slots + + int empty () const; // is the plex empty? + virtual int full() const = 0; // it it full? + + int chunk_size() const; // report chunk size; + + virtual int OK() const = 0; // representation invariant + + void error(const char* msg) const; + void index_error() const; + void empty_error() const; + void full_error() const; +}; + + +// <T>IChunk ops + +inline int <T>IChunk:: size() const +{ + return top - base; +} + + +inline int <T>IChunk:: base_index() const +{ + return base; +} + +inline int <T>IChunk:: low_index() const +{ + return low; +} + +inline int <T>IChunk:: fence_index() const +{ + return fence; +} + +inline int <T>IChunk:: top_index() const +{ + return top; +} + +inline <T>* <T>IChunk:: pointer_to(int i) const +{ + return &(data[i-base]); +} + +inline int <T>IChunk:: index_of(const <T>* p) const +{ + return ((int)p - (int)data) / sizeof(<T>) + base; +} + +inline int <T>IChunk:: possible_index(int i) const +{ + return i >= base && i < top; +} + +inline int <T>IChunk:: possible_pointer(const <T>* p) const +{ + return p >= data && p < &(data[top-base]); +} + +inline int <T>IChunk:: actual_index(int i) const +{ + return i >= low && i < fence; +} + +inline int <T>IChunk:: actual_pointer(const <T>* p) const +{ + return p >= data && p < &(data[fence-base]); +} + +inline int <T>IChunk:: can_grow_high () const +{ + return fence < top; +} + +inline int <T>IChunk:: can_grow_low () const +{ + return base < low; +} + +inline <T>* <T>IChunk:: invalidate() +{ + <T>* p = data; + data = 0; + return p; +} + + +inline <T>IChunk* <T>IChunk::prev() const +{ + return prv; +} + +inline <T>IChunk* <T>IChunk::next() const +{ + return nxt; +} + +inline void <T>IChunk::link_to_prev(<T>IChunk* prev) +{ + nxt = prev->nxt; + prv = prev; + nxt->prv = this; + prv->nxt = this; +} + +inline void <T>IChunk::link_to_next(<T>IChunk* next) +{ + prv = next->prv; + nxt = next; + nxt->prv = this; + prv->nxt = this; +} + +inline void <T>IChunk::unlink() +{ + <T>IChunk* n = nxt; + <T>IChunk* p = prv; + n->prv = p; + p->nxt = n; + prv = nxt = this; +} + +inline int <T>IChunk:: empty() const +{ + return low == fence; +} + +inline int <T>IChunk:: full() const +{ + return top - base == fence - low; +} + +inline int <T>IChunk:: first_index() const +{ + return (low == fence)? fence : low; +} + +inline int <T>IChunk:: last_index() const +{ + return (low == fence)? low - 1 : fence - 1; +} + +inline int <T>IChunk:: succ(int i) const +{ + return (i < low) ? low : i + 1; +} + +inline int <T>IChunk:: pred(int i) const +{ + return (i > fence) ? (fence - 1) : i - 1; +} + +inline int <T>IChunk:: valid_index(int i) const +{ + return i >= low && i < fence; +} + +inline int <T>IChunk:: valid_pointer(const <T>* p) const +{ + return p >= &(data[low - base]) && p < &(data[fence - base]); +} + +inline <T>* <T>IChunk:: grow_high () +{ + if (!can_grow_high()) full_error(); + return &(data[fence++ - base]); +} + +inline <T>* <T>IChunk:: grow_low () +{ + if (!can_grow_low()) full_error(); + return &(data[--low - base]); +} + +inline void <T>IChunk:: shrink_high () +{ + if (empty()) empty_error(); + --fence; +} + +inline void <T>IChunk:: shrink_low () +{ + if (empty()) empty_error(); + ++low; +} + +inline <T>* <T>IChunk::first_pointer() const +{ + return (low == fence)? 0 : &(data[low - base]); +} + +inline <T>* <T>IChunk::last_pointer() const +{ + return (low == fence)? 0 : &(data[fence - base - 1]); +} + +inline <T>* <T>IChunk::succ(<T>* p) const +{ + return ((p+1) < &(data[low - base]) || (p+1) >= &(data[fence - base])) ? + 0 : (p+1); +} + +inline <T>* <T>IChunk::pred(<T>* p) const +{ + return ((p-1) < &(data[low - base]) || (p-1) >= &(data[fence - base])) ? + 0 : (p-1); +} + + +// generic Plex operations + +inline <T>Plex::<T>Plex() {} + +inline int <T>Plex::chunk_size() const +{ + return csize; +} + +inline int <T>Plex::ecnef () const +{ + return lo - 1; +} + + +inline int <T>Plex::fence () const +{ + return fnc; +} + +inline int <T>Plex::length () const +{ + return fnc - lo; +} + +inline int <T>Plex::empty () const +{ + return fnc == lo; +} + +inline <T>IChunk* <T>Plex::tl() const +{ + return hd->prev(); +} + +inline int <T>Plex::one_chunk() const +{ + return hd == hd->prev(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Queue.ccP b/gnu/lib/libg++/g++-include/gen/Queue.ccP new file mode 100644 index 000000000000..fb48d952ff71 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Queue.ccP @@ -0,0 +1,14 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.Queue.h" + +<T>Queue::~<T>Queue() {} + + +// error handling + +void <T>Queue::error(const char* msg) +{ + (*lib_error_handler)("Queue", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Queue.hP b/gnu/lib/libg++/g++-include/gen/Queue.hP new file mode 100644 index 000000000000..73db6e034eb2 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Queue.hP @@ -0,0 +1,51 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>Queue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>Queue_h + +#include <builtin.h> + +#include "<T>.defs.h" + +class <T>Queue +{ +public: + <T>Queue() { } + virtual ~<T>Queue(); + + virtual void enq(<T&> item) = 0; + virtual <T> deq() = 0; + virtual <T>& front() = 0; + virtual void del_front() = 0; + + virtual void clear() = 0; + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + + void error(const char*); + + virtual int OK() = 0; +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP b/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP new file mode 100644 index 000000000000..7537dd07884d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP @@ -0,0 +1,690 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.<C>.RAVLMap.h" + + +/* + constants & inlines for maintaining balance & thread status in tree nodes +*/ + +#define AVLBALANCEMASK 3 +#define AVLBALANCED 0 +#define AVLLEFTHEAVY 1 +#define AVLRIGHTHEAVY 2 + +#define LTHREADBIT 4 +#define RTHREADBIT 8 + + +static inline int bf(<T><C>RAVLNode* t) +{ + return t->stat & AVLBALANCEMASK; +} + +static inline void set_bf(<T><C>RAVLNode* t, int b) +{ + t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK); +} + + +static inline int rthread(<T><C>RAVLNode* t) +{ + return t->stat & RTHREADBIT; +} + +static inline void set_rthread(<T><C>RAVLNode* t, int b) +{ + if (b) + t->stat |= RTHREADBIT; + else + t->stat &= ~RTHREADBIT; +} + +static inline int lthread(<T><C>RAVLNode* t) +{ + return t->stat & LTHREADBIT; +} + +static inline void set_lthread(<T><C>RAVLNode* t, int b) +{ + if (b) + t->stat |= LTHREADBIT; + else + t->stat &= ~LTHREADBIT; +} + +/* + traversal primitives +*/ + + +<T><C>RAVLNode* <T><C>RAVLMap::leftmost() +{ + <T><C>RAVLNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T><C>RAVLNode* <T><C>RAVLMap::rightmost() +{ + <T><C>RAVLNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T><C>RAVLNode* <T><C>RAVLMap::succ(<T><C>RAVLNode* t) +{ + <T><C>RAVLNode* r = t->rt; + if (!rthread(t)) while (!lthread(r)) r = r->lt; + return r; +} + +<T><C>RAVLNode* <T><C>RAVLMap::pred(<T><C>RAVLNode* t) +{ + <T><C>RAVLNode* l = t->lt; + if (!lthread(t)) while (!rthread(l)) l = l->rt; + return l; +} + + +Pix <T><C>RAVLMap::seek(<T&> key) +{ + <T><C>RAVLNode* t = root; + if (t == 0) + return 0; + for (;;) + { + int cmp = <T>CMP(key, t->item); + if (cmp == 0) + return Pix(t); + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + t = t->lt; + } + else if (rthread(t)) + return 0; + else + t = t->rt; + } +} + + +int <T><C>RAVLMap::rankof(<T&> key) +{ + int r; + <T><C>RAVLNode* t = root; + if (t == 0) + return 0; + for (r=t->rank; t != 0; r+=t->rank) + { + int cmp = <T>CMP(key, t->item); + if (cmp == 0) + return r; + else if (cmp < 0) + { + if (lthread(t)) + return 0; + else + { + r -= t->rank; + t = t->lt; + } + } + else if (rthread(t)) + return 0; + else + { + t = t->rt; + } + } + return 0; +} + +Pix <T><C>RAVLMap::ranktoPix(int i) +{ + int r; + <T><C>RAVLNode* t = root; + + if ((i<1)||(i>count)) + return 0; + for (r=t->rank; r!=i; r+=t->rank) + { + if (r>i) + { + r -= t->rank; + t = t->lt; + } + else + t = t->rt; + } + return Pix(t); +} + +/* + The combination of threads and AVL bits make adding & deleting + interesting, but very awkward. + + We use the following statics to avoid passing them around recursively +*/ + +static int _need_rebalancing; // to send back balance info from rec. calls +static <T>* _target_item; // add/del_item target +static <T><C>RAVLNode* _found_node; // returned added/deleted node +static int _already_found; // for deletion subcases +static int _rank_changed; // for rank computation + + +void <T><C>RAVLMap:: _add(<T><C>RAVLNode*& t) +{ + int cmp = <T>CMP(*_target_item, t->item); + if (cmp == 0) + { + _found_node = t; + return; + } + else if (cmp < 0) + { + if (lthread(t)) + { + ++count; + _found_node = new <T><C>RAVLNode(*_target_item, def); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t->lt; + _found_node->rt = t; + t->lt = _found_node; + set_lthread(t, 0); + _need_rebalancing = 1; + _rank_changed = 1; + } + else + _add(t->lt); + if (_rank_changed) ++t->rank; + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + return; + case AVLLEFTHEAVY: + { + <T><C>RAVLNode* l = t->lt; + if (bf(l) == AVLLEFTHEAVY) + { + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + } + else + { + <T><C>RAVLNode* r = l->rt; + r->rank += l->rank; + t->rank -= r->rank; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + return; + } + } + } + } + } + else + { + if (rthread(t)) + { + ++count; + _found_node = new <T><C>RAVLNode(*_target_item, def); + set_rthread(t, 0); + set_lthread(_found_node, 1); + set_rthread(_found_node, 1); + _found_node->lt = t; + _found_node->rt = t->rt; + t->rt = _found_node; + _need_rebalancing = 1; + _rank_changed = 1; + } + else + _add(t->rt); + if (_need_rebalancing) + { + switch(bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + _need_rebalancing = 0; + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + return; + case AVLRIGHTHEAVY: + { + <T><C>RAVLNode* r = t->rt; + if (bf(r) == AVLRIGHTHEAVY) + { + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + _need_rebalancing = 0; + } + else + { + <T><C>RAVLNode* l = r->lt; + r->rank -= l->rank; + l->rank += t->rank; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + _need_rebalancing = 0; + return; + } + } + } + } + } +} + + +<C>& <T><C>RAVLMap::operator [] (<T&> item) +{ + if (root == 0) + { + ++count; + root = new <T><C>RAVLNode(item, def); + set_rthread(root, 1); + set_lthread(root, 1); + return root->cont; + } + else + { + _target_item = &item; + _need_rebalancing = 0; + _rank_changed = 0; + _add(root); + return _found_node->cont; + } +} + + +void <T><C>RAVLMap::_del(<T><C>RAVLNode* par, <T><C>RAVLNode*& t) +{ + int comp; + if (_already_found) + { + if (rthread(t)) + comp = 0; + else + comp = 1; + } + else + comp = <T>CMP(*_target_item, t->item); + if (comp == 0) + { + if (lthread(t) && rthread(t)) + { + _found_node = t; + if (t == par->lt) + { + set_lthread(par, 1); + par->lt = t->lt; + } + else + { + set_rthread(par, 1); + par->rt = t->rt; + } + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else if (lthread(t)) + { + _found_node = t; + <T><C>RAVLNode* s = succ(t); + if (s != 0 && lthread(s)) + s->lt = t->lt; + t = t->rt; + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else if (rthread(t)) + { + _found_node = t; + <T><C>RAVLNode* p = pred(t); + if (p != 0 && rthread(p)) + p->rt = t->rt; + t = t->lt; + _need_rebalancing = 1; + _rank_changed = 1; + return; + } + else // replace item & find someone deletable + { + <T><C>RAVLNode* p = pred(t); + t->item = p->item; + t->cont = p->cont; + _already_found = 1; + comp = -1; // fall through below to left + } + } + + if (comp < 0) + { + if (lthread(t)) + return; + _del(t, t->lt); + if (_rank_changed) --t->rank; + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLLEFTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLRIGHTHEAVY); + _need_rebalancing = 0; + return; + case AVLRIGHTHEAVY: + { + <T><C>RAVLNode* r = t->rt; + switch (bf(r)) + { + case AVLBALANCED: + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLRIGHTHEAVY); + set_bf(r, AVLLEFTHEAVY); + _need_rebalancing = 0; + t = r; + return; + case AVLRIGHTHEAVY: + r->rank += t->rank; + if (lthread(r)) + t->rt = r; + else + t->rt = r->lt; + set_rthread(t, lthread(r)); + r->lt = t; + set_lthread(r, 0); + set_bf(t, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + case AVLLEFTHEAVY: + { + <T><C>RAVLNode* l = r->lt; + r->rank -= l->rank; + l->rank += t->rank; + set_lthread(r, rthread(l)); + if (rthread(l)) + r->lt = l; + else + r->lt = l->rt; + l->rt = r; + set_rthread(l, 0); + set_rthread(t, lthread(l)); + if (lthread(l)) + t->rt = l; + else + t->rt = l->lt; + l->lt = t; + set_lthread(l, 0); + if (bf(l) == AVLRIGHTHEAVY) + set_bf(t, AVLLEFTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(l) == AVLLEFTHEAVY) + set_bf(r, AVLRIGHTHEAVY); + else + set_bf(r, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + } + } + } + } + } + else + { + if (rthread(t)) + return; + _del(t, t->rt); + if (!_need_rebalancing) + return; + switch (bf(t)) + { + case AVLRIGHTHEAVY: + set_bf(t, AVLBALANCED); + return; + case AVLBALANCED: + set_bf(t, AVLLEFTHEAVY); + _need_rebalancing = 0; + return; + case AVLLEFTHEAVY: + { + <T><C>RAVLNode* l = t->lt; + switch (bf(l)) + { + case AVLBALANCED: + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLLEFTHEAVY); + set_bf(l, AVLRIGHTHEAVY); + _need_rebalancing = 0; + t = l; + return; + case AVLLEFTHEAVY: + t->rank -= l->rank; + if (rthread(l)) + t->lt = l; + else + t->lt = l->rt; + set_lthread(t, rthread(l)); + l->rt = t; + set_rthread(l, 0); + set_bf(t, AVLBALANCED); + set_bf(l, AVLBALANCED); + t = l; + return; + case AVLRIGHTHEAVY: + { + <T><C>RAVLNode* r = l->rt; + r->rank += l->rank; + t->rank -= r->rank; + set_rthread(l, lthread(r)); + if (lthread(r)) + l->rt = r; + else + l->rt = r->lt; + r->lt = l; + set_lthread(r, 0); + set_lthread(t, rthread(r)); + if (rthread(r)) + t->lt = r; + else + t->lt = r->rt; + r->rt = t; + set_rthread(r, 0); + if (bf(r) == AVLLEFTHEAVY) + set_bf(t, AVLRIGHTHEAVY); + else + set_bf(t, AVLBALANCED); + if (bf(r) == AVLRIGHTHEAVY) + set_bf(l, AVLLEFTHEAVY); + else + set_bf(l, AVLBALANCED); + set_bf(r, AVLBALANCED); + t = r; + return; + } + } + } + } + } +} + + +void <T><C>RAVLMap::del(<T&> item) +{ + if (root == 0) return; + _need_rebalancing = 0; + _already_found = 0; + _found_node = 0; + _rank_changed = 0; + _target_item = &item; + _del(root, root); + if (_found_node) + { + delete(_found_node); + if (--count == 0) + root = 0; + } +} + +void <T><C>RAVLMap::_kill(<T><C>RAVLNode* t) +{ + if (t != 0) + { + if (!lthread(t)) _kill(t->lt); + if (!rthread(t)) _kill(t->rt); + delete t; + } +} + + +<T><C>RAVLMap::<T><C>RAVLMap(<T><C>RAVLMap& b) :<T><C>Map(b.def) +{ + root = 0; + count = 0; + for (Pix i = b.first(); i != 0; b.next(i)) + (*this)[b.key(i)] = b.contents(i); +} + + +int <T><C>RAVLMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T><C>RAVLNode* trail = leftmost(); + v &= rankof(trail->item) == n; + <T><C>RAVLNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + v &= rankof(t->item) == n; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/RAVLMap.hP b/gnu/lib/libg++/g++-include/gen/RAVLMap.hP new file mode 100644 index 000000000000..d3c523ee2978 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RAVLMap.hP @@ -0,0 +1,147 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + ranking code from Paul Anderson (paul%lfcs.ed.ac.uk) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T><C>RAVLMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T><C>RAVLMap_h 1 + +#include "<T>.<C>.Map.h" + +struct <T><C>RAVLNode +{ + <T><C>RAVLNode* lt; + <T><C>RAVLNode* rt; + <T> item; + <C> cont; + int rank; + char stat; + <T><C>RAVLNode(<T&> h, <C&> c, + <T><C>RAVLNode* l=0, <T><C>RAVLNode* r=0, int k=1); + ~<T><C>RAVLNode(); +}; + +inline <T><C>RAVLNode::<T><C>RAVLNode(<T&> h, <C&> c, + <T><C>RAVLNode* l, <T><C>RAVLNode* r, int k) + :item(h), cont(c), lt(l), rt(r), rank(k), stat(0) {} + +inline <T><C>RAVLNode::~<T><C>RAVLNode() {} + +typedef <T><C>RAVLNode* <T><C>RAVLNodePtr; + + +class <T><C>RAVLMap : public <T><C>Map +{ +protected: + <T><C>RAVLNode* root; + + <T><C>RAVLNode* leftmost(); + <T><C>RAVLNode* rightmost(); + <T><C>RAVLNode* pred(<T><C>RAVLNode* t); + <T><C>RAVLNode* succ(<T><C>RAVLNode* t); + void _kill(<T><C>RAVLNode* t); + void _add(<T><C>RAVLNode*& t); + void _del(<T><C>RAVLNode* p, <T><C>RAVLNode*& t); + +public: + <T><C>RAVLMap(<C&> dflt); + <T><C>RAVLMap(<T><C>RAVLMap& a); + ~<T><C>RAVLMap(); + + <C>& operator [] (<T&> key); + + void del(<T&> key); + + Pix first(); + void next(Pix& i); + <T>& key(Pix i); + <C>& contents(Pix i); + + Pix seek(<T&> key); + int contains(<T&> key); + + Pix ranktoPix(int i); + int rankof(<T&> key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline <T><C>RAVLMap::~<T><C>RAVLMap() +{ + _kill(root); +} + +inline <T><C>RAVLMap::<T><C>RAVLMap(<C&> dflt) :<T><C>Map(dflt) +{ + root = 0; +} + + +inline Pix <T><C>RAVLMap::first() +{ + return Pix(leftmost()); +} + +inline Pix <T><C>RAVLMap::last() +{ + return Pix(rightmost()); +} + +inline void <T><C>RAVLMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T><C>RAVLNode*)i)); +} + +inline void <T><C>RAVLMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T><C>RAVLNode*)i)); +} + +inline <T>& <T><C>RAVLMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>RAVLNode*)i)->item; +} + +inline <C>& <T><C>RAVLMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>RAVLNode*)i)->cont; +} + +inline void <T><C>RAVLMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T><C>RAVLMap::contains(<T&> key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/RPlex.ccP b/gnu/lib/libg++/g++-include/gen/RPlex.ccP new file mode 100644 index 000000000000..0dbd2cee7e49 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RPlex.ccP @@ -0,0 +1,477 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.RPlex.h" + +typedef <T>IChunk* _<T>IChunk_ptr; + +<T>RPlex:: <T>RPlex() +{ + lo = fnc = 0; + csize = DEFAULT_INITIAL_CAPACITY; + <T>* data = new <T>[csize]; + set_cache(new <T>IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _<T>IChunk_ptr[maxch]; + chunks[lch] = ch; +} + +<T>RPlex:: <T>RPlex(int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = 0; + if (chunksize > 0) + { + csize = chunksize; + <T>* data = new <T>[csize]; + set_cache(new <T>IChunk(data, lo, lo, fnc, csize+lo)); + hd = ch; + } + else + { + csize = -chunksize; + <T>* data = new <T>[csize]; + set_cache(new <T>IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _<T>IChunk_ptr[maxch]; + chunks[lch] = ch; +} + + +<T>RPlex:: <T>RPlex(int l, int chunksize) +{ + if (chunksize == 0) error("invalid constructor specification"); + lo = fnc = l; + if (chunksize > 0) + { + csize = chunksize; + <T>* data = new <T>[csize]; + set_cache(new <T>IChunk(data, lo, lo, fnc, lo+csize)); + hd = ch; + } + else + { + csize = -chunksize; + <T>* data = new <T>[csize]; + set_cache(new <T>IChunk(data, chunksize+lo, lo, fnc, fnc)); + hd = ch; + } + maxch = MIN_NCHUNKS; + lch = maxch / 2; + fch = lch + 1; + base = ch->base_index() - lch * csize; + chunks = new _<T>IChunk_ptr[maxch]; + chunks[lch] = ch; +} + +void <T>RPlex::make_initial_chunks(int up) +{ + int count = 0; + int need = fnc - lo; + hd = 0; + if (up) + { + int l = lo; + do + { + ++count; + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + <T>* data = new <T> [csize]; + <T>IChunk* h = new <T>IChunk(data, l, l, l+sz, l+csize); + if (hd != 0) + h->link_to_next(hd); + else + hd = h; + l += sz; + need -= sz; + } while (need > 0); + } + else + { + int hi = fnc; + do + { + ++count; + int sz; + if (need >= csize) + sz = csize; + else + sz = need; + <T>* data = new <T> [csize]; + <T>IChunk* h = new <T>IChunk(data, hi-csize, hi-sz, hi, hi); + if (hd != 0) + h->link_to_next(hd); + hd = h; + hi -= sz; + need -= sz; + } while (need > 0); + } + set_cache((<T>IChunk*)hd); + + maxch = MIN_NCHUNKS; + if (maxch < count * 2) + maxch = count * 2; + chunks = new _<T>IChunk_ptr[maxch]; + lch = maxch / 3; + fch = lch + count; + base = ch->base_index() - csize * lch; + int k = lch; + do + { + chunks[k++] = ch; + set_cache(ch->next()); + } while (ch != hd); +} + +<T>RPlex:: <T>RPlex(int l, int hi, const <T&> initval, int chunksize) +{ + lo = l; + fnc = hi + 1; + if (chunksize == 0) + { + csize = fnc - l; + make_initial_chunks(1); + } + else if (chunksize < 0) + { + csize = -chunksize; + make_initial_chunks(0); + } + else + { + csize = chunksize; + make_initial_chunks(1); + } + fill(initval); +} + +<T>RPlex::<T>RPlex(const <T>RPlex& a) +{ + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; +} + +void <T>RPlex::operator= (const <T>RPlex& a) +{ + if (&a != this) + { + invalidate(); + lo = a.lo; + fnc = a.fnc; + csize = a.csize; + make_initial_chunks(); + for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i]; + } +} + + +void <T>RPlex::cache(const <T>* p) const +{ + const <T>IChunk* old = ch; + const <T>IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) index_error(); + } + set_cache(t); +} + +int <T>RPlex::owns(Pix px) const +{ + <T>* p = (<T>*)px; + const <T>IChunk* old = ch; + const <T>IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + set_cache(t); + return 1; +} + + +<T>* <T>RPlex::dosucc(const <T>* p) const +{ + if (p == 0) return 0; + const <T>IChunk* old = ch; + const <T>IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->next()); + if (t == old) return 0; + } + int i = t->index_of(p) + 1; + if (i >= fnc) return 0; + if (i >= t->fence_index()) t = (t->next()); + set_cache(t); + return t->pointer_to(i); +} + +<T>* <T>RPlex::dopred(const <T>* p) const +{ + if (p == 0) return 0; + const <T>IChunk* old = ch; + const <T>IChunk* t = ch; + while (!t->actual_pointer(p)) + { + t = (t->prev()); + if (t == old) return 0; + } + int i = t->index_of(p) - 1; + if (i < lo) return 0; + if (i < t->low_index()) t = (t->prev()); + set_cache(t); + return (t->pointer_to(i)); +} + +int <T>RPlex::add_high(const <T&> elem) +{ + <T>IChunk* t = tl(); + if (!t->can_grow_high()) + { + if (t-><T>IChunk::empty() && one_chunk()) + { + t->clear(fnc); + base = t->base_index() - lch * csize; + } + else + { + <T>* data = new <T> [csize]; + t = (new <T>IChunk(data, fnc, fnc, fnc,fnc+csize)); + t->link_to_prev(tl()); + if (fch == maxch) + { + maxch *= 2; + <T>IChunk** newch = new _<T>IChunk_ptr [maxch]; + memcpy(newch, chunks, fch * sizeof(_<T>IChunk_ptr)); + delete chunks; + chunks = newch; + } + chunks[fch++] = t; + } + } + *((t-><T>IChunk::grow_high())) = elem; + set_cache(t); + return fnc++; +} + +int <T>RPlex::del_high () +{ + if (empty()) empty_error(); + <T>IChunk* t = tl(); + if (t-><T>IChunk::empty()) // kill straggler first + { + <T>IChunk* pred = t->prev(); + del_chunk(t); + t = (pred); + --fch; + } + t-><T>IChunk::shrink_high(); + if (t-><T>IChunk::empty() && !one_chunk()) + { + <T>IChunk* pred = t->prev(); + del_chunk(t); + t = (pred); + --fch; + } + set_cache(t); + return --fnc - 1; +} + +int <T>RPlex::add_low (const <T&> elem) +{ + <T>IChunk* t = hd; + if (!t->can_grow_low()) + { + if (t-><T>IChunk::empty() && one_chunk()) + { + t->cleardown(lo); + base = t->base_index() - lch * csize; + } + else + { + <T>* data = new <T> [csize]; + hd = new <T>IChunk(data, lo-csize, lo, lo, lo); + hd->link_to_next(t); + t = ( hd); + if (lch == 0) + { + lch = maxch; + fch += maxch; + maxch *= 2; + <T>IChunk** newch = new _<T>IChunk_ptr [maxch]; + memcpy(&(newch[lch]), chunks, lch * sizeof(_<T>IChunk_ptr)); + delete chunks; + chunks = newch; + base = t->base_index() - (lch - 1) * csize; + } + chunks[--lch] = t; + } + } + *((t-><T>IChunk::grow_low())) = elem; + set_cache(t); + return --lo; +} + + +int <T>RPlex::del_low () +{ + if (empty()) empty_error(); + <T>IChunk* t = hd; + if (t-><T>IChunk::empty()) + { + hd = t->next(); + del_chunk(t); + t = hd; + ++lch; + } + t-><T>IChunk::shrink_low(); + if (t-><T>IChunk::empty() && !one_chunk()) + { + hd = t->next(); + del_chunk(t); + t = hd; + ++lch; + } + set_cache(t); + return ++lo; +} + +void <T>RPlex::reverse() +{ + <T> tmp; + int l = lo; + int h = fnc - 1; + <T>IChunk* loch = hd; + <T>IChunk* hich = tl(); + while (l < h) + { + <T>* lptr = loch->pointer_to(l); + <T>* hptr = hich->pointer_to(h); + tmp = *lptr; + *lptr = *hptr; + *hptr = tmp; + if (++l >= loch->fence_index()) loch = loch->next(); + if (--h < hich->low_index()) hich = hich->prev(); + } +} + +void <T>RPlex::fill(const <T&> x) +{ + for (int i = lo; i < fnc; ++i) (*this)[i] = x; +} + +void <T>RPlex::fill(const <T&> x, int lo, int hi) +{ + for (int i = lo; i <= hi; ++i) (*this)[i] = x; +} + + +void <T>RPlex::clear() +{ + for (int i = lch + 1; i < fch; ++i) + del_chunk(chunks[i]); + fch = lch + 1; + set_cache(chunks[lch]); + ch-><T>IChunk::clear(lo); + fnc = lo; +} + +int <T>RPlex::reset_low(int l) +{ + int old = lo; + int diff = l - lo; + if (diff != 0) + { + lo += diff; + fnc += diff; + <T>IChunk* t = hd; + do + { + t->re_index(t->low_index() + diff); + t = t->next(); + } while (t != hd); + } + base = hd->base_index() - lch * csize; + return old; +} + + +int <T>RPlex::OK () const +{ + int v = hd != 0 && ch != 0; // at least one chunk + + v &= fnc == tl()->fence_index(); // last chunk fnc == plex fnc + v &= lo == hd-><T>IChunk::low_index(); // first lo == plex lo + + v &= base == hd->base_index() - lch * csize; // base is correct; + v &= lch < fch; + v &= fch <= maxch; // within allocation; + +// loop for others: + + int k = lch; // to cross-check nch + + int found_ch = 0; // to make sure ch is in list; + const <T>IChunk* t = (hd); + for (;;) + { + v &= chunks[k++] == t; // each chunk is at proper index + if (t == ch) ++found_ch; + v &= t-><T>IChunk::OK(); // each chunk is OK + if (t == tl()) + break; + else // and has indices contiguous to succ + { + v &= t->top_index() == t->next()->base_index(); + if (t != hd) // internal chunks full + { + v &= !t->empty(); + v &= !t->can_grow_low(); + v &= !t->can_grow_high(); + } + t = t->next(); + } + } + v &= found_ch == 1; + v &= fch == k; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/RPlex.hP b/gnu/lib/libg++/g++-include/gen/RPlex.hP new file mode 100644 index 000000000000..ed28c357e4d1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/RPlex.hP @@ -0,0 +1,257 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Marc Shapiro (shapiro@sor.inria.fr) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _<T>RPlex_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>RPlex_h 1 + +#include "<T>.Plex.h" + +// minimum number of chunks to index + +#ifndef MIN_NCHUNKS +#define MIN_NCHUNKS 16 +#endif + +class <T>RPlex: public <T>Plex +{ + int base; // base index of lowest chunk + int lch; // index of lowest used chunk + int fch; // 1 + index of highest used chunk + int maxch; // max chunks in array + <T>IChunk** chunks; // array of chunks + <T>IChunk* ch; // cached chunk + + void make_initial_chunks(int up = 1); + + void cache(int idx) const; + void cache(const <T>* p) const; + <T>* dopred(const <T>* p) const; + <T>* dosucc(const <T>* p) const; + + void set_cache(const <T>IChunk* t) const; // logically, + // not physically const + +public: + <T>RPlex(); // set low = 0; + // fence = 0; + // csize = default + + <T>RPlex(int ch_size); // low = 0; + // fence = 0; + // csize = ch_size + + <T>RPlex(int lo, // low = lo; + int ch_size); // fence=lo + // csize = ch_size + + <T>RPlex(int lo, // low = lo + int hi, // fence = hi+1 + const <T&> initval,// fill with initval, + int ch_size = 0); // csize= ch_size + // or fence-lo if 0 + + <T>RPlex(const <T>RPlex&); + + ~<T>RPlex(); + + void operator= (const <T>RPlex&); + +// virtuals + + <T>& high_element (); + <T>& low_element (); + + const <T>& high_element () const; + const <T>& low_element () const; + + Pix first() const; + Pix last() const; + void prev(Pix& ptr) const; + void next(Pix& ptr) const; + int owns(Pix p) const; + <T>& operator () (Pix p); + const <T>& operator () (Pix p) const; + + int low() const; + int high() const; + int valid(int idx) const; + void prev(int& idx) const; + void next(int& x) const; + <T>& operator [] (int index); + const <T>& operator [] (int index) const; + + int Pix_to_index(Pix p) const; + Pix index_to_Pix(int idx) const; + + int can_add_high() const; + int can_add_low() const; + int full() const; + + int add_high(const <T&> elem); + int del_high (); + int add_low (const <T&> elem); + int del_low (); + + void fill(const <T&> x); + void fill(const <T&> x, int from, int to); + void clear(); + void reverse(); + + int reset_low(int newlow); + + int OK () const; +}; + + +inline void <T>RPlex::prev(int& idx) const +{ + --idx; +} + +inline void <T>RPlex::next(int& idx) const +{ + ++idx; +} + +inline int <T>RPlex::full () const +{ + return 0; +} + +inline int <T>RPlex::can_add_high() const +{ + return 1; +} + +inline int <T>RPlex::can_add_low() const +{ + return 1; +} + +inline int <T>RPlex::valid (int idx) const +{ + return idx >= lo && idx < fnc; +} + +inline int <T>RPlex::low() const +{ + return lo; +} + +inline int <T>RPlex::high() const +{ + return fnc - 1; +} + +inline void <T>RPlex::set_cache(const <T>IChunk* t) const +{ + ((<T>RPlex*)(this))->ch = (<T>IChunk*)t; +} + +inline void <T>RPlex::cache(int idx) const +{ + if (idx < lo || idx >= fnc) index_error(); + set_cache(chunks[(idx - base) / csize]); +} + +inline <T>& <T>RPlex::low_element () +{ + cache(lo); return *(ch->pointer_to(lo)); +} + +inline <T>& <T>RPlex::high_element () +{ + cache(fnc-1); return *(ch->pointer_to(fnc - 1)); +} + +inline const <T>& <T>RPlex::low_element () const +{ + cache(lo); return *((const <T>*)(ch->pointer_to(lo))); +} + +inline const <T>& <T>RPlex::high_element () const +{ + cache(fnc-1); return *((const <T>*)(ch->pointer_to(fnc - 1))); +} + +inline int <T>RPlex::Pix_to_index(Pix px) const +{ + <T>* p = (<T>*)px; + if (!ch->actual_pointer(p)) cache(p); + return ch->index_of(p); +} + +inline Pix <T>RPlex::index_to_Pix(int idx) const +{ + if (!ch->actual_index(idx)) cache(idx); + return (Pix)(ch->pointer_to(idx)); +} + +inline Pix <T>RPlex::first() const +{ + return Pix(hd-><T>IChunk::first_pointer()); +} + +inline Pix <T>RPlex::last() const +{ + return Pix(tl()-><T>IChunk::last_pointer()); +} + +inline void <T>RPlex::prev(Pix& p) const +{ + Pix q = Pix(ch-><T>IChunk::pred((<T>*)p)); + p = (q == 0)? Pix(dopred((<T>*)p)) : q; +} + +inline void <T>RPlex::next(Pix& p) const +{ + Pix q = Pix(ch-><T>IChunk::succ((<T>*)p)); + p = (q == 0)? Pix(dosucc((<T>*)p)) : q; +} + +inline <T>& <T>RPlex:: operator () (Pix p) +{ + return *((<T>*)p); +} + + +inline <T>& <T>RPlex:: operator [] (int idx) +{ + cache(idx); return *(ch->pointer_to(idx)); +} + +inline const <T>& <T>RPlex:: operator () (Pix p) const +{ + return *((const <T>*)p); +} + +inline const <T>& <T>RPlex:: operator [] (int idx) const +{ + cache(idx); return *((const <T>*)(ch->pointer_to(idx))); +} + +inline <T>RPlex::~<T>RPlex() +{ + delete chunks; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLBag.ccP b/gnu/lib/libg++/g++-include/gen/SLBag.ccP new file mode 100644 index 000000000000..50d2447c7d29 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLBag.ccP @@ -0,0 +1,105 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.SLBag.h" + +int <T>SLBag::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix <T>SLBag::seek(<T&> item, Pix i) +{ + if (i == 0) i = first(); else next(i); + for (; i != 0 && (!(<T>EQ(p(i), item))); p.next(i)); + return i; +} + +int <T>SLBag::nof(<T&> item) +{ + int n = 0; + for (Pix p = first(); p; next(p)) if (<T>EQ((*this)(p), item)) ++n; + return n; +} + + +void <T>SLBag::del(<T&> item) +{ + Pix i = p.first(); + if (i == 0) + return; + else if (<T>EQ(p(i), item)) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (<T>EQ(p(i), item)) + { + --count; + p.del_after(trail); + return; + } + trail = i; + p.next(i); + } + } +} + +void <T>SLBag::remove(<T&> item) +{ + Pix i = p.first(); + while (i != 0 && <T>EQ(p(i), item)) + { + --count; + p.del_front(); + i = p.first(); + } + if (i != 0) + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (<T>EQ(p(i), item)) + { + --count; + p.del_after(trail); + i = trail; + p.next(i); + } + else + { + trail = i; + p.next(i); + } + } + } +} + diff --git a/gnu/lib/libg++/g++-include/gen/SLBag.hP b/gnu/lib/libg++/g++-include/gen/SLBag.hP new file mode 100644 index 000000000000..edb648e9d3a2 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLBag.hP @@ -0,0 +1,96 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>SLBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SLBag_h 1 + +#include "<T>.Bag.h" +#include "<T>.SLList.h" + +class <T>SLBag : public <T>Bag +{ +protected: + <T>SLList p; + +public: + <T>SLBag(); + <T>SLBag(const <T>SLBag&); + + Pix add(<T&> item); + void del(<T&> item); + void remove(<T&>item); + int contains(<T&> item); + int nof(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + int owns(Pix i); + Pix seek(<T&> item, Pix from = 0); + + int OK(); +}; + + +inline <T>SLBag::<T>SLBag() : p() { count = 0; } + +inline <T>SLBag::<T>SLBag(const <T>SLBag& s) : p(s.p) { count = s.count; } + +inline Pix <T>SLBag::first() +{ + return p.first(); +} + +inline void <T>SLBag::next(Pix & idx) +{ + p.next(idx); +} + +inline <T>& <T>SLBag::operator ()(Pix idx) +{ + return p(idx); +} + +inline void <T>SLBag::clear() +{ + count = 0; p.clear(); +} + +inline int <T>SLBag::owns (Pix idx) +{ + return p.owns(idx); +} + +inline Pix <T>SLBag::add(<T&> item) +{ + ++count; + return p.append(item); +} + +inline int <T>SLBag::contains(<T&> item) +{ + return seek(item) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLList.ccP b/gnu/lib/libg++/g++-include/gen/SLList.ccP new file mode 100644 index 000000000000..3ebd8d5bc98d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLList.ccP @@ -0,0 +1,292 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../SLList.cc, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <values.h> +#include <stream.h> +#include <builtin.h> +#include "<T>.SLList.h" + +void <T>SLList::error(const char* msg) +{ + (*lib_error_handler)("SLList", msg); +} + +int <T>SLList::length() +{ + int l = 0; + <T>SLListNode* t = last; + if (t != 0) do { ++l; t = t->tl; } while (t != last); + return l; +} + +<T>SLList::<T>SLList(const <T>SLList& a) +{ + if (a.last == 0) + last = 0; + else + { + <T>SLListNode* p = a.last->tl; + <T>SLListNode* h = new <T>SLListNode(p->hd); + last = h; + for (;;) + { + if (p == a.last) + { + last->tl = h; + return; + } + p = p->tl; + <T>SLListNode* n = new <T>SLListNode(p->hd); + last->tl = n; + last = n; + } + } +} + +<T>SLList& <T>SLList::operator = (const <T>SLList& a) +{ + if (last != a.last) + { + clear(); + if (a.last != 0) + { + <T>SLListNode* p = a.last->tl; + <T>SLListNode* h = new <T>SLListNode(p->hd); + last = h; + for (;;) + { + if (p == a.last) + { + last->tl = h; + break; + } + p = p->tl; + <T>SLListNode* n = new <T>SLListNode(p->hd); + last->tl = n; + last = n; + } + } + } + return *this; +} + +void <T>SLList::clear() +{ + if (last == 0) + return; + + <T>SLListNode* p = last->tl; + last->tl = 0; + last = 0; + + while (p != 0) + { + <T>SLListNode* nxt = p->tl; + delete(p); + p = nxt; + } +} + + +Pix <T>SLList::prepend(<T&> item) +{ + <T>SLListNode* t = new <T>SLListNode(item); + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + } + return Pix(t); +} + + +Pix <T>SLList::prepend(<T>SLListNode* t) +{ + if (t == 0) return 0; + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + } + return Pix(t); +} + + +Pix <T>SLList::append(<T&> item) +{ + <T>SLListNode* t = new <T>SLListNode(item); + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + last = t; + } + return Pix(t); +} + +Pix <T>SLList::append(<T>SLListNode* t) +{ + if (t == 0) return 0; + if (last == 0) + t->tl = last = t; + else + { + t->tl = last->tl; + last->tl = t; + last = t; + } + return Pix(t); +} + +void <T>SLList::join(<T>SLList& b) +{ + <T>SLListNode* t = b.last; + b.last = 0; + if (last == 0) + last = t; + else if (t != 0) + { + <T>SLListNode* f = last->tl; + last->tl = t->tl; + t->tl = f; + last = t; + } +} + +Pix <T>SLList::ins_after(Pix p, <T&> item) +{ + <T>SLListNode* u = (<T>SLListNode*)p; + <T>SLListNode* t = new <T>SLListNode(item); + if (last == 0) + t->tl = last = t; + else if (u == 0) // ins_after 0 means prepend + { + t->tl = last->tl; + last->tl = t; + } + else + { + t->tl = u->tl; + u->tl = t; + if (u == last) + last = t; + } + return Pix(t); +} + + +void <T>SLList::del_after(Pix p) +{ + <T>SLListNode* u = (<T>SLListNode*)p; + if (last == 0 || u == last) error("cannot del_after last"); + if (u == 0) u = last; // del_after 0 means delete first + <T>SLListNode* t = u->tl; + if (u == t) + last = 0; + else + { + u->tl = t->tl; + if (last == t) + last = u; + } + delete t; +} + +int <T>SLList::owns(Pix p) +{ + <T>SLListNode* t = last; + if (t != 0 && p != 0) + { + do + { + if (Pix(t) == p) return 1; + t = t->tl; + } while (t != last); + } + return 0; +} + +<T> <T>SLList::remove_front() +{ + if (last == 0) error("remove_front of empty list"); + <T>SLListNode* t = last->tl; + <T> res = t->hd; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; + return res; +} + +int <T>SLList::remove_front(<T>& x) +{ + if (last == 0) + return 0; + else + { + <T>SLListNode* t = last->tl; + x = t->hd; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; + return 1; + } +} + + +void <T>SLList::del_front() +{ + if (last == 0) error("del_front of empty list"); + <T>SLListNode* t = last->tl; + if (t == last) + last = 0; + else + last->tl = t->tl; + delete t; +} + +int <T>SLList::OK() +{ + int v = 1; + if (last != 0) + { + <T>SLListNode* t = last; + long count = MAXLONG; // Lots of chances to find last! + do + { + count--; + t = t->tl; + } while (count > 0 && t != last); + v &= count > 0; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SLList.hP b/gnu/lib/libg++/g++-include/gen/SLList.hP new file mode 100644 index 000000000000..e5570bdf8fec --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLList.hP @@ -0,0 +1,137 @@ +// This may look like C code, but it is really -*- C++ -*- +// WARNING: This file is obsolete. Use ../SLList.h, if you can. +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>SLList_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SLList_h 1 + +#include <Pix.h> +#include "<T>.defs.h" + +#ifndef _<T>SLListNode_h +#define _<T>SLListNode_h 1 + +struct <T>SLListNode +{ + <T>SLListNode* tl; + <T> hd; + <T>SLListNode() { } + <T>SLListNode(const <T&> h, <T>SLListNode* t = 0); + ~<T>SLListNode() { } +}; + + +inline <T>SLListNode::<T>SLListNode(const <T&> h, <T>SLListNode* t) +:hd(h), tl(t) {} + +typedef <T>SLListNode* <T>SLListNodePtr; + +#endif + + +class <T>SLList +{ +protected: + <T>SLListNode* last; + +public: + <T>SLList(); + <T>SLList(const <T>SLList& a); + ~<T>SLList(); + + <T>SLList& operator = (const <T>SLList& a); + + int empty(); + int length(); + + void clear(); + + Pix prepend(<T&> item); + Pix append(<T&> item); + + void join(<T>SLList&); + + Pix prepend(<T>SLListNode*); + Pix append(<T>SLListNode*); + + <T>& operator () (Pix p); + Pix first(); + void next(Pix& p); + int owns(Pix p); + Pix ins_after(Pix p, <T&> item); + void del_after(Pix p); + + <T>& front(); + <T>& rear(); + <T> remove_front(); + int remove_front(<T>& x); + void del_front(); + + void error(const char* msg); + int OK(); +}; + +inline <T>SLList::~<T>SLList() +{ + clear(); +} + +inline <T>SLList::<T>SLList() +{ + last = 0; +} + +inline int <T>SLList::empty() +{ + return last == 0; +} + + +inline Pix <T>SLList::first() +{ + return (last == 0)? 0 : Pix(last->tl); +} + +inline void <T>SLList::next(Pix& p) +{ + p = (p == 0 || p == last)? 0 : Pix(((<T>SLListNode*)(p))->tl); +} + +inline <T>& <T>SLList::operator () (Pix p) +{ + if (p == 0) error("null Pix"); + return ((<T>SLListNode*)(p))->hd; +} + +inline <T>& <T>SLList::front() +{ + if (last == 0) error("front: empty list"); + return last->tl->hd; +} + +inline <T>& <T>SLList::rear() +{ + if (last == 0) error("rear: empty list"); + return last->hd; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLQueue.ccP b/gnu/lib/libg++/g++-include/gen/SLQueue.ccP new file mode 100644 index 000000000000..8a5935b77570 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLQueue.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.SLQueue.h" diff --git a/gnu/lib/libg++/g++-include/gen/SLQueue.hP b/gnu/lib/libg++/g++-include/gen/SLQueue.hP new file mode 100644 index 000000000000..20fd74c9c57e --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLQueue.hP @@ -0,0 +1,108 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _<T>SLQueue_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SLQueue_h + +#include "<T>.SLList.h" +#include "<T>.Queue.h" + +class <T>SLQueue : public <T>Queue +{ + <T>SLList p; + +public: + <T>SLQueue(); + <T>SLQueue(const <T>SLQueue& q); + ~<T>SLQueue(); + + void operator = (const <T>SLQueue&); + + void enq(<T&> item); + <T> deq(); + <T>& front(); + void del_front(); + + void clear(); + int empty(); + int full(); + int length(); + + int OK(); +}; + +inline <T>SLQueue::<T>SLQueue() :p() {} +inline <T>SLQueue::<T>SLQueue(const <T>SLQueue& q) : p(q.p) {} + +inline <T>SLQueue::~<T>SLQueue() {} + +inline void <T>SLQueue::enq(<T&>item) +{ + p.append(item); +} + +inline <T> <T>SLQueue::deq() +{ + return p.remove_front(); +} + +inline <T>& <T>SLQueue::front() +{ + return p.front(); +} + + +inline void <T>SLQueue::del_front() +{ + p.del_front(); +} + +inline void <T>SLQueue::operator =(const <T>SLQueue& s) +{ + p = s.p; +} + +inline int <T>SLQueue::empty() +{ + return p.empty(); +} + +inline int <T>SLQueue::full() +{ + return 0; +} + +inline int <T>SLQueue::length() +{ + return p.length(); +} + +inline int <T>SLQueue::OK() +{ + return p.OK(); +} + +inline void <T>SLQueue::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLSet.ccP b/gnu/lib/libg++/g++-include/gen/SLSet.ccP new file mode 100644 index 000000000000..5f580849ff34 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLSet.ccP @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.SLSet.h" + +int <T>SLSet::OK() +{ + int v = p.OK(); + v &= count == p.length(); + if (!v) error("invariant failure"); + return v; +} + +Pix <T>SLSet::seek(<T&> item) +{ + for (Pix i = p.first(); i != 0 && !<T>EQ(p(i),item); p.next(i)); + return i; +} + +Pix <T>SLSet::add(<T&> item) +{ + Pix i = seek(item); + if (i == 0) + { + ++count; + i = p.append(item); + } + return i; +} + +void <T>SLSet::del(<T&> item) +{ + Pix i = p.first(); + if (i == 0) + return; + else if (<T>EQ(p(i), item)) + { + --count; + p.del_front(); + } + else + { + Pix trail = i; + p.next(i); + while (i != 0) + { + if (<T>EQ(p(i), item)) + { + --count; + p.del_after(trail); + return; + } + trail = i; + p.next(i); + } + } +} + diff --git a/gnu/lib/libg++/g++-include/gen/SLSet.hP b/gnu/lib/libg++/g++-include/gen/SLSet.hP new file mode 100644 index 000000000000..fcf153633f80 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLSet.hP @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>SLSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SLSet_h 1 + +#include "<T>.Set.h" +#include "<T>.SLList.h" + +class <T>SLSet : public <T>Set +{ +protected: + <T>SLList p; + +public: + <T>SLSet(); + <T>SLSet(const <T>SLSet&); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + int owns(Pix i); + Pix seek(<T&> item); + + int OK(); +}; + +inline <T>SLSet::<T>SLSet() : p() { count = 0; } + +inline <T>SLSet::<T>SLSet(const <T>SLSet& s) : p(s.p) { count = s.count; } + +inline Pix <T>SLSet::first() +{ + return p.first(); +} + +inline void <T>SLSet::next(Pix & idx) +{ + p.next(idx); +} + +inline <T>& <T>SLSet::operator ()(Pix idx) +{ + return p(idx); +} + +inline void <T>SLSet::clear() +{ + count = 0; p.clear(); +} + +inline int <T>SLSet::contains (<T&> item) +{ + return seek(item) != 0; +} + +inline int <T>SLSet::owns (Pix idx) +{ + return p.owns(idx); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SLStack.ccP b/gnu/lib/libg++/g++-include/gen/SLStack.ccP new file mode 100644 index 000000000000..3996b41fac55 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLStack.ccP @@ -0,0 +1,4 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.SLStack.h" diff --git a/gnu/lib/libg++/g++-include/gen/SLStack.hP b/gnu/lib/libg++/g++-include/gen/SLStack.hP new file mode 100644 index 000000000000..e20d9b9c2a47 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SLStack.hP @@ -0,0 +1,109 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>SLStack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SLStack_h 1 + +#include "<T>.SLList.h" +#include "<T>.Stack.h" + +class <T>SLStack : public <T>Stack +{ + <T>SLList p; + +public: + <T>SLStack(); + <T>SLStack(const <T>SLStack& s); + ~<T>SLStack(); + + void operator = (const <T>SLStack&); + + void push(<T&> item); + <T> pop(); + <T>& top(); + void del_top(); + + int empty(); + int full(); + int length(); + + void clear(); + + int OK(); + +}; + +inline <T>SLStack::<T>SLStack() :p() {} +inline <T>SLStack::<T>SLStack(const <T>SLStack& a) : p(a.p) {} +inline <T>SLStack::~<T>SLStack() {} + +inline void <T>SLStack::push(<T&> item) +{ + p.prepend(item); +} + +inline <T> <T>SLStack::pop() +{ + return p.remove_front(); +} + +inline <T>& <T>SLStack::top() +{ + return p.front(); +} + +inline void <T>SLStack::del_top() +{ + p.del_front(); +} + +inline void <T>SLStack::operator =(const <T>SLStack& s) +{ + p = s.p; +} + +inline int <T>SLStack::empty() +{ + return p.empty(); +} + +inline int <T>SLStack::full() +{ + return 0; +} + +inline int <T>SLStack::length() +{ + return p.length(); +} + +inline int <T>SLStack::OK() +{ + return p.OK(); +} + +inline void <T>SLStack::clear() +{ + p.clear(); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Set.ccP b/gnu/lib/libg++/g++-include/gen/Set.ccP new file mode 100644 index 000000000000..f312aa15cc75 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Set.ccP @@ -0,0 +1,116 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <builtin.h> +#include "<T>.Set.h" + + +Pix <T>Set::seek(<T&> item) +{ + for (Pix i = first(); i != 0 && !(<T>EQ((*this)(i), item)); next(i)); + return i; +} + +int <T>Set::owns(Pix idx) +{ + if (idx == 0) return 0; + for (Pix i = first(); i; next(i)) if (i == idx) return 1; + return 0; +} + +void <T>Set::clear() +{ + Pix i = first(); + while (i != 0) + { + del((*this)(i)); + i = first(); + } +} + +int <T>Set::contains (<T&> item) +{ + return seek(item) != 0; +} + +int <T>Set::operator <= (<T>Set& b) +{ + if (count > b.count) return 0; + if (count == 0) return 1; + for (Pix i = first(); i; next(i)) if (b.seek((*this)(i)) == 0) return 0; + return 1; +} + +int <T>Set::operator == (<T>Set& b) +{ + int n = count; + if (n != b.count) return 0; + if (n == 0) return 1; + Pix i = first(); + Pix j = b.first(); + while (n-- > 0) + { + if ((b.seek((*this)(i)) == 0) || (seek(b(j)) == 0)) return 0; + next(i); + b.next(j); + } + return 1; +} + +int <T>Set::operator != (<T>Set& b) +{ + return !(*this == b); +} + +void <T>Set::operator |= (<T>Set& b) +{ + if (&b != this) + for (Pix i = b.first(); i; b.next(i)) add(b(i)); +} + +void <T>Set::operator -= (<T>Set& b) +{ + if (&b == this) + clear(); + else + for (Pix i = b.first(); i; b.next(i)) del(b(i)); +} + + +void <T>Set::operator &= (<T>Set& b) +{ + if (&b != this) + { + Pix i = first(); + Pix n = i; + while (i != 0) + { + next(n); + if (b.seek((*this)(i)) == 0) del((*this)(i)); + i = n; + } + } +} + +void <T>Set::error(const char* msg) +{ + (*lib_error_handler)("Set", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Set.hP b/gnu/lib/libg++/g++-include/gen/Set.hP new file mode 100644 index 000000000000..6c2192262711 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Set.hP @@ -0,0 +1,78 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>Set_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>Set_h 1 + +#include <Pix.h> +#include "<T>.defs.h" + +class <T>Set +{ +protected: + + int count; + +public: + virtual ~<T>Set(); + + int length(); // current number of items + int empty(); + + virtual Pix add(<T&> item) = 0; // add item; return Pix + virtual void del(<T&> item) = 0; // delete item + virtual int contains(<T&> item); // is item in set? + + virtual void clear(); // delete all items + + virtual Pix first() = 0; // Pix of first item or 0 + virtual void next(Pix& i) = 0; // advance to next or 0 + virtual <T>& operator () (Pix i) = 0; // access item at i + + virtual int owns(Pix i); // is i a valid Pix ? + virtual Pix seek(<T&> item); // Pix of item + + void operator |= (<T>Set& b); // add all items in b + void operator -= (<T>Set& b); // delete items also in b + void operator &= (<T>Set& b); // delete items not in b + + int operator == (<T>Set& b); + int operator != (<T>Set& b); + int operator <= (<T>Set& b); + + void error(const char* msg); + virtual int OK() = 0; // rep invariant +}; + +inline <T>Set::~<T>Set() {} + +inline int <T>Set::length() +{ + return count; +} + +inline int <T>Set::empty() +{ + return count == 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SkipBag.ccP b/gnu/lib/libg++/g++-include/gen/SkipBag.ccP new file mode 100644 index 000000000000..cc347e981338 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipBag.ccP @@ -0,0 +1,322 @@ +// This may look like C code, but it is really -*- C++ -*- + +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#include <stream.h> +#include <time.h> +#include "<T>.SkipBag.h" + +MLCG* <T>SkipBag::gen = 0; +int <T>SkipBaginit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1L) n++; + return n; +} + +<T>SkipBag::<T>SkipBag(long size) +: level(0), + header(new <T>SkipBagNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + <T>SkipBagNodePtr *buffer_start = header->forward; + <T>SkipBagNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (<T>SkipBagNodePtr) header; +} + +<T>SkipBag::<T>SkipBag(<T>SkipBag& b) +: level (0), + header (new <T>SkipBagNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + <T>SkipBagNodePtr *buffer_start = header->forward; + <T>SkipBagNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (<T>SkipBagNodePtr)header; + + for (<T>SkipBagNodePtr t = b.leftmost(); t; t = b.succ(t)) + add(t->item); +} + +Pix <T>SkipBag::add (<T&> item) +{ + <T>SkipBagNodePtr *update = new <T>SkipBagNodePtr[max_levels+1]; + <T>SkipBagNodePtr curr = (<T>SkipBagNodePtr) this->header; + int l = level; + <T>SkipBagNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + <T>CMP(temp->item, item) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (<T>SkipBagNodePtr)header; + }; + + temp = new <T>RealSkipBagNode (item, l); + <T>SkipBagNodePtr *temp_forward = temp->forward; + + do + { + <T>SkipBagNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return Pix(temp); +} + +void <T>SkipBag::del(<T&> key) +{ + + int l = level; + int curr_level = level; + <T>SkipBagNodePtr *update = new <T>SkipBagNodePtr[max_levels+1]; + <T>SkipBagNodePtr curr = (<T>SkipBagNodePtr)header; + <T>SkipBagNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && <T>CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (<T>CMP(temp->item,key)==0) + { + <T>SkipBagNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + <T>SkipBagNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +<T>SkipBagNodePtr <T>SkipBag::rightmost() +{ + <T>SkipBagNodePtr temp; + <T>SkipBagNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +<T>SkipBagNodePtr <T>SkipBag::pred(<T>SkipBagNodePtr t) +{ + <T>SkipBagNodePtr temp, curr = (<T>SkipBagNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void <T>SkipBag::_kill() +{ + <T>SkipBagNode *p = this->header->forward[0]; + + while (p != header) + { + <T>SkipBagNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void <T>SkipBag::clear() +{ + <T>SkipBagNodePtr *buffer_start = header->forward; + <T>SkipBagNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (<T>SkipBagNodePtr)header; +} + +Pix <T>SkipBag::seek(<T&> key, Pix i) +{ + <T>SkipBagNodePtr temp; + <T>SkipBagNode *curr = header; + int l = level; + if (i) + curr = (<T>SkipBagNode *)i; + + do + { + while ((temp = curr->forward[l])!=header && + <T>CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (<T>CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + + +int <T>SkipBag::nof(<T&> item) +{ + int n = 0; + <T>SkipBagNodePtr t = (<T>SkipBagNodePtr)(seek(item)); + if (t != 0) + { + do + { + ++n; + t = succ(t); + } while (t != 0 && <T>EQ(item, t->item)); + } + return n; +} + +void <T>SkipBag::remove(<T&> key) +{ + Pix t = seek(key); + while (t != 0) + { + del(key); + t = seek(key); + } +} + + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int <T>SkipBag::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int <T>SkipBag::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + <T>SkipBagNodePtr trail = leftmost(); + <T>SkipBagNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +<T>SkipBaginit::<T>SkipBaginit() +{ + if (!count) + <T>SkipBag::gen = new MLCG(time(0)); + count++; +} + +<T>SkipBaginit::~<T>SkipBaginit() +{ + count--; + if (!count) + delete <T>SkipBag::gen; +} diff --git a/gnu/lib/libg++/g++-include/gen/SkipBag.hP b/gnu/lib/libg++/g++-include/gen/SkipBag.hP new file mode 100644 index 000000000000..1bfe9da44627 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipBag.hP @@ -0,0 +1,171 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _<T>SkipBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SkipBag_h 1 + +#include "<T>.Bag.h" + +#include <values.h> +#include <MLCG.h> + +class <T>SkipBag; +class <T>RealSkipBagNode; + +class <T>SkipBagNode +{ +friend class <T>SkipBag; + private: + <T>RealSkipBagNode * * forward; + <T>SkipBagNode(int size); +}; + +class <T>RealSkipBagNode : public <T>SkipBagNode +{ +friend class <T>SkipBag; + private: + <T> item; + <T>RealSkipBagNode(<T&> h, int size); +}; + +typedef <T>RealSkipBagNode* <T>SkipBagNodePtr; + +inline <T>SkipBagNode::<T>SkipBagNode(int size) +: forward(new <T>SkipBagNodePtr[size+1]) +{ +} + +inline <T>RealSkipBagNode::<T>RealSkipBagNode(<T&> h, int size) +: item(h), + <T>SkipBagNode(size) +{ +} + +class <T>SkipBag : public <T>Bag +{ +friend class <T>SkipBaginit; + protected: + <T>SkipBagNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + <T>SkipBagNodePtr leftmost(void); + <T>SkipBagNodePtr rightmost(void); + <T>SkipBagNodePtr pred(<T>SkipBagNodePtr t); + <T>SkipBagNodePtr succ(<T>SkipBagNodePtr t); + void _kill(void); + + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + + public: + <T>SkipBag(long size=DEFAULT_INITIAL_CAPACITY); + <T>SkipBag(<T>SkipBag& a); + ~<T>SkipBag(void); + + Pix add(<T&> i); + void del(<T&> i); + void remove(<T&>i); + int nof(<T&> i); + int contains(<T&> i); + + void clear(void); + + Pix first(void); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> i, Pix from = 0); + + Pix last(void); + void prev(Pix& i); + + int OK(void); +}; + +inline <T>SkipBagNodePtr <T>SkipBag::leftmost(void) +{ + return header->forward[0]; +} + +inline <T>SkipBagNodePtr <T>SkipBag::succ(<T>SkipBagNodePtr t) +{ + <T>SkipBagNodePtr result = 0; + if (t->forward[0]!=header) result = t->forward[0]; + return result; +} + +inline Pix <T>SkipBag::first(void) +{ + return Pix(leftmost()); +} + +inline Pix <T>SkipBag::last(void) +{ + return Pix(rightmost()); +} + +inline void <T>SkipBag::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T>SkipBagNodePtr)i)); +} + +inline <T>& <T>SkipBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>SkipBagNodePtr)i)->item; +} + +inline void <T>SkipBag::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T>SkipBagNodePtr)i)); +} + +inline int <T>SkipBag::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline <T>SkipBag::~<T>SkipBag() +{ + _kill(); + delete header; +} + +static class <T>SkipBaginit +{ + public: + <T>SkipBaginit(); + ~<T>SkipBaginit(); + private: + static int count; +} <T>skipBaginit; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SkipMap.ccP b/gnu/lib/libg++/g++-include/gen/SkipMap.ccP new file mode 100644 index 000000000000..8b6afe2eddf3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipMap.ccP @@ -0,0 +1,307 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include <stream.h> +#include <time.h> +#include "<T>.<C>.SkipMap.h" + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +MLCG* <T><C>SkipMap::gen = 0; +int <T><C>SkipMapinit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1) n++; + return n; +} + +<T><C>SkipMap::<T><C>SkipMap(<C&> dflt, long size) +: <T><C>Map(dflt), + level(0), + header(new <T><C>SkipMapNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + <T><C>SkipMapNodePtr *buffer_start = header->forward; + <T><C>SkipMapNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (<T><C>SkipMapNodePtr) header; +} + +<T><C>SkipMap::<T><C>SkipMap(<T><C>SkipMap& b) +: <T><C>Map(b.def), + level (0), + header (new <T><C>SkipMapNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + <T><C>SkipMapNodePtr *buffer_start = header->forward; + <T><C>SkipMapNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (<T><C>SkipMapNodePtr)header; + + for (<T><C>SkipMapNodePtr t = b.leftmost(); t; t = b.succ(t)) + (*this)[t->item] = t->cont; +} + +<C>& <T><C>SkipMap::operator [] (<T&> item) +{ + <T><C>SkipMapNodePtr *update = new <T><C>SkipMapNodePtr[max_levels+1]; + <T><C>SkipMapNodePtr curr = + (<T><C>SkipMapNodePtr) this->header; + int l = level; + <T><C>SkipMapNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + <T>CMP(temp->item, item) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (temp != header && <T>CMP(temp->item, item) == 0) + { + delete update; + return temp->cont; + } + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (<T><C>SkipMapNodePtr)header; + }; + + temp = new <T><C>RealSkipMapNode (item, def, l); + <T><C>SkipMapNodePtr *temp_forward = temp->forward; + + do + { + <T><C>SkipMapNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return temp->cont; +} + +void <T><C>SkipMap::del(<T&> key) +{ + + int l = level; + int curr_level = level; + <T><C>SkipMapNodePtr *update = new <T><C>SkipMapNodePtr[max_levels+1]; + <T><C>SkipMapNodePtr curr = (<T><C>SkipMapNodePtr)header; + <T><C>SkipMapNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && <T>CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (<T>CMP(temp->item,key)==0) + { + <T><C>SkipMapNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + <T><C>SkipMapNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +<T><C>SkipMapNodePtr <T><C>SkipMap::rightmost() +{ + <T><C>SkipMapNodePtr temp; + <T><C>SkipMapNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +<T><C>SkipMapNodePtr <T><C>SkipMap::pred(<T><C>SkipMapNodePtr t) +{ + <T><C>SkipMapNodePtr temp, curr = (<T><C>SkipMapNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void <T><C>SkipMap::_kill() +{ + <T><C>SkipMapNode *p = this->header->forward[0]; + + while (p != header) + { + <T><C>SkipMapNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void <T><C>SkipMap::clear() +{ + <T><C>SkipMapNodePtr *buffer_start = header->forward; + <T><C>SkipMapNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (<T><C>SkipMapNodePtr)header; +} + +Pix <T><C>SkipMap::seek(<T&> key) +{ + <T><C>SkipMapNodePtr temp; + <T><C>SkipMapNode *curr = header; + int l = level; + + do + { + while ((temp = curr->forward[l])!=header && + <T>CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (<T>CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int <T><C>SkipMap::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int <T><C>SkipMap::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + <T><C>SkipMapNodePtr trail = leftmost(); + <T><C>SkipMapNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +<T><C>SkipMapinit::<T><C>SkipMapinit() +{ + if (!count) + <T><C>SkipMap::gen = new MLCG(time(0)); + count++; +} + +<T><C>SkipMapinit::~<T><C>SkipMapinit() +{ + count--; + if (!count) + delete <T><C>SkipMap::gen; +} + + diff --git a/gnu/lib/libg++/g++-include/gen/SkipMap.hP b/gnu/lib/libg++/g++-include/gen/SkipMap.hP new file mode 100644 index 000000000000..65766d64c7a7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipMap.hP @@ -0,0 +1,176 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Bags implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _<T><C>SkipMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T><C>SkipMap_h 1 + +#include "<T>.<C>.Map.h" + +#include <values.h> +#include <MLCG.h> + +class <T><C>SkipMap; +class <T><C>RealSkipMapNode; + +class <T><C>SkipMapNode +{ +friend class <T><C>SkipMap; + private: + <T><C>RealSkipMapNode * * forward; + protected: + <T><C>SkipMapNode(int size); +}; + +class <T><C>RealSkipMapNode : public <T><C>SkipMapNode +{ +friend class <T><C>SkipMap; + private: + <T> item; + <C> cont; + <T><C>RealSkipMapNode(<T&> h, <C&> i, int size); +}; + +typedef <T><C>RealSkipMapNode* <T><C>SkipMapNodePtr; + +inline <T><C>SkipMapNode::<T><C>SkipMapNode(int size) +: forward(new <T><C>SkipMapNodePtr[size+1]) +{ +} + +inline <T><C>RealSkipMapNode::<T><C>RealSkipMapNode(<T&> h, <C&> i, int size) +: item(h), cont(i), + <T><C>SkipMapNode(size) +{ +} + +class <T><C>SkipMap : public <T><C>Map +{ +friend class <T><C>SkipMapinit; + protected: + <T><C>SkipMapNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + <T><C>SkipMapNodePtr leftmost(); + <T><C>SkipMapNodePtr rightmost(); + <T><C>SkipMapNodePtr pred(<T><C>SkipMapNodePtr t); + <T><C>SkipMapNodePtr succ(<T><C>SkipMapNodePtr t); + void _kill(); + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + + public: + <T><C>SkipMap( <C&> dflt, long size=DEFAULT_INITIAL_CAPACITY); + <T><C>SkipMap(<T><C>SkipMap& a); + ~<T><C>SkipMap(); + + <C>& operator [] (<T&> key); + + void del(<T&> key); + + Pix first(); + void next(Pix& i); + <T>& key(Pix i); + <C>& contents(Pix i); + + Pix seek(<T&> key); + int contains(<T&> key); + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + +inline <T><C>SkipMap::~<T><C>SkipMap() +{ + _kill(); + delete header; +} + +inline <T><C>SkipMapNodePtr <T><C>SkipMap::leftmost() +{ + return header->forward[0]==header ? 0 : header->forward[0]; +} + +inline Pix <T><C>SkipMap::first() +{ + return Pix(leftmost()); +} + +inline Pix <T><C>SkipMap::last() +{ + return Pix(rightmost()); +} + +inline <T><C>SkipMapNodePtr <T><C>SkipMap::succ(<T><C>SkipMapNodePtr t) +{ + return t->forward[0]==header ? 0 : t->forward[0]; +} + +inline void <T><C>SkipMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T><C>SkipMapNodePtr)i)); +} + +inline void <T><C>SkipMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T><C>SkipMapNodePtr)i)); +} + +inline <T>& <T><C>SkipMap::key (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>SkipMapNodePtr)i)->item; +} + +inline <C>& <T><C>SkipMap::contents (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>SkipMapNodePtr)i)->cont; +} + +inline int <T><C>SkipMap::contains(<T&> key) +{ + return seek(key) != 0; +} + +static class <T><C>SkipMapinit +{ + public: + <T><C>SkipMapinit(); + ~<T><C>SkipMapinit(); + private: + static int count; +} <T><C>skipMapinit; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SkipSet.ccP b/gnu/lib/libg++/g++-include/gen/SkipSet.ccP new file mode 100644 index 000000000000..a1bf33d0fa01 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipSet.ccP @@ -0,0 +1,395 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Sets implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#include <stream.h> +#include <time.h> + +#include "<T>.SkipSet.h" + +MLCG* <T>SkipSet::gen = 0; +int <T>SkipSetinit::count = 0; + +static int countbits(long bits) +{ + int n = 0; + while(bits>>=1L) n++; + return n; +} + +<T>SkipSet::<T>SkipSet(long size) +: level(0), + header(new <T>SkipSetNode (countbits(size)+1)), + max_levels (countbits(size)+1), + random_bits(gen->asLong()), + randoms_left(BITS_IN_RANDOM / 2) +{ + <T>SkipSetNodePtr *buffer_start = header->forward; + <T>SkipSetNodePtr *trav = &header->forward[max_levels]; + + count = 0; + while (trav > buffer_start) + *--trav = (<T>SkipSetNodePtr) header; +} + +<T>SkipSet::<T>SkipSet(<T>SkipSet& b) +: level (0), + header (new <T>SkipSetNode (b.max_levels)), + max_levels (b.max_levels), + random_bits (gen->asLong()), + randoms_left (BITS_IN_RANDOM / 2) +{ + <T>SkipSetNodePtr *buffer_start = header->forward; + <T>SkipSetNodePtr *trav = &header->forward[max_levels]; + + count = 0; + + while (trav > buffer_start) + *--trav = (<T>SkipSetNodePtr)header; + + for (<T>SkipSetNodePtr t = b.leftmost(); t; t = b.succ(t)) + add(t->item); +} + +/* relationals */ + +int <T>SkipSet::operator == (<T>SkipSet& y) +{ + if (count != y.count) + return 0; + else + { + <T>SkipSetNodePtr t = leftmost(); + <T>SkipSetNodePtr u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!<T>EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int <T>SkipSet::operator <= (<T>SkipSet& y) +{ + if (count > y.count) + return 0; + else + { + <T>SkipSetNodePtr t = leftmost(); + <T>SkipSetNodePtr u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = <T>CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +void <T>SkipSet::operator |=(<T>SkipSet& y) +{ + if (&y == this) return; + <T>SkipSetNodePtr u = y.leftmost(); + while (u != 0) + { + add(u->item); + u = y.succ(u); + } +} + +void <T>SkipSet::operator &= (<T>SkipSet& y) +{ + if (y.count == 0) + clear(); + else if (&y != this && count != 0) + { + <T>SkipSetNodePtr t = leftmost(); + while (t != 0) + { + <T>SkipSetNodePtr s = succ(t); + if (y.seek(t->item) == 0) del(t->item); + t = s; + } + } +} + + +void <T>SkipSet::operator -=(<T>SkipSet& y) +{ + if (&y == this) + clear(); + else if (y.count != 0) + { + <T>SkipSetNodePtr t = leftmost(); + while (t != 0) + { + <T>SkipSetNodePtr s = succ(t); + if (y.seek(t->item) != 0) del(t->item); + t = s; + } + } +} + +Pix <T>SkipSet::add (<T&> i) +{ + <T>SkipSetNodePtr *update = new <T>SkipSetNodePtr[max_levels+1]; + <T>SkipSetNodePtr curr = (<T>SkipSetNodePtr) this->header; + int l = level; + <T>SkipSetNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header && + <T>CMP(temp->item, i) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (temp != header && <T>CMP(temp->item, i) == 0) + return Pix(temp); + + if ((l = random_level ()) > level) + { + l = ++level; + update[l] = (<T>SkipSetNodePtr)header; + }; + + temp = new <T>RealSkipSetNode (i, l); + <T>SkipSetNodePtr *temp_forward = temp->forward; + + do + { + <T>SkipSetNodePtr *curr_forward = update[l]->forward; + + temp_forward[l] = curr_forward[l]; + curr_forward[l] = temp; + } + while (--l >= 0); + + count++; + delete update; + return Pix(temp); +} + +void <T>SkipSet::del(<T&> key) +{ + + int l = level; + int curr_level = level; + <T>SkipSetNodePtr *update = new <T>SkipSetNodePtr[max_levels+1]; + <T>SkipSetNodePtr curr = (<T>SkipSetNodePtr)header; + <T>SkipSetNodePtr temp; + + do + { + while ((temp = curr->forward[l])!=header + && <T>CMP(temp->item,key) < 0) + curr = temp; + update[l] = curr; + } + while (--l >= 0); + + if (<T>CMP(temp->item,key)==0) + { + <T>SkipSetNodePtr *temp_forward = temp->forward; + + for (l = 0; + l <= curr_level && (curr = update[l])->forward[l] == temp; + l++) + curr->forward[l] = temp_forward[l]; + + delete temp; + + <T>SkipSetNodePtr *forward = header->forward; + + while (forward[curr_level]==header && curr_level > 0) + curr_level--; + + level = curr_level; + count--; + delete update; + return; + } +} + +<T>SkipSetNodePtr <T>SkipSet::rightmost() +{ + <T>SkipSetNodePtr temp; + <T>SkipSetNode* curr = header; + int l = level; + + do + while ((temp = curr->forward[l])!=header) + curr = temp; + while (--l >= 0); + + return temp==header ? 0 : temp; +} + +<T>SkipSetNodePtr <T>SkipSet::pred(<T>SkipSetNodePtr t) +{ + <T>SkipSetNodePtr temp, curr = (<T>SkipSetNodePtr) header; + int l = level; + + do + while ((temp = curr->forward[l])!=t) + curr = temp; + while (--l >= 0); + + return curr == header ? 0 : curr; +} + +void <T>SkipSet::_kill() +{ + <T>SkipSetNode *p = this->header->forward[0]; + + while (p != header) + { + <T>SkipSetNodePtr q = p->forward[0]; + delete p; + p = q; + } +} + +void <T>SkipSet::clear() +{ + <T>SkipSetNodePtr *buffer_start = header->forward; + <T>SkipSetNodePtr *trav = &header->forward[level+1]; + _kill(); + count = 0; + + while (trav > buffer_start) + *--trav = (<T>SkipSetNodePtr)header; +} + +Pix <T>SkipSet::seek(<T&> key) +{ + <T>SkipSetNodePtr temp; + <T>SkipSetNode *curr = header; + int l = level; + + do + { + while ((temp = curr->forward[l])!=header && + <T>CMP(temp->item, key) < 0) + curr = temp; + } + while (--l >= 0); + + if (<T>CMP(temp->item, key) != 0) + return 0; + else + { + return Pix(temp); + } +} + + +/* + * random function for probabilistic balancing + * + * Hardwired for p = .25. Not too flexible, + * but fast. Changing this would require a constructor + * that would accept a different value for p, etc. + * Perhaps someone else would like to implement this? + * + */ +int <T>SkipSet::random_level (void) +{ + int rlevel = 0; + int b; + + do + { + b = random_bits & 3L; + if (!b) + rlevel++; + random_bits >>= 2; + if (--randoms_left == 0) + { + random_bits = gen->asLong(); + randoms_left = BITS_IN_RANDOM / 2; + }; + } + while (!b); + + return rlevel > max_levels ? max_levels : rlevel; +} + +int <T>SkipSet::OK() +{ + int v = 1; + if (header == 0) + v = 0; + else + { + int n = 0; + <T>SkipSetNodePtr trail = leftmost(); + <T>SkipSetNodePtr t = 0; + if (trail) t = succ(trail); + if (t) n++; + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + +<T>SkipSetinit::<T>SkipSetinit() +{ + if (!count) + <T>SkipSet::gen = new MLCG(time(0)); + count++; +} + +<T>SkipSetinit::~<T>SkipSetinit() +{ + count--; + if (!count) + delete <T>SkipSet::gen; +} diff --git a/gnu/lib/libg++/g++-include/gen/SkipSet.hP b/gnu/lib/libg++/g++-include/gen/SkipSet.hP new file mode 100644 index 000000000000..cd953052394d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SkipSet.hP @@ -0,0 +1,187 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1991 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Sets implemented via William Pugh SkipList algorithms. + * CACM, June 1990, p 668-676. + * + */ + +#ifndef _<T>SkipSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SkipSet_h 1 + +#include "<T>.Set.h" + +#include <values.h> +#include <MLCG.h> + +class <T>SkipSet; +class <T>RealSkipSetNode; + +class <T>SkipSetNode +{ +friend class <T>SkipSet; + private: + <T>RealSkipSetNode * * forward; + <T>SkipSetNode(int size); +}; + +class <T>RealSkipSetNode : public <T>SkipSetNode +{ +friend class <T>SkipSet; + private: + <T> item; + <T>RealSkipSetNode(<T&> h, int size); +}; + +typedef <T>RealSkipSetNode* <T>SkipSetNodePtr; + +inline <T>SkipSetNode::<T>SkipSetNode(int size) +: forward(new <T>SkipSetNodePtr[size+1]) +{ +} + +inline <T>RealSkipSetNode::<T>RealSkipSetNode(<T&> h, int size) +: item(h), + <T>SkipSetNode(size) +{ +} + +class <T>SkipSet : public <T>Set +{ +friend class <T>SkipSetinit; + protected: + <T>SkipSetNode* header; + int level; + int max_levels; + int randoms_left; + long random_bits; + + static MLCG* gen; + int random_level(void); + + <T>SkipSetNodePtr leftmost(void); + <T>SkipSetNodePtr rightmost(void); + <T>SkipSetNodePtr pred(<T>SkipSetNodePtr t); + <T>SkipSetNodePtr succ(<T>SkipSetNodePtr t); + void _kill(void); + + private: + enum { BITS_IN_RANDOM = LONGBITS-1 }; + public: + <T>SkipSet(long size=DEFAULT_INITIAL_CAPACITY); + <T>SkipSet(<T>SkipSet& a); + ~<T>SkipSet(); + + Pix add(<T&> i); + void del(<T&> i); + int contains(<T&> i); + + void clear(void); + + Pix first(void); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> i); + + Pix last(void); + void prev(Pix& i); + + void operator |= (<T>SkipSet& b); + void operator -= (<T>SkipSet& b); + void operator &= (<T>SkipSet& b); + + int operator == (<T>SkipSet& b); + int operator != (<T>SkipSet& b); + int operator <= (<T>SkipSet& b); + + int OK(void); +}; + +/* + * A little overkill on the inlines. + * + */ + +inline <T>SkipSet::~<T>SkipSet(void) +{ + _kill(); + delete header; +} + +inline int <T>SkipSet::operator != (<T>SkipSet& b) +{ + return ! (*this == b); +} + +inline <T>SkipSetNodePtr <T>SkipSet::leftmost(void) +{ + return header->forward[0]; +} + +inline <T>SkipSetNodePtr <T>SkipSet::succ(<T>SkipSetNodePtr t) +{ + <T>SkipSetNodePtr result = 0; + if (t->forward[0]!=header) result = t->forward[0]; + return result; +} + +inline Pix <T>SkipSet::first(void) +{ + return Pix(leftmost()); +} + +inline Pix <T>SkipSet::last(void) +{ + return Pix(rightmost()); +} + +inline void <T>SkipSet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T>SkipSetNodePtr)i)); +} + +inline void <T>SkipSet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T>SkipSetNodePtr)i)); +} + +inline <T>& <T>SkipSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>SkipSetNodePtr)i)->item; +} + + +inline int <T>SkipSet::contains(<T&> key) +{ + return seek(key) != 0; +} + +static class <T>SkipSetinit +{ + public: + <T>SkipSetinit(); + ~<T>SkipSetinit(); + private: + static int count; +} <T>skipSetinit; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayBag.ccP b/gnu/lib/libg++/g++-include/gen/SplayBag.ccP new file mode 100644 index 000000000000..ff02a992a656 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayBag.ccP @@ -0,0 +1,445 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.SplayBag.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + <T>SplayNode* lt; + <T>SplayNode* rt; + <T>SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +<T>SplayNode* <T>SplayBag::leftmost() +{ + <T>SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T>SplayNode* <T>SplayBag::rightmost() +{ + <T>SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T>SplayNode* <T>SplayBag::succ(<T>SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +<T>SplayNode* <T>SplayBag::pred(<T>SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + + +Pix <T>SplayBag::seek(<T&> key, Pix i) +{ + if (root == 0) return 0; + + <T>SplayNode* t = (<T>SplayNode*) i; + if (t != 0) + { + int cmp = <T>CMP(key, t->item); + if (cmp == 0) + { + t = succ(t); + if (t != 0 && <T>EQ(key, t->item)) + return Pix(t); + else + return 0; + } + else if (cmp < 0) + return 0; + } + + t = root; + int comp = <T>CMP(key, t->item); + if (comp == 0) + return Pix(t); + + <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null); + <T>SplayNode* l = dummy; + <T>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + <T>SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = <T>CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = <T>CMP(key, t->item); + } + } + } + else + { + <T>SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = <T>CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = <T>CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + if (comp != 0) + return 0; + else + { + l = pred(t); + while (l != 0 && <T>EQ(l->item, key)) { t = l; l = pred(l); } + return Pix(t); + } +} + +int <T>SplayBag::nof(<T&> item) +{ + int n = 0; + <T>SplayNode* t = (<T>SplayNode*)(seek(item)); + if (t != 0) + { + do + { + ++n; + t = succ(t); + } while (t != 0 && <T>EQ(item, t->item)); + } + return n; +} + +Pix <T>SplayBag::add(<T&> item) +{ + ++count; + <T>SplayNode* newnode = new <T>SplayNode(item); + <T>SplayNode* t = root; + if (t == 0) + { + root = newnode; + return Pix(root); + } + + int comp = <T>CMP(item, t->item); + + <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null); + <T>SplayNode* l = dummy; + <T>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + int done = 0; + while (!done) + { + if (comp >= 0) + { + <T>SplayNode* tr = t->rt; + if (tr == 0) + { + tr = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + <T>SplayNode* trr = tr->rt; + if (trr == 0) + { + trr = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + <T>SplayNode* tl = t->lt; + if (tl == 0) + { + tl = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + <T>SplayNode* tll = tl->lt; + if (tll == 0) + { + tll = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + +void <T>SplayBag::_del(<T>SplayNode* t) +{ + if (t == 0) return; + + <T>SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + <T>SplayNode* r = t->rt; + <T>SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void <T>SplayBag::remove(<T&> key) +{ + <T>SplayNode* t = (<T>SplayNode*)(seek(key)); + while (t != 0) + { + _del(t); + t = (<T>SplayNode*)(seek(key)); + } +} + + +void <T>SplayBag::_kill(<T>SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +<T>SplayNode* <T>SplayBag::_copy(<T>SplayNode* t) +{ + if (t != 0) + { + <T>SplayNode* l = _copy(t->lt); + <T>SplayNode* r = _copy(t->rt); + <T>SplayNode* x = new <T>SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +int <T>SplayBag::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T>SplayNode* trail = leftmost(); + <T>SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) <= 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} + diff --git a/gnu/lib/libg++/g++-include/gen/SplayBag.hP b/gnu/lib/libg++/g++-include/gen/SplayBag.hP new file mode 100644 index 000000000000..9d7fcad1ddc3 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayBag.hP @@ -0,0 +1,144 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>SplayBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SplayBag_h 1 + +#include "<T>.Bag.h" +#include "<T>.SplayNode.h" + +class <T>SplayBag : public <T>Bag +{ +protected: + <T>SplayNode* root; + + <T>SplayNode* leftmost(); + <T>SplayNode* rightmost(); + <T>SplayNode* pred(<T>SplayNode* t); + <T>SplayNode* succ(<T>SplayNode* t); + void _kill(<T>SplayNode* t); + <T>SplayNode* _copy(<T>SplayNode* t); + void _del(<T>SplayNode* t); + +public: + <T>SplayBag(); + <T>SplayBag(<T>SplayBag& a); + ~<T>SplayBag(); + + Pix add(<T&> item); + void del(<T&> item); + void remove(<T&>item); + int nof(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item, Pix from = 0); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + + +inline <T>SplayBag::~<T>SplayBag() +{ + _kill(root); +} + +inline <T>SplayBag::<T>SplayBag() +{ + root = 0; + count = 0; +} + +inline <T>SplayBag::<T>SplayBag(<T>SplayBag& b) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix <T>SplayBag::first() +{ + return Pix(leftmost()); +} + +inline Pix <T>SplayBag::last() +{ + return Pix(rightmost()); +} + +inline void <T>SplayBag::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T>SplayNode*)i)); +} + +inline void <T>SplayBag::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T>SplayNode*)i)); +} + +inline <T>& <T>SplayBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>SplayNode*)i)->item; +} + +inline void <T>SplayBag::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T>SplayBag::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline void <T>SplayBag::del(<T&> key) +{ + _del((<T>SplayNode*)(seek(key))); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayMap.ccP b/gnu/lib/libg++/g++-include/gen/SplayMap.ccP new file mode 100644 index 000000000000..4be340db0f6d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayMap.ccP @@ -0,0 +1,401 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.<C>.SplayMap.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + <T><C>SplayNode* lt; + <T><C>SplayNode* rt; + <T><C>SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +<T><C>SplayNode* <T><C>SplayMap::leftmost() +{ + <T><C>SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T><C>SplayNode* <T><C>SplayMap::rightmost() +{ + <T><C>SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T><C>SplayNode* <T><C>SplayMap::succ(<T><C>SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +<T><C>SplayNode* <T><C>SplayMap::pred(<T><C>SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix <T><C>SplayMap::seek(<T&> key) +{ + <T><C>SplayNode* t = root; + if (t == 0) + return 0; + + int comp = <T>CMP(key, t->item); + if (comp == 0) + return Pix(t); + + <T><C>SplayNode* dummy = (<T><C>SplayNode*)(&_dummy_null); + <T><C>SplayNode* l = dummy; + <T><C>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + <T><C>SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = <T>CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = <T>CMP(key, t->item); + } + } + } + else + { + <T><C>SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = <T>CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = <T>CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + +<C>& <T><C>SplayMap::operator [] (<T&> item) +{ + <T><C>SplayNode* t = root; + if (t == 0) + { + ++count; + root = new <T><C>SplayNode(item, def); + return root->cont; + } + int comp = <T>CMP(item, t->item); + if (comp == 0) + return t->cont; + + <T><C>SplayNode* dummy = (<T><C>SplayNode*)(&_dummy_null); + <T><C>SplayNode* l = dummy; + <T><C>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + <T><C>SplayNode* tr = t->rt; + if (tr == 0) + { + ++count; + tr = new <T><C>SplayNode(item, def); + comp = 0; + } + else + comp = <T>CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + <T><C>SplayNode* trr = tr->rt; + if (trr == 0) + { + ++count; + trr = new <T><C>SplayNode(item, def); + comp = 0; + } + else + comp = <T>CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + <T><C>SplayNode* tl = t->lt; + if (tl == 0) + { + ++count; + tl = new <T><C>SplayNode(item, def); + comp = 0; + } + else + comp = <T>CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + <T><C>SplayNode* tll = tl->lt; + if (tll == 0) + { + ++count; + tll = new <T><C>SplayNode(item, def); + comp = 0; + } + else + comp = <T>CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return root->cont; +} + +void <T><C>SplayMap::del(<T&> key) +{ + <T><C>SplayNode* t = (<T><C>SplayNode*)(seek(key)); + if (t == 0) return; + + <T><C>SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + <T><C>SplayNode* r = t->rt; + <T><C>SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void <T><C>SplayMap::_kill(<T><C>SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +<T><C>SplayNode* <T><C>SplayMap::_copy(<T><C>SplayNode* t) +{ + if (t != 0) + { + <T><C>SplayNode* l = _copy(t->lt); + <T><C>SplayNode* r = _copy(t->rt); + <T><C>SplayNode* x = new <T><C>SplayNode(t->item, t->cont, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + + +int <T><C>SplayMap::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T><C>SplayNode* trail = leftmost(); + <T><C>SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SplayMap.hP b/gnu/lib/libg++/g++-include/gen/SplayMap.hP new file mode 100644 index 000000000000..ced95378ab72 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayMap.hP @@ -0,0 +1,154 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T><C>SplayMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T><C>SplayMap_h 1 + +#include "<T>.<C>.Map.h" + +#ifndef _<T><C>SplayNode +#define _<T><C>SplayNode 1 + +struct <T><C>SplayNode +{ + <T><C>SplayNode* lt; + <T><C>SplayNode* rt; + <T><C>SplayNode* par; + <T> item; + <C> cont; + <T><C>SplayNode(<T&> h, <C&> c, + <T><C>SplayNode* l=0, + <T><C>SplayNode* r=0); + ~<T><C>SplayNode(); +}; + + +inline <T><C>SplayNode::<T><C>SplayNode(<T&> h, <C&> c, + <T><C>SplayNode* l, + <T><C>SplayNode* r) + :item(h), cont(c), lt(l), rt(r), par(0) {} + +inline <T><C>SplayNode::~<T><C>SplayNode() {} + +typedef <T><C>SplayNode* <T><C>SplayNodePtr; + +#endif + +class <T><C>SplayMap : public <T><C>Map +{ +protected: + <T><C>SplayNode* root; + + <T><C>SplayNode* leftmost(); + <T><C>SplayNode* rightmost(); + <T><C>SplayNode* pred(<T><C>SplayNode* t); + <T><C>SplayNode* succ(<T><C>SplayNode* t); + void _kill(<T><C>SplayNode* t); + <T><C>SplayNode* _copy(<T><C>SplayNode* t); + +public: + <T><C>SplayMap(<C&> dflt); + <T><C>SplayMap(<T><C>SplayMap& a); + ~<T><C>SplayMap(); + + <C>& operator [] (<T&> key); + + void del(<T&> key); + + Pix first(); + void next(Pix& i); + <T>& key(Pix i); + <C>& contents(Pix i); + + Pix seek(<T&> key); + int contains(<T&> key); + + void clear(); + + Pix last(); + void prev(Pix& i); + + int OK(); +}; + + +inline <T><C>SplayMap::~<T><C>SplayMap() +{ + _kill(root); +} + +inline <T><C>SplayMap::<T><C>SplayMap(<C&> dflt) :<T><C>Map(dflt) +{ + root = 0; +} + +inline <T><C>SplayMap::<T><C>SplayMap(<T><C>SplayMap& b) :<T><C>Map(b.def) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix <T><C>SplayMap::first() +{ + return Pix(leftmost()); +} + +inline Pix <T><C>SplayMap::last() +{ + return Pix(rightmost()); +} + +inline void <T><C>SplayMap::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T><C>SplayNode*)i)); +} + +inline void <T><C>SplayMap::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T><C>SplayNode*)i)); +} + +inline <T>& <T><C>SplayMap::key (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>SplayNode*)i)->item; +} + +inline <C>& <T><C>SplayMap::contents (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T><C>SplayNode*)i)->cont; +} + +inline void <T><C>SplayMap::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T><C>SplayMap::contains(<T&> key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayNode.ccP b/gnu/lib/libg++/g++-include/gen/SplayNode.ccP new file mode 100644 index 000000000000..9dfb1d8c0658 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayNode.ccP @@ -0,0 +1,21 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1992 Free Software Foundation + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.SplayNode.h" diff --git a/gnu/lib/libg++/g++-include/gen/SplayNode.hP b/gnu/lib/libg++/g++-include/gen/SplayNode.hP new file mode 100644 index 000000000000..a196861fc9cc --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayNode.hP @@ -0,0 +1,44 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1982 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _<T>SplayNode +#define _<T>SplayNode 1 +#ifdef __GNUG__ +#pragma interface +#endif +#include "<T>.defs.h" + +struct <T>SplayNode +{ + <T>SplayNode* lt; + <T>SplayNode* rt; + <T>SplayNode* par; + <T> item; + <T>SplayNode(<T&> h, <T>SplayNode* l=0, <T>SplayNode* r=0); + ~<T>SplayNode(); +}; + + +inline <T>SplayNode::<T>SplayNode(<T&> h, <T>SplayNode* l, <T>SplayNode* r) +:item(h), lt(l), rt(r), par(0) {} + +inline <T>SplayNode::~<T>SplayNode() {} + +typedef <T>SplayNode* <T>SplayNodePtr; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP b/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP new file mode 100644 index 000000000000..0740cd9a930d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP @@ -0,0 +1,523 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.SplayPQ.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + <T>SplayNode* lt; + <T>SplayNode* rt; + <T>SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +<T>SplayNode* <T>SplayPQ::leftmost() +{ + <T>SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T>SplayNode* <T>SplayPQ::rightmost() +{ + <T>SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T>SplayNode* <T>SplayPQ::succ(<T>SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +<T>SplayNode* <T>SplayPQ::pred(<T>SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix <T>SplayPQ::seek(<T&> key) +{ + <T>SplayNode* t = root; + if (t == 0) + return 0; + + int comp = <T>CMP(key, t->item); + if (comp == 0) + return Pix(t); + + <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null); + <T>SplayNode* l = dummy; + <T>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + <T>SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = <T>CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = <T>CMP(key, t->item); + } + } + } + else + { + <T>SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = <T>CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = <T>CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + +Pix <T>SplayPQ::enq(<T&> item) +{ + ++count; + <T>SplayNode* newnode = new <T>SplayNode(item); + <T>SplayNode* t = root; + if (t == 0) + { + root = newnode; + return Pix(root); + } + + int comp = <T>CMP(item, t->item); + + <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null); + <T>SplayNode* l = dummy; + <T>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + int done = 0; + while (!done) + { + if (comp >= 0) + { + <T>SplayNode* tr = t->rt; + if (tr == 0) + { + tr = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + <T>SplayNode* trr = tr->rt; + if (trr == 0) + { + trr = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + <T>SplayNode* tl = t->lt; + if (tl == 0) + { + tl = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + <T>SplayNode* tll = tl->lt; + if (tll == 0) + { + tll = newnode; + comp = 0; done = 1; + } + else + comp = <T>CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + + +void <T>SplayPQ::del(Pix pix) +{ + <T>SplayNode* t = (<T>SplayNode*)pix; + if (t == 0) return; + + <T>SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + <T>SplayNode* r = t->rt; + <T>SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + +<T>& <T>SplayPQ::front() +{ + if (root == 0) + error ("min: empty tree\n"); +// else + { + <T>SplayNode* t = root; + <T>SplayNode* l = root->lt; + for(;;) + { + if (l == 0) + { + root = t; + root->par = 0; + return root->item; + } + else + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + l->rt = t; t->par = l; + t = l; + l = l->lt; + } + } + } +} + +void <T>SplayPQ::del_front() +{ + if (root != 0) + { + --count; + <T>SplayNode* t = root; + <T>SplayNode* l = root->lt; + if (l == 0) + { + if ((root = t->rt) != 0) root->par = 0; + delete t; + } + else + { + for(;;) + { + <T>SplayNode* ll = l->lt; + if (ll == 0) + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + delete l; + break; + } + else + { + <T>SplayNode* lll = ll->lt; + if (lll == 0) + { + if ((l->lt = ll->rt) != 0) l->lt->par = l; + delete ll; + break; + } + else + { + t->lt = ll; ll->par = t; + if ((l->lt = ll->rt) != 0) l->lt->par = l; + ll->rt = l; l->par = ll; + t = ll; + l = lll; + } + } + } + } + } +} + +<T> <T>SplayPQ::deq() +{ + if (root == 0) + error("deq: empty tree"); +// else + { + --count; + <T>SplayNode* t = root; + <T>SplayNode* l = root->lt; + if (l == 0) + { + if ((root = t->rt) != 0) root->par = 0; + <T> res = t->item; + delete t; + return res; + } + else + { + for(;;) + { + <T>SplayNode* ll = l->lt; + if (ll == 0) + { + if ((t->lt = l->rt) != 0) t->lt->par = t; + <T> res = l->item; + delete l; + return res; + } + else + { + <T>SplayNode* lll = ll->lt; + if (lll == 0) + { + if ((l->lt = ll->rt) != 0) l->lt->par = l; + <T> res = ll->item; + delete ll; + return res; + } + else + { + t->lt = ll; ll->par = t; + if ((l->lt = ll->rt) != 0) l->lt->par = l; + ll->rt = l; l->par = ll; + t = ll; + l = lll; + } + } + } + } + } +} + + +void <T>SplayPQ::_kill(<T>SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +<T>SplayNode* <T>SplayPQ::_copy(<T>SplayNode* t) +{ + if (t != 0) + { + <T>SplayNode* l = _copy(t->lt); + <T>SplayNode* r = _copy(t->rt); + <T>SplayNode* x = new <T>SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +int <T>SplayPQ::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T>SplayNode* trail = leftmost(); + <T>SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SplayPQ.hP b/gnu/lib/libg++/g++-include/gen/SplayPQ.hP new file mode 100644 index 000000000000..c75c4a05299d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplayPQ.hP @@ -0,0 +1,123 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>SplayPQ_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SplayPQ_h 1 + +#include "<T>.PQ.h" +#include "<T>.SplayNode.h" + +class <T>SplayPQ : public <T>PQ +{ +protected: + <T>SplayNode* root; + + <T>SplayNode* leftmost(); + <T>SplayNode* rightmost(); + <T>SplayNode* pred(<T>SplayNode* t); + <T>SplayNode* succ(<T>SplayNode* t); + void _kill(<T>SplayNode* t); + <T>SplayNode* _copy(<T>SplayNode* t); + +public: + <T>SplayPQ(); + <T>SplayPQ(<T>SplayPQ& a); + virtual ~<T>SplayPQ(); + + Pix enq(<T&> item); + <T> deq(); + + <T>& front(); + void del_front(); + + int contains(<T&> item); + + void clear(); + + Pix first(); + Pix last(); + void next(Pix& i); + void prev(Pix& i); + <T>& operator () (Pix i); + void del(Pix i); + Pix seek(<T&> item); + + int OK(); // rep invariant +}; + + +inline <T>SplayPQ::~<T>SplayPQ() +{ + _kill(root); +} + +inline <T>SplayPQ::<T>SplayPQ() +{ + root = 0; + count = 0; +} + +inline <T>SplayPQ::<T>SplayPQ(<T>SplayPQ& b) +{ + count = b.count; + root = _copy(b.root); +} + +inline Pix <T>SplayPQ::first() +{ + return Pix(leftmost()); +} + +inline Pix <T>SplayPQ::last() +{ + return Pix(rightmost()); +} + +inline void <T>SplayPQ::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T>SplayNode*)i)); +} + +inline void <T>SplayPQ::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T>SplayNode*)i)); +} + +inline <T>& <T>SplayPQ::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>SplayNode*)i)->item; +} + +inline void <T>SplayPQ::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T>SplayPQ::contains(<T&> key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/SplaySet.ccP b/gnu/lib/libg++/g++-include/gen/SplaySet.ccP new file mode 100644 index 000000000000..bba5601c7eb6 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplaySet.ccP @@ -0,0 +1,499 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.SplaySet.h" + + +/* + + struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985 + splay tree algorithms + + All routines use a version of their `simple top-down' splay alg. (p 669) + +*/ + +struct _dummySplayNode +{ + <T>SplayNode* lt; + <T>SplayNode* rt; + <T>SplayNode* par; +} _dummy_null; + + +/* + traversal primitives +*/ + + +<T>SplayNode* <T>SplaySet::leftmost() +{ + <T>SplayNode* t = root; + if (t != 0) while (t->lt != 0) t = t->lt; + return t; +} + +<T>SplayNode* <T>SplaySet::rightmost() +{ + <T>SplayNode* t = root; + if (t != 0) while (t->rt != 0) t = t->rt; + return t; +} + +<T>SplayNode* <T>SplaySet::succ(<T>SplayNode* t) +{ + if (t == 0) + return 0; + if (t->rt != 0) + { + t = t->rt; + while (t->lt != 0) t = t->lt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->lt) + return t->par; + else + t = t->par; + } + } +} + +<T>SplayNode* <T>SplaySet::pred(<T>SplayNode* t) +{ + if (t == 0) + return 0; + else if (t->lt != 0) + { + t = t->lt; + while (t->rt != 0) t = t->rt; + return t; + } + else + { + for (;;) + { + if (t->par == 0 || t == t->par->rt) + return t->par; + else + t = t->par; + } + } +} + + +Pix <T>SplaySet::seek(<T&> key) +{ + <T>SplayNode* t = root; + if (t == 0) + return 0; + + int comp = <T>CMP(key, t->item); + if (comp == 0) + return Pix(t); + + <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null); + <T>SplayNode* l = dummy; + <T>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + <T>SplayNode* tr = t->rt; + if (tr == 0) + break; + else + { + comp = <T>CMP(key, tr->item); + if (comp <= 0 || tr->rt == 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + if (comp >= 0) + break; + } + else + { + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = tr->rt; + comp = <T>CMP(key, t->item); + } + } + } + else + { + <T>SplayNode* tl = t->lt; + if (tl == 0) + break; + else + { + comp = <T>CMP(key, tl->item); + if (comp >= 0 || tl->lt == 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + if (comp <= 0) + break; + } + else + { + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tl->lt; + comp = <T>CMP(key, t->item); + } + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return (comp == 0) ? Pix(t) : 0; +} + + + +Pix <T>SplaySet::add(<T&> item) +{ + <T>SplayNode* t = root; + if (t == 0) + { + ++count; + root = new <T>SplayNode(item); + return Pix(root); + } + int comp = <T>CMP(item, t->item); + if (comp == 0) + return Pix(t); + + <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null); + <T>SplayNode* l = dummy; + <T>SplayNode* r = dummy; + dummy->rt = dummy->lt = dummy->par = 0; + + while (comp != 0) + { + if (comp > 0) + { + <T>SplayNode* tr = t->rt; + if (tr == 0) + { + ++count; + tr = new <T>SplayNode(item); + comp = 0; + } + else + comp = <T>CMP(item, tr->item); + + if (comp <= 0) + { + l->rt = t; t->par = l; + l = t; + t = tr; + } + else + { + <T>SplayNode* trr = tr->rt; + if (trr == 0) + { + ++count; + trr = new <T>SplayNode(item); + comp = 0; + } + else + comp = <T>CMP(item, trr->item); + + if ((t->rt = tr->lt) != 0) t->rt->par = t; + tr->lt = t; t->par = tr; + l->rt = tr; tr->par = l; + l = tr; + t = trr; + } + } + else + { + <T>SplayNode* tl = t->lt; + if (tl == 0) + { + ++count; + tl = new <T>SplayNode(item); + comp = 0; + } + else + comp = <T>CMP(item, tl->item); + + if (comp >= 0) + { + r->lt = t; t->par = r; + r = t; + t = tl; + } + else + { + <T>SplayNode* tll = tl->lt; + if (tll == 0) + { + ++count; + tll = new <T>SplayNode(item); + comp = 0; + } + else + comp = <T>CMP(item, tll->item); + + if ((t->lt = tl->rt) != 0) t->lt->par = t; + tl->rt = t; t->par = tl; + r->lt = tl; tl->par = r; + r = tl; + t = tll; + } + } + } + if ((r->lt = t->rt) != 0) r->lt->par = r; + if ((l->rt = t->lt) != 0) l->rt->par = l; + if ((t->lt = dummy->rt) != 0) t->lt->par = t; + if ((t->rt = dummy->lt) != 0) t->rt->par = t; + t->par = 0; + root = t; + return Pix(root); +} + +void <T>SplaySet::del(<T&> key) +{ + <T>SplayNode* t = (<T>SplayNode*)(seek(key)); + if (t == 0) return; + + <T>SplayNode* p = t->par; + + --count; + if (t->rt == 0) + { + if (t == root) + { + if ((root = t->lt) != 0) root->par = 0; + } + else if (t == p->lt) + { + if ((p->lt = t->lt) != 0) p->lt->par = p; + } + else + if ((p->rt = t->lt) != 0) p->rt->par = p; + } + else + { + <T>SplayNode* r = t->rt; + <T>SplayNode* l = r->lt; + for(;;) + { + if (l == 0) + { + if (t == root) + { + root = r; + r->par = 0; + } + else if (t == p->lt) + { + p->lt = r; + r->par = p; + } + else + { + p->rt = r; + r->par = p; + } + if ((r->lt = t->lt) != 0) r->lt->par = r; + break; + } + else + { + if ((r->lt = l->rt) != 0) r->lt->par = r; + l->rt = r; r->par = l; + r = l; + l = l->lt; + } + } + } + delete t; +} + + +void <T>SplaySet::_kill(<T>SplayNode* t) +{ + if (t != 0) + { + _kill(t->lt); + _kill(t->rt); + delete t; + } +} + + +<T>SplayNode* <T>SplaySet::_copy(<T>SplayNode* t) +{ + if (t != 0) + { + <T>SplayNode* l = _copy(t->lt); + <T>SplayNode* r = _copy(t->rt); + <T>SplayNode* x = new <T>SplayNode(t->item, l, r); + if (l != 0) l->par = x; + if (r != 0) r->par = x; + return x; + } + else + return 0; +} + +/* relationals */ + +int <T>SplaySet::operator == (<T>SplaySet& y) +{ + if (count != y.count) + return 0; + else + { + <T>SplayNode* t = leftmost(); + <T>SplayNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (!<T>EQ(t->item, u->item)) + return 0; + else + { + t = succ(t); + u = y.succ(u); + } + } + } +} + +int <T>SplaySet::operator <= (<T>SplaySet& y) +{ + if (count > y.count) + return 0; + else + { + <T>SplayNode* t = leftmost(); + <T>SplayNode* u = y.leftmost(); + for (;;) + { + if (t == 0) + return 1; + else if (u == 0) + return 0; + int cmp = <T>CMP(t->item, u->item); + if (cmp == 0) + { + t = succ(t); + u = y.succ(u); + } + else if (cmp < 0) + return 0; + else + u = y.succ(u); + } + } +} + + +void <T>SplaySet::operator |=(<T>SplaySet& y) +{ + if (&y == this) return; + <T>SplayNode* u = y.leftmost(); + while (u != 0) + { + add(u->item); + u = y.succ(u); + } +} + +void <T>SplaySet::operator &= (<T>SplaySet& y) +{ + if (y.count == 0) + clear(); + else if (&y != this && count != 0) + { + <T>SplayNode* t = leftmost(); + while (t != 0) + { + <T>SplayNode* s = succ(t); + if (y.seek(t->item) == 0) del(t->item); + t = s; + } + } +} + + +void <T>SplaySet::operator -=(<T>SplaySet& y) +{ + if (&y == this) + clear(); + else if (y.count != 0) + { + <T>SplayNode* t = leftmost(); + while (t != 0) + { + <T>SplayNode* s = succ(t); + if (y.seek(t->item) != 0) del(t->item); + t = s; + } + } +} + +int <T>SplaySet::OK() +{ + int v = 1; + if (root == 0) + v = count == 0; + else + { + int n = 1; + <T>SplayNode* trail = leftmost(); + <T>SplayNode* t = succ(trail); + while (t != 0) + { + ++n; + v &= <T>CMP(trail->item, t->item) < 0; + trail = t; + t = succ(t); + } + v &= n == count; + } + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/SplaySet.hP b/gnu/lib/libg++/g++-include/gen/SplaySet.hP new file mode 100644 index 000000000000..cf50b975548a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/SplaySet.hP @@ -0,0 +1,133 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>SplaySet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>SplaySet_h 1 + +#include "<T>.Set.h" +#include "<T>.SplayNode.h" + +class <T>SplaySet : public <T>Set +{ +protected: + <T>SplayNode* root; + + <T>SplayNode* leftmost(); + <T>SplayNode* rightmost(); + <T>SplayNode* pred(<T>SplayNode* t); + <T>SplayNode* succ(<T>SplayNode* t); + void _kill(<T>SplayNode* t); + <T>SplayNode* _copy(<T>SplayNode* t); + +public: + <T>SplaySet(); + <T>SplaySet(<T>SplaySet& a); + ~<T>SplaySet(); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item); + + Pix last(); + void prev(Pix& i); + + void operator |= (<T>SplaySet& b); + void operator -= (<T>SplaySet& b); + void operator &= (<T>SplaySet& b); + + int operator == (<T>SplaySet& b); + int operator != (<T>SplaySet& b); + int operator <= (<T>SplaySet& b); + + int OK(); +}; + + +inline <T>SplaySet::~<T>SplaySet() +{ + _kill(root); +} + +inline <T>SplaySet::<T>SplaySet() +{ + root = 0; + count = 0; +} + +inline <T>SplaySet::<T>SplaySet(<T>SplaySet& b) +{ + count = b.count; + root = _copy(b.root); +} + + +inline int <T>SplaySet::operator != (<T>SplaySet& b) +{ + return ! (*this == b); +} + +inline Pix <T>SplaySet::first() +{ + return Pix(leftmost()); +} + +inline Pix <T>SplaySet::last() +{ + return Pix(rightmost()); +} + +inline void <T>SplaySet::next(Pix& i) +{ + if (i != 0) i = Pix(succ((<T>SplayNode*)i)); +} + +inline void <T>SplaySet::prev(Pix& i) +{ + if (i != 0) i = Pix(pred((<T>SplayNode*)i)); +} + +inline <T>& <T>SplaySet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return ((<T>SplayNode*)i)->item; +} + +inline void <T>SplaySet::clear() +{ + _kill(root); + count = 0; + root = 0; +} + +inline int <T>SplaySet::contains(<T&> key) +{ + return seek(key) != 0; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/Stack.ccP b/gnu/lib/libg++/g++-include/gen/Stack.ccP new file mode 100644 index 000000000000..efb6b8edbde5 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Stack.ccP @@ -0,0 +1,11 @@ +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.Stack.h" + +<T>Stack::~<T>Stack() {} + +void <T>Stack::error(const char* msg) +{ + (*lib_error_handler)("Stack", msg); +} diff --git a/gnu/lib/libg++/g++-include/gen/Stack.hP b/gnu/lib/libg++/g++-include/gen/Stack.hP new file mode 100644 index 000000000000..37acb2fac5b7 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/Stack.hP @@ -0,0 +1,51 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>Stack_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>Stack_h + +#include <builtin.h> + +#include "<T>.defs.h" + +class <T>Stack +{ +public: + <T>Stack() { } + virtual ~<T>Stack(); + + virtual void push(<T&> item) = 0; + virtual <T> pop() = 0; + virtual <T>& top() = 0; + virtual void del_top() = 0; + + virtual int empty() = 0; + virtual int full() = 0; + virtual int length() = 0; + + virtual void clear() = 0; + + void error(const char*); + virtual int OK() = 0; +}; + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VHBag.ccP b/gnu/lib/libg++/g++-include/gen/VHBag.ccP new file mode 100644 index 000000000000..81a20eb140db --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHBag.ccP @@ -0,0 +1,264 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.VHBag.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +<T>VHBag::<T>VHBag(unsigned int sz) +{ + tab = new <T>[size = sz]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +<T>VHBag::<T>VHBag(<T>VHBag& a) +{ + tab = new <T>[size = a.size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix <T>VHBag::seek(<T&> key, Pix p) +{ + <T>* t = (<T>*) p; + if (t == 0 || !<T>EQ(*t, key)) + { + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && <T>EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; + } + else + { + int seent = 0; + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (&tab[h] == t) + seent = 1; + else if (seent && status[h] == VALIDCELL && <T>EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; + } +} + +int <T>VHBag::nof(<T&> item) +{ + int n = 0; + unsigned int hashval = <T>HASH(item); + unsigned int h = hashval % size; + unsigned int firsth = size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return n; + else if (h != firsth && status[h] == VALIDCELL && <T>EQ(item, tab[h])) + { + ++n; + if (firsth >= size) + firsth = h; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return n; +} + + +Pix <T>VHBag::add(<T&> item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + unsigned int bestspot = size; + unsigned int hashval = <T>HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); +} + + +void <T>VHBag::del(<T&> key) +{ + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && <T>EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + +void <T>VHBag::remove(<T&> key) +{ + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && <T>EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + +void <T>VHBag::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void <T>VHBag::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + <T>* oldtab = tab; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new <T>[size = newsize]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix <T>VHBag::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void <T>VHBag::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int <T>VHBag::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VHBag.hP b/gnu/lib/libg++/g++-include/gen/VHBag.hP new file mode 100644 index 000000000000..72c774a5591d --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHBag.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>VHBag_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>VHBag_h 1 + +#include "<T>.Bag.h" + + +class <T>VHBag : public <T>Bag +{ +protected: + <T>* tab; + char* status; + unsigned int size; + +public: + <T>VHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + <T>VHBag(<T>VHBag& a); + ~<T>VHBag(); + + Pix add(<T&> item); + void del(<T&> item); + void remove(<T&>item); + int nof(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item, Pix from = 0); + + int capacity(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + + +inline <T>VHBag::~<T>VHBag() +{ + delete [] tab; + delete status; +} + + +inline int <T>VHBag::capacity() +{ + return size; +} + +inline int <T>VHBag::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline <T>& <T>VHBag::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return *((<T>*)i); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VHMap.ccP b/gnu/lib/libg++/g++-include/gen/VHMap.ccP new file mode 100644 index 000000000000..d6b60e997a9c --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHMap.ccP @@ -0,0 +1,210 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.<C>.VHMap.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +<T><C>VHMap::<T><C>VHMap(<C&> dflt, unsigned int sz) + :<T><C>Map(dflt) +{ + tab = new <T>[size = sz]; + cont = new <C>[size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; +} + +<T><C>VHMap::<T><C>VHMap(<T><C>VHMap& a) : <T><C>Map(a.def) +{ + tab = new <T>[size = a.size]; + cont = new <C>[size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix <T><C>VHMap::seek(<T&> key) +{ + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && <T>EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; +} + + +<C>& <T><C>VHMap::operator [](<T&> item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + + unsigned int bestspot = size; + unsigned int hashval = <T>HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + ++count; + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + cont[bestspot] = def; + return cont[bestspot]; + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + else if (<T>EQ(tab[h],item)) + return cont[h]; + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + + ++count; + status[bestspot] = VALIDCELL; + tab[bestspot] = item; + cont[bestspot] = def; + return cont[bestspot]; +} + + +void <T><C>VHMap::del(<T&> key) +{ + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && <T>EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + + +void <T><C>VHMap::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void <T><C>VHMap::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + <T>* oldtab = tab; + <C>* oldcont = cont; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new <T>[size = newsize]; + cont = new <C>[size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) + if (oldstatus[i] == VALIDCELL) + (*this)[oldtab[i]] = oldcont[i]; + delete [] oldtab; + delete [] oldcont; + delete oldstatus; +} + +Pix <T><C>VHMap::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void <T><C>VHMap::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int <T><C>VHMap::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VHMap.hP b/gnu/lib/libg++/g++-include/gen/VHMap.hP new file mode 100644 index 000000000000..ac8fe4d219a8 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHMap.hP @@ -0,0 +1,84 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T><C>VHMap_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T><C>VHMap_h 1 + +#include "<T>.<C>.Map.h" + + +class <T><C>VHMap : public <T><C>Map +{ +protected: + <T>* tab; + <C>* cont; + char* status; + unsigned int size; + +public: + <T><C>VHMap(<C&> dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY); + <T><C>VHMap(<T><C>VHMap& a); + ~<T><C>VHMap(); + + <C>& operator [] (<T&> key); + + void del(<T&> key); + + Pix first(); + void next(Pix& i); + <T>& key(Pix i); + <C>& contents(Pix i); + + Pix seek(<T&> key); + int contains(<T&> key); + + void clear(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + +inline <T><C>VHMap::~<T><C>VHMap() +{ + delete [] tab; + delete [] cont; + delete [] status; +} + +inline int <T><C>VHMap::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline <T>& <T><C>VHMap::key(Pix i) +{ + if (i == 0) error("null Pix"); + return *((<T>*)i); +} + +inline <C>& <T><C>VHMap::contents(Pix i) +{ + if (i == 0) error("null Pix"); + return cont[((unsigned)(i) - (unsigned)(tab)) / sizeof(<T>)]; +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VHSet.ccP b/gnu/lib/libg++/g++-include/gen/VHSet.ccP new file mode 100644 index 000000000000..a78b319834c1 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHSet.ccP @@ -0,0 +1,263 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "<T>.VHSet.h" + +/* codes for status fields */ + +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +<T>VHSet::<T>VHSet(unsigned int sz) +{ + tab = new <T>[size = sz]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +<T>VHSet::<T>VHSet(<T>VHSet& a) +{ + tab = new <T>[size = a.size]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + + +/* + * hashing method: double hash based on high bits of hash fct, + * followed by linear probe. Can't do too much better if table + * sizes not constrained to be prime. +*/ + + +static inline unsigned int doublehashinc(unsigned int h, unsigned int s) +{ + unsigned int dh = ((h / s) % s); + return (dh > 1)? dh : 1; +} + +Pix <T>VHSet::seek(<T&> key) +{ + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return 0; + else if (status[h] == VALIDCELL && <T>EQ(key, tab[h])) + return Pix(&tab[h]); + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + return 0; +} + + +Pix <T>VHSet::add(<T&> item) +{ + if (HASHTABLE_TOO_CROWDED(count, size)) + resize(); + + unsigned int bestspot = size; + unsigned int hashval = <T>HASH(item); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + { + if (bestspot >= size) bestspot = h; + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + } + else if (status[h] == DELETEDCELL) + { + if (bestspot >= size) bestspot = h; + } + else if (<T>EQ(tab[h],item)) + return Pix(&tab[h]); + + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } + tab[bestspot] = item; + status[bestspot] = VALIDCELL; + ++count; + return Pix(&tab[bestspot]); + +} + + +void <T>VHSet::del(<T&> key) +{ + unsigned int hashval = <T>HASH(key); + unsigned int h = hashval % size; + for (unsigned int i = 0; i <= size; ++i) + { + if (status[h] == EMPTYCELL) + return; + else if (status[h] == VALIDCELL && <T>EQ(key, tab[h])) + { + status[h] = DELETEDCELL; + --count; + return; + } + if (i == 0) + h = (h + doublehashinc(hashval, size)) % size; + else if (++h >= size) + h -= size; + } +} + + +void <T>VHSet::clear() +{ + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; +} + +void <T>VHSet::resize(unsigned int newsize) +{ + if (newsize <= count) + { + newsize = DEFAULT_INITIAL_CAPACITY; + while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1; + } + <T>* oldtab = tab; + char* oldstatus = status; + unsigned int oldsize = size; + tab = new <T>[size = newsize]; + status = new char[size]; + for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = 0; + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix <T>VHSet::first() +{ + for (unsigned int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void <T>VHSet::next(Pix& i) +{ + if (i == 0) return; + unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + +int <T>VHSet:: operator == (<T>VHSet& b) +{ + if (count != b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + for (i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0) + return 0; + return 1; + } +} + +int <T>VHSet::operator <= (<T>VHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (unsigned int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + return 1; + } +} + +void <T>VHSet::operator |= (<T>VHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (unsigned int i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL) add(b.tab[i]); +} + +void <T>VHSet::operator &= (<T>VHSet& b) +{ + if (&b == this || count == 0) + return; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +void <T>VHSet::operator -= (<T>VHSet& b) +{ + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) != 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +int <T>VHSet::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (unsigned int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} diff --git a/gnu/lib/libg++/g++-include/gen/VHSet.hP b/gnu/lib/libg++/g++-include/gen/VHSet.hP new file mode 100644 index 000000000000..b7b3a3578c5a --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VHSet.hP @@ -0,0 +1,96 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>VHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>VHSet_h 1 + +#include "<T>.Set.h" + + + +class <T>VHSet : public <T>Set +{ +protected: + <T>* tab; + char* status; + unsigned int size; + +public: + <T>VHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY); + <T>VHSet(<T>VHSet& a); + ~<T>VHSet(); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item); + + void operator |= (<T>VHSet& b); + void operator -= (<T>VHSet& b); + void operator &= (<T>VHSet& b); + + int operator == (<T>VHSet& b); + int operator != (<T>VHSet& b); + int operator <= (<T>VHSet& b); + + int capacity(); + void resize(unsigned int newsize = 0); + + int OK(); +}; + + +inline <T>VHSet::~<T>VHSet() +{ + delete [] tab; + delete status; +} + + +inline int <T>VHSet::capacity() +{ + return size; +} + +inline int <T>VHSet::contains(<T&> key) +{ + return seek(key) != 0; +} + +inline <T>& <T>VHSet::operator () (Pix i) +{ + if (i == 0) error("null Pix"); + return *((<T>*)i); +} + +inline int <T>VHSet::operator != (<T>VHSet& b) +{ + return ! ((*this) == b); +} + +#endif diff --git a/gnu/lib/libg++/g++-include/gen/VOHSet.ccP b/gnu/lib/libg++/g++-include/gen/VOHSet.ccP new file mode 100644 index 000000000000..c5d4557a4cb4 --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VOHSet.ccP @@ -0,0 +1,308 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Doug Schmidt + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include <stream.h> +#include "<T>.VOHSet.h" + + +/* codes for status fields */ +#define EMPTYCELL 0 +#define VALIDCELL 1 +#define DELETEDCELL 2 + + +<T>VOHSet::<T>VOHSet(int sz) +{ +// The size of the hash table is always the smallest power of 2 >= the size +// indicated by the user. This allows several optimizations, including +// the use of actual double hashing and elimination of the mod instruction. + + size = 1; + while (size < sz) size <<= 1; + tab = new <T>[size]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; +} + +<T>VOHSet::<T>VOHSet(<T>VOHSet& a) +{ + tab = new <T>[size = a.size]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; + for (Pix p = a.first(); p; a.next(p)) add(a(p)); +} + +Pix <T>VOHSet::seek(<T&> key) +{ +// Uses ordered double hashing to perform a search of the table. +// This greatly speeds up the average-case time for an unsuccessful search. + + unsigned hashval = <T>HASH(key); + + // We can avoid the mod operation since size is a power of 2. + unsigned h = hashval & (size - 1); + + // The increment must be odd, since all odd numbers are relatively + // prime to a power of 2!! + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + // There is always at least 1 empty cell, so this loop is guaranteed to halt! + while (status[h] != EMPTYCELL) + { + int cmp = <T>CMP (key, tab[h]); + if (cmp == 0) + { + if (status[h] == VALIDCELL) + return Pix(&tab[h]); + else + return 0; + } + else if (cmp > 0) + return 0; + else + h = ((h + inc) & (size - 1)); + } + return 0; +} + +// This adds an item if it doesn't already exist. By performing the initial +// comparison we assure that the table always contains at least 1 empty +// spot. This speeds up later searching by a constant factor. +// The insertion algorithm uses ordered double hashing. See Standish's +// 1980 ``Data Structure's Techniques'' book for details. + +Pix <T>VOHSet::add(<T&> x) +{ + if (size <= cnt+1) + resize(); + + unsigned hashval = <T>HASH(x); + unsigned h = hashval & (size - 1); + + if (status[h] != VALIDCELL) // save some work if possible + { + if (status[h] == EMPTYCELL) + cnt++; + count++; + tab[h] = x; + status[h] = VALIDCELL; + return Pix(&tab[h]); + } + int cmp = <T>CMP(x, tab[h]); + if (cmp == 0) + return Pix(&tab[h]); + + <T> item = x; + Pix mypix = 0; + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + for (;;) + { + if (cmp < 0) + { + <T> temp = tab[h]; + tab[h] = item; + item = temp; + if (mypix == 0) mypix = Pix(&tab[h]); + inc = ((((<T>HASH(item) / size) << 1) + 1) & (size - 1)); + h = ((h + inc) & (size - 1)); + if (status[h] != EMPTYCELL) cmp = <T>CMP(item, tab[h]); + } + else + h = ((h + inc) & (size - 1)); + if (status[h] != VALIDCELL) + { + if (status[h] == EMPTYCELL) + cnt++; + count++; + tab[h] = item; + status[h] = VALIDCELL; + return (mypix == 0)? Pix(&tab[h]) : mypix; + } + } +} + + +void <T>VOHSet::del(<T&> key) +{ +// This performs a deletion by marking the item's status field. +// Note that we only decrease the count, *not* the cnt, since this +// would cause trouble for subsequent steps in the algorithm. See +// Reingold and Hanson's ``Data Structure's'' book for a justification +// of this approach. + + unsigned hashval = <T>HASH(key); + unsigned h = hashval & (size - 1); + unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1)); + + while (status[h] != EMPTYCELL) + { + int cmp = <T>CMP(key, tab[h]); + if (cmp > 0) + h = ((h + inc) & (size - 1)); + else if (status[h] == VALIDCELL && cmp == 0) + { + status[h] = DELETEDCELL; + count--; + return; + } + else + return; + } +} + +void <T>VOHSet::clear() +{ + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; +} + +void <T>VOHSet::resize(int newsize) +{ + if (newsize <= count) + newsize = count; + int s = 1; + while (s <= newsize) s <<= 1; + newsize = s; + + <T>* oldtab = tab; + char* oldstatus = status; + int oldsize = size; + tab = new <T>[size = newsize]; + status = new char[size]; + for (int i = 0; i < size; ++i) status[i] = EMPTYCELL; + count = cnt = 0; + + for (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]); + delete [] oldtab; + delete oldstatus; +} + +Pix <T>VOHSet::first() +{ + for (int pos = 0; pos < size; ++pos) + if (status[pos] == VALIDCELL) return Pix(&tab[pos]); + return 0; +} + +void <T>VOHSet::next(Pix& i) +{ + if (i == 0) return; + int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1; + for (; pos < size; ++pos) + if (status[pos] == VALIDCELL) + { + i = Pix(&tab[pos]); + return; + } + i = 0; +} + + +int <T>VOHSet:: operator == (<T>VOHSet& b) +{ + if (count != b.count) + return 0; + else + { + for (int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + for (i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0) + return 0; + return 1; + } +} + +int <T>VOHSet:: operator != (<T>VOHSet& b) +{ + return !(*this == b); +} + +int <T>VOHSet::operator <= (<T>VOHSet& b) +{ + if (count > b.count) + return 0; + else + { + for (int i = 0; i < size; ++i) + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + return 0; + return 1; + } +} + +void <T>VOHSet::operator |= (<T>VOHSet& b) +{ + if (&b == this || b.count == 0) + return; + for (int i = 0; i < b.size; ++i) + if (b.status[i] == VALIDCELL) add(b.tab[i]); +} + +void <T>VOHSet::operator &= (<T>VOHSet& b) +{ + if (&b == this || count == 0) + return; + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) == 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +void <T>VOHSet::operator -= (<T>VOHSet& b) +{ + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL && b.seek(tab[i]) != 0) + { + status[i] = DELETEDCELL; + --count; + } + } +} + +int <T>VOHSet::OK() +{ + int v = tab != 0; + v &= status != 0; + int n = 0; + for (int i = 0; i < size; ++i) + { + if (status[i] == VALIDCELL) ++n; + else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL) + v = 0; + } + v &= n == count; + if (!v) error("invariant failure"); + return v; +} + + + diff --git a/gnu/lib/libg++/g++-include/gen/VOHSet.hP b/gnu/lib/libg++/g++-include/gen/VOHSet.hP new file mode 100644 index 000000000000..94decaad123b --- /dev/null +++ b/gnu/lib/libg++/g++-include/gen/VOHSet.hP @@ -0,0 +1,88 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + based on code by Doug Schmidt + +This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef _<T>VOHSet_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _<T>VOHSet_h 1 + +#include "<T>.Set.h" + + + +class <T>VOHSet : public <T>Set +{ + <T>* tab; + char* status; + int size; + int cnt; // keeps track of VALIDCELLs and DELETEDCELLs + +public: + <T>VOHSet(int sz = DEFAULT_INITIAL_CAPACITY); + <T>VOHSet(<T>VOHSet&); + ~<T>VOHSet(); + + Pix add(<T&> item); + void del(<T&> item); + int contains(<T&> item); + + void clear(); + + Pix first(); + void next(Pix& i); + <T>& operator () (Pix i); + Pix seek(<T&> item); + + void operator |= (<T>VOHSet& b); + void operator -= (<T>VOHSet& b); + void operator &= (<T>VOHSet& b); + + int operator == (<T>VOHSet& b); + int operator != (<T>VOHSet& b); + int operator <= (<T>VOHSet& b); + + int capacity(); + void resize(int newsize = 0); + + int OK(); +}; + + +inline <T>VOHSet::~<T>VOHSet() +{ + delete [] tab; + delete status; +} + + +inline int <T>VOHSet::contains(<T&> key) +{ + return seek(key) != 0; +} + + +inline <T>& <T>VOHSet::operator () (Pix p) +{ + if (p == 0) error("null Pix"); |