GC old gcc 2.7.2.2.

This commit is contained in:
tv 1998-12-12 23:44:22 +00:00
parent 178fc3cc05
commit 1343ef3796
652 changed files with 6 additions and 452428 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.74 1998/12/07 01:42:34 simonb Exp $
# $NetBSD: Makefile,v 1.75 1998/12/12 23:44:22 tv Exp $
.include <bsd.own.mk> # for configuration variables.
@ -54,7 +54,7 @@ build: beforeinstall
.if !defined(UPDATE)
${MAKE} cleandir
.endif
.if defined(USE_EGCS) && empty(HAVE_GCC28)
.if empty(HAVE_GCC28)
.if defined(DESTDIR)
@echo "*** CAPUTE!"
@echo " You attempted to compile the world with egcs. You must"
@ -73,13 +73,6 @@ build: beforeinstall
${MAKE} depend && ${MAKE} NOMAN= && ${MAKE} NOMAN= install)
(cd ${.CURDIR}/gnu/lib && \
${MAKE} depend && ${MAKE} NOMAN= && ${MAKE} NOMAN= install)
.if !defined(USE_EGCS)
.if (${MACHINE_ARCH} != "alpha") && \
(${MACHINE_ARCH} != "powerpc")
(cd ${.CURDIR}/gnu/usr.bin/gcc/libgcc && \
${MAKE} depend && ${MAKE} NOMAN= && ${MAKE} NOMAN= install)
.endif
.endif
.if exists(domestic) && !defined(EXPORTABLE_SYSTEM)
# libtelnet depends on libdes and libkrb. libkrb depends on
# libcom_err.

View File

@ -1,14 +1,6 @@
# $NetBSD: Makefile,v 1.16 1998/08/28 15:34:24 tv Exp $
# $NetBSD: Makefile,v 1.17 1998/12/12 23:50:45 tv Exp $
# XXX Temporary for USE_EGCS
.include <bsd.own.mk>
SUBDIR+= libmalloc
.ifdef USE_EGCS
SUBDIR+= libg2c libgcc libobjc libstdc++
.else
SUBDIR+= libg++
.endif
SUBDIR+= libg2c libgcc libmalloc libobjc libstdc++
# XXX Until our bintuils is upgraded
.if (${MACHINE_ARCH} != "powerpc")

View File

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,51 +0,0 @@
# $NetBSD: Makefile,v 1.26 1998/10/14 15:05:30 tv Exp $
HAVE_GCC28!= ${CXX} --version | egrep "^(2\.8|egcs)" ; echo
.if empty(HAVE_GCC28)
SUBDIR= libstdc++
HEADERS= cassert cctype cerrno cfloat ciso646 climits clocale cmath complex \
csetjmp csignal cstdarg cstddef cstdio cstdlib cstring ctime \
cwchar cwctype new stddef string exception stdexcept typeinfo \
algorithm deque list map queue set stack vector utility functional \
iterator memory numeric
INCS= _G_config.h
INCSDIR= /usr/include/${MACHINE}
incinstall:: other-includes
other-includes:
@echo installing includes from libio
@(cd libio ; for j in *.h; do \
cmp -s $$j ${DESTDIR}/usr/include/g++/$$j || \
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j \
${DESTDIR}/usr/include/g++/$$j; \
done)
@echo installing includes from libstdc++/std
@(cd libstdc++/std ; for j in *.h *.cc; do \
cmp -s $$j ${DESTDIR}/usr/include/g++/std/$$j || \
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j \
${DESTDIR}/usr/include/g++/std/$$j; \
done)
@echo installing includes from libstdc++/stl
@(cd libstdc++/stl ; for j in *.h *.cc; do \
cmp -s $$j ${DESTDIR}/usr/include/g++/$$j || \
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j \
${DESTDIR}/usr/include/g++/$$j; \
done)
@echo installing includes from libstdc++
@(cd libstdc++ ; for j in *.h ${HEADERS}; do \
cmp -s $$j ${DESTDIR}/usr/include/g++/$$j || \
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j \
${DESTDIR}/usr/include/g++/$$j; \
done)
.include <bsd.inc.mk>
.include <bsd.subdir.mk>
.else
.include <bsd.own.mk>
${TARGETS}:
.endif

View File

@ -1,5 +0,0 @@
This is libg++ 2.7.2 from the Free Software Foundation.
Complete, unmodified libg++ sources are available from
prep.ai.mit.edu and prep's mirrors.

View File

@ -1,121 +0,0 @@
/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
#ifndef _G_config_h
#define _G_config_h
#define _G_LIB_VERSION "2.7.2"
#if ! defined(__alpha__) && !defined(__mips) /* ELF */
#define _G_NAMES_HAVE_UNDERSCORE 1
#else /* ELF */
#define _G_NAMES_HAVE_UNDERSCORE 0
#endif /* ELF */
#define _G_VTABLE_LABEL_HAS_LENGTH 1
#if ! defined(__alpha__) && !defined(__mips) /* ELF */
#define _G_VTABLE_LABEL_PREFIX "__vt$"
#else /* ELF */
#define _G_VTABLE_LABEL_PREFIX "_vt$"
#endif /* ELF */
#define _G_HAVE_ST_BLKSIZE 1
#ifndef __alpha__
typedef unsigned long _G_clock_t;
#else /* __alpha__ */
typedef int _G_clock_t;
#endif /* __alpha__ */
typedef int _G_dev_t;
#ifndef __alpha__
typedef long long _G_fpos_t;
#else /* __alpha__ */
typedef long _G_fpos_t;
#endif /* __alpha__ */
typedef unsigned int _G_gid_t;
typedef unsigned int _G_ino_t;
typedef unsigned short _G_mode_t;
typedef unsigned short _G_nlink_t;
#ifndef __alpha__
typedef long long _G_off_t;
#else /* __alpha__ */
typedef long _G_off_t;
#endif /* __alpha__ */
typedef int _G_pid_t;
#ifndef __PTRDIFF_TYPE__
#ifndef __alpha__
#define __PTRDIFF_TYPE__ int
#else /* __alpha__ */
#define __PTRDIFF_TYPE__ long
#endif /* __alpha__ */
#endif
typedef __PTRDIFF_TYPE__ _G_ptrdiff_t;
typedef unsigned int _G_sigset_t;
#ifndef __SIZE_TYPE__
#ifndef __alpha__
#define __SIZE_TYPE__ unsigned int
#else /* __alpha__ */
#define __SIZE_TYPE__ unsigned long
#endif /* __alpha__ */
#endif
typedef __SIZE_TYPE__ _G_size_t;
#ifndef __alpha__
typedef long _G_time_t;
#else /* __alpha__ */
typedef int _G_time_t;
#endif /* __alpha__ */
typedef unsigned int _G_uid_t;
typedef int _G_wchar_t;
#ifndef __alpha__
typedef int _G_ssize_t;
typedef int /* default */ _G_wint_t;
#ifndef __powerpc__
typedef char * _G_va_list;
#else
#define _G_NEED_STDARG_H 1
#endif /* __powerpc__ */
#else /* __alpha__ */
typedef long _G_ssize_t;
typedef unsigned int /* default */ _G_wint_t;
#define _G_NEED_STDARG_H
#define _G_va_list va_list
#endif /* __alpha__ */
#define _G_signal_return_type void
#define _G_sprintf_return_type int
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
typedef int _G_int8_t __attribute__((__mode__(__QI__)));
typedef unsigned int _G_uint8_t __attribute__((__mode__(__QI__)));
typedef int _G_int16_t __attribute__((__mode__(__HI__)));
typedef unsigned int _G_uint16_t __attribute__((__mode__(__HI__)));
typedef int _G_int32_t __attribute__((__mode__(__SI__)));
typedef unsigned int _G_uint32_t __attribute__((__mode__(__SI__)));
typedef int _G_int64_t __attribute__((__mode__(__DI__)));
typedef unsigned int _G_uint64_t __attribute__((__mode__(__DI__)));
#else
typedef short _G_int16_t;
typedef unsigned short _G_uint16_t;
typedef int _G_int32_t;
typedef unsigned int _G_uint32_t;
#endif
#define _G_BUFSIZ 1024
#define _G_FOPEN_MAX 20
#define _G_FILENAME_MAX 1024
#define _G_NULL 0 /* default */
#if defined (__cplusplus) || defined (__STDC__)
#define _G_ARGS(ARGLIST) ARGLIST
#else
#define _G_ARGS(ARGLIST) ()
#endif
#if !defined (__GNUG__) || defined (__STRICT_ANSI__)
#define _G_NO_NRV
#endif
#if !defined (__GNUG__)
#define _G_NO_EXTERN_TEMPLATES
#endif
#define _G_HAVE_ATEXIT 1
#define _G_HAVE_SYS_RESOURCE 1
#define _G_HAVE_SYS_TIMES 1
#define _G_HAVE_SYS_SOCKET 1
#define _G_HAVE_SYS_CDEFS 1
#define _G_HAVE_SYS_WAIT 1
#define _G_HAVE_UNISTD 1
#define _G_HAVE_DIRENT 1
#define _G_HAVE_CURSES 1
#define _G_MATH_H_INLINES 0
#define _G_HAVE_BOOL 1
#endif /* !_G_config_h */

View File

@ -1,614 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,141 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:lt(l), rt(r), item(h), cont(c), 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);
inline ~<T><C>AVLMap();
<C>& operator [] (<T&> key);
void del(<T&> key);
inline Pix first();
inline void next(Pix& i);
inline <T>& key(Pix i);
inline <C>& contents(Pix i);
Pix seek(<T&> key);
inline int contains(<T&> key);
inline 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

View File

@ -1,892 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,152 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:lt(l), rt(r), item(h), 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);
inline ~<T>AVLSet();
Pix add(<T&> item);
void del(<T&> item);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <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

View File

@ -1,397 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 = (const <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;
}

View File

@ -1,118 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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();
const <T>* vec() const;
<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 = (const <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 const <T>* <T>AVec::vec() const
{
return s;
}
inline void <T>AVec::check_len(int l)
{
if (l != len)
error("nonconformant vectors.");
}
#endif

View File

@ -1,377 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
for (;;)
{
int comp = <T>CMP(t->item, item);
if (comp == 0)
return Pix(t);
else if (comp > 0)
t = t->lt;
else
t = t->rt;
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;
}
}
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;
}

View File

@ -1,152 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:lt(l), rt(r), par(p), item(h) {}
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);
inline ~<T>BSTSet();
Pix add(<T&> item);
void del(<T&> item);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <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

View File

@ -1,74 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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();
}
}

View File

@ -1,79 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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:
inline 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
inline 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

View File

@ -1,210 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
{
<T>CHNode* p;
for (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;
}

View File

@ -1,76 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>CHBag();
Pix add(<T&> item);
void del(<T&> item);
void remove(<T&>item);
int nof(<T&> item);
inline int contains(<T&> item);
void clear();
Pix first();
void next(Pix& i);
inline <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

View File

@ -1,168 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
<T><C>CHNode* t;
for (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)
{
<T><C>CHNode* p;
for (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;
}

View File

@ -1,104 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
: tl(t), hd(h), cont(c) {}
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);
inline ~<T><C>CHMap();
<C>& operator [] (<T&> key);
void del(<T&> key);
Pix first();
void next(Pix& i);
inline <T>& key(Pix i);
inline <C>& contents(Pix i);
Pix seek(<T&> key);
inline 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

View File

@ -1,21 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include "<T>.CHNode.h"

View File

@ -1,43 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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) :tl(t), hd(h) {}
inline <T>CHNode::~<T>CHNode() {}
typedef <T>CHNode* <T>CHNodePtr;
#endif

View File

@ -1,273 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
<T>CHNode* t;
for (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 (unsigned int 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)
{
<T>CHNode* p;
for (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;
}

View File

@ -1,84 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>CHSet();
Pix add(<T&> item);
void del(<T&> item);
inline int contains(<T&> item);
void clear();
Pix first();
void next(Pix& i);
inline <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

View File

@ -1,4 +0,0 @@
#ifdef __GNUG__
#pragma implementation
#endif
#include "<T>.DLDeque.h"

View File

@ -1,130 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>DLDeque();
void operator = (const <T>DLDeque&);
inline void push(<T&> item); // insert at front
inline void enq(<T&> item); // insert at rear
inline <T>& front();
inline <T>& rear();
inline <T> deq();
inline void del_front();
inline void del_rear();
inline void clear();
inline int empty();
inline int full();
inline int length();
inline 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

View File

@ -1,339 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <limits.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 = LONG_MAX; // 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;
}

View File

@ -1,157 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:bk(p), fd(n), hd(h) {}
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

View File

@ -1,11 +0,0 @@
#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);
}

View File

@ -1,57 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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

View File

@ -1,4 +0,0 @@
#ifdef __GNUG__
#pragma implementation
#endif
#include "<T>.FPQueue.h"

View File

@ -1,112 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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

View File

@ -1,4 +0,0 @@
#ifdef __GNUG__
#pragma implementation
#endif
#include "<T>.FPStack.h"

View File

@ -1,114 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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

View File

@ -1,167 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,253 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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&)
inline ~<T>FPlex();
void operator= (const <T>FPlex&);
// virtuals
inline <T>& high_element ();
inline <T>& low_element ();
inline const <T>& high_element () const;
inline const <T>& low_element () const;
inline Pix first() const;
inline Pix last() const;
inline void prev(Pix& ptr) const;
inline void next(Pix& ptr) const;
inline int owns(Pix p) const;
inline <T>& operator () (Pix p);
inline const <T>& operator () (Pix p) const;
inline int low() const;
inline int high() const;
inline int valid(int idx) const;
inline void prev(int& idx) const;
inline void next(int& x) const;
inline <T>& operator [] (int index);
inline const <T>& operator [] (int index) const;
inline int Pix_to_index(Pix p) const;
inline Pix index_to_Pix(int idx) const;
inline int can_add_high() const;
inline int can_add_low() const;
inline int full() const;
inline int add_high(const <T&> elem);
inline int del_high ();
inline int add_low (const <T&> elem);
inline 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

View File

@ -1,972 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 = (const <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)
{
<T>ListNode* p;
for ( 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)
{
<T>ListNode* p;
for ( p = P; n-- > 0; p = p->tl);
return (p->hd);
}
int operator == (const <T>List& x, const <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) const
{
const <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;
// Former bug: targ can be a reference to a element in this list
// So do not dereference a element if targ is the element,
// until targ is no longer needed, as dereferencing it may destroy it.
<T>ListNode* to_be_dereferenced = 0;
for (;;)
{
if (h == &Nil<T>ListNode)
{
P = h;
if (to_be_dereferenced)
dereference(to_be_dereferenced);
return;
}
else if (<T>EQ(h->hd, targ))
{
<T>ListNode* nxt = h->tl;
reference(nxt);
if ((&targ == &h->hd) && (to_be_dereferenced == 0))
to_be_dereferenced = h;
else
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);
if ((&targ == &p->hd) && (to_be_dereferenced == 0))
to_be_dereferenced = p;
else
dereference(p);
trail->tl = nxt;
p = nxt;
}
else
{
trail = p;
p = p->tl;
}
}
P = h;
if (to_be_dereferenced)
dereference(to_be_dereferenced);
}
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(const <T>List& x)
{
const <T>ListNode* a = x.P;
if (a == &Nil<T>ListNode)
return <T>List(&Nil<T>ListNode);
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;
}

View File

@ -1,279 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _<T>List_h
#ifdef __GNUG__
#pragma interface
#endif
#define _<T>List_h 1
#include <Pix.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
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, const <T>List& tl);
<T>List(<T>List& a);
<T>List(Pix p);
~<T>List();
<T>List& operator = (const <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(const <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 == (const <T>List& a, const <T>List& b);
friend inline int operator != (const <T>List& a, const <T>List& b);
Pix first();
void next(Pix& p);
Pix seek(<T&> item) const;
<T>& operator () (Pix p);
const <T>& operator () (Pix p) const;
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(const <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, const <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 != (const <T>List& x, const <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 const <T>& <T>List::operator () (Pix p) const
{
return ((const <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

View File

@ -1,848 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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] == ~0UL) ++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);
<T>MChunk* t;
for (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();
<T>MChunk* t;
for (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;
<T>MChunk* t;
for (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;
}

View File

@ -1,414 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
inline void mark(int); // bitmap operations
inline void free(int);
inline 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);
inline ~<T>MChunk();
// virtuals
int first_index() const;
int last_index() const;
inline int succ(int idx) const;
inline int pred(int idx) const;
<T>* first_pointer() const;
<T>* last_pointer() const;
<T>* succ(<T>*) const;
<T>* pred(<T>*) const;
inline int empty() const;
inline int full() const;
inline int valid_index(int i) const;
inline int valid_pointer(const <T>* p) const;
inline <T>* grow_high ();
inline <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
inline <T>& high_element ();
inline <T>& low_element ();
inline const <T>& high_element () const;
inline const <T>& low_element () const;
inline Pix first() const;
inline Pix last() const ;
void prev(Pix& ptr) const;
void next(Pix& ptr) const;
int owns(Pix p) const;
inline <T>& operator () (Pix p);
inline const <T>& operator () (Pix p) const;
inline int low() const;
inline int high() const;
int valid(int idx) const;
inline void prev(int& idx) const;
inline void next(int& x) const;
inline <T>& operator [] (int index);
inline const <T>& operator [] (int index) const;
inline int Pix_to_index(Pix p) const;
inline Pix index_to_Pix(int idx) const;
inline int can_add_high() const;
inline int can_add_low() const;
inline 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

View File

@ -1,59 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <builtin.h>
#include "<T>.<C>.Map.h"
Pix <T><C>Map::seek(<T&> item)
{
Pix i;
for (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);
}

View File

@ -1,87 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline virtual ~<T><C>Map();
int length() const; // current number of items
int empty() const;
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() const
{
return count;
}
inline int <T><C>Map::empty() const
{
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

View File

@ -1,196 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,91 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline int contains(<T&> item);
int nof(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <T>& operator () (Pix i);
inline 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

View File

@ -1,321 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,101 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <T>& operator () (Pix i);
inline 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

View File

@ -1,221 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,73 +0,0 @@
#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);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <T>& operator () (Pix i);
inline 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

View File

@ -1,280 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,102 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <T>& operator () (Pix i);
inline 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

View File

@ -1,339 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <limits.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 (int 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 = INT_MAX;
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 = LONG_MAX; // 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;
}

View File

@ -1,108 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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&);
inline ~<T>PHPQ();
Pix enq(<T&> item);
inline <T> deq();
inline <T>& front();
void del_front();
inline int contains(<T&> item);
void clear();
Pix first();
void next(Pix& i);
inline <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

View File

@ -1,63 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
{
Pix i;
for (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);
}

View File

@ -1,78 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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();
inline 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

View File

@ -1,32 +0,0 @@
/* : 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 */

View File

@ -1,79 +0,0 @@
/* : 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 */

View File

@ -1,222 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,494 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
inline virtual int empty() const ;
inline 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;
inline virtual int first_index() const; // lowest valid index or fence if none
inline 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
inline 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;
inline 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
inline virtual int succ(int idx) const; // next valid index or fence if none
inline virtual int pred(int idx) const; // previous index or low - 1 if none
inline virtual <T>* first_pointer() const; // pointer to first valid pos or 0
inline virtual <T>* last_pointer() const; // pointer to first valid pos or 0
inline virtual <T>* succ(<T>* p) const; // next pointer or 0
inline virtual <T>* pred(<T>* p) const; // previous pointer or 0
// modification
inline virtual <T>* grow_high (); // return spot to add an element
inline virtual <T>* grow_low ();
inline virtual void shrink_high (); // logically delete top index
inline 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

View File

@ -1,14 +0,0 @@
#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);
}

View File

@ -1,51 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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

View File

@ -1,690 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,147 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:lt(l), rt(r), item(h), cont(c), 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);
inline ~<T><C>RAVLMap();
<C>& operator [] (<T&> key);
void del(<T&> key);
inline Pix first();
inline void next(Pix& i);
inline <T>& key(Pix i);
inline <C>& contents(Pix i);
Pix seek(<T&> key);
inline int contains(<T&> key);
Pix ranktoPix(int i);
int rankof(<T&> key);
inline 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

View File

@ -1,477 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,257 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
inline 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&);
inline ~<T>RPlex();
void operator= (const <T>RPlex&);
// virtuals
inline <T>& high_element ();
inline <T>& low_element ();
inline const <T>& high_element () const;
inline const <T>& low_element () const;
inline Pix first() const;
inline Pix last() const;
inline void prev(Pix& ptr) const;
inline void next(Pix& ptr) const;
int owns(Pix p) const;
inline <T>& operator () (Pix p);
inline const <T>& operator () (Pix p) const;
inline int low() const;
inline int high() const;
inline int valid(int idx) const;
inline void prev(int& idx) const;
inline void next(int& x) const;
inline <T>& operator [] (int index);
inline const <T>& operator [] (int index) const;
inline int Pix_to_index(Pix p) const;
inline Pix index_to_Pix(int idx) const;
inline int can_add_high() const;
inline int can_add_low() const;
inline 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

View File

@ -1,105 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
}
}
}
}

View File

@ -1,96 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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&);
inline Pix add(<T&> item);
void del(<T&> item);
void remove(<T&>item);
inline int contains(<T&> item);
int nof(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <T>& operator () (Pix i);
inline 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

View File

@ -1,292 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <limits.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 = LONG_MAX; // 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;
}

View File

@ -1,137 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:tl(t), hd(h) {}
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

View File

@ -1,4 +0,0 @@
#ifdef __GNUG__
#pragma implementation
#endif
#include "<T>.SLQueue.h"

View File

@ -1,108 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>SLQueue();
void operator = (const <T>SLQueue&);
inline void enq(<T&> item);
inline <T> deq();
inline <T>& front();
inline void del_front();
inline void clear();
inline int empty();
inline int full();
inline int length();
inline 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

View File

@ -1,77 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
{
Pix i;
for (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);
}
}
}

View File

@ -1,87 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <T>& operator () (Pix i);
inline 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

View File

@ -1,4 +0,0 @@
#ifdef __GNUG__
#pragma implementation
#endif
#include "<T>.SLStack.h"

View File

@ -1,109 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>SLStack();
void operator = (const <T>SLStack&);
inline void push(<T&> item);
inline <T> pop();
inline <T>& top();
inline void del_top();
inline int empty();
inline int full();
inline int length();
inline void clear();
inline 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

View File

@ -1,117 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <builtin.h>
#include "<T>.Set.h"
Pix <T>Set::seek(<T&> item)
{
Pix i;
for (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);
}

View File

@ -1,78 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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:
inline 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

View File

@ -1,322 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,171 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <limits.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

View File

@ -1,307 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,176 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <limits.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

View File

@ -1,395 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,187 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <limits.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

View File

@ -1,445 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,126 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>SplayBag();
Pix add(<T&> item);
inline void del(<T&> item);
void remove(<T&>item);
int nof(<T&> item);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <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

View File

@ -1,401 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,154 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:lt(l), rt(r), par(0), item(h), cont(c) {}
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);
inline ~<T><C>SplayMap();
<C>& operator [] (<T&> key);
void del(<T&> key);
inline Pix first();
inline void next(Pix& i);
inline <T>& key(Pix i);
inline <C>& contents(Pix i);
Pix seek(<T&> key);
inline int contains(<T&> key);
inline 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

View File

@ -1,21 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include "<T>.SplayNode.h"

View File

@ -1,44 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
:lt(l), rt(r), par(0), item(h) {}
inline <T>SplayNode::~<T>SplayNode() {}
typedef <T>SplayNode* <T>SplayNodePtr;
#endif

View File

@ -1,523 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,123 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline virtual ~<T>SplayPQ();
Pix enq(<T&> item);
<T> deq();
<T>& front();
void del_front();
inline int contains(<T&> item);
inline void clear();
inline Pix first();
Pix last();
inline void next(Pix& i);
void prev(Pix& i);
inline <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

View File

@ -1,499 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
}

View File

@ -1,145 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>SplaySet();
Pix add(<T&> item);
void del(<T&> item);
inline int contains(<T&> item);
inline void clear();
inline Pix first();
inline void next(Pix& i);
inline <T>& operator () (Pix i);
Pix seek(<T&> item);
Pix last();
void prev(Pix& i);
<T>SplaySet& operator = (const <T>SplaySet& b);
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 <T>SplaySet& <T>SplaySet::operator = (const <T>SplaySet& b)
{
if (this != &b)
{
_kill (root);
count = b.count;
root = _copy (b.root);
}
return *this;
}
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

View File

@ -1,11 +0,0 @@
#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);
}

View File

@ -1,51 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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

View File

@ -1,264 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 (unsigned int 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;
}

View File

@ -1,84 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>VHBag();
Pix add(<T&> item);
void del(<T&> item);
void remove(<T&>item);
int nof(<T&> item);
inline int contains(<T&> item);
void clear();
Pix first();
void next(Pix& i);
inline <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

View File

@ -1,210 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 (unsigned int 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;
}

View File

@ -1,84 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T><C>VHMap();
<C>& operator [] (<T&> key);
void del(<T&> key);
Pix first();
void next(Pix& i);
inline <T>& key(Pix i);
inline <C>& contents(Pix i);
Pix seek(<T&> key);
inline 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

View File

@ -1,263 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 (unsigned int 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 (unsigned int 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;
}

View File

@ -1,96 +0,0 @@
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
inline ~<T>VHSet();
Pix add(<T&> item);
void del(<T&> item);
inline int contains(<T&> item);
void clear();
Pix first();
void next(Pix& i);
inline <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

Some files were not shown because too many files have changed in this diff Show More