GC old gcc 2.7.2.2.
This commit is contained in:
parent
178fc3cc05
commit
1343ef3796
11
Makefile
11
Makefile
@ -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.
|
||||
|
@ -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")
|
||||
|
@ -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.
|
@ -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
|
@ -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.
|
||||
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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"
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
#include "<T>.DLDeque.h"
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
#include "<T>.FPQueue.h"
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
#include "<T>.FPStack.h"
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
@ -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 */
|
@ -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 */
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
#include "<T>.SLQueue.h"
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
#include "<T>.SLStack.h"
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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"
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user