diff --git a/darkice/tags/darkice-0_2/AUTHORS b/darkice/tags/darkice-0_2/AUTHORS new file mode 100644 index 0000000..0276ca3 --- /dev/null +++ b/darkice/tags/darkice-0_2/AUTHORS @@ -0,0 +1,4 @@ +DarkIce is being written by: + + Akos Maroy, darkeye@users.sourceforge.net + diff --git a/darkice/tags/darkice-0_2/COPYING b/darkice/tags/darkice-0_2/COPYING new file mode 100644 index 0000000..c93d9fb --- /dev/null +++ b/darkice/tags/darkice-0_2/COPYING @@ -0,0 +1,389 @@ +Contents +-------- + +1. Standard Template Library license +2. GNU General Public License + + + +1. Standard Template Library license +------------------------------------ + +Sources found in the stl directory are covered under the following +license: + + Copyright (c) 1996 + Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, distribute and sell this software + and its documentation for any purpose is hereby granted without fee, + provided that the above copyright notice appear in all copies and + that both that copyright notice and this permission notice appear + in supporting documentation. Silicon Graphics makes no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied warranty. + + + Copyright (c) 1994 + Hewlett-Packard Company + + Permission to use, copy, modify, distribute and sell this software + and its documentation for any purpose is hereby granted without fee, + provided that the above copyright notice appear in all copies and + that both that copyright notice and this permission notice appear + in supporting documentation. Hewlett-Packard Company makes no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied warranty. + + + + + +2. GNU General Public License +----------------------------- + +All source code in the src directory is covered under the +GNU General Public License (GNU GPL). + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + + 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. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year 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. + + , 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. diff --git a/darkice/tags/darkice-0_2/ChangeLog b/darkice/tags/darkice-0_2/ChangeLog new file mode 100644 index 0000000..f6c65d2 --- /dev/null +++ b/darkice/tags/darkice-0_2/ChangeLog @@ -0,0 +1,5 @@ + +13-11-2000, Akos Maroy, darkeye@users.sourceforge.net + + Initial release. Supports the lame encoder. + diff --git a/darkice/tags/darkice-0_2/INSTALL b/darkice/tags/darkice-0_2/INSTALL new file mode 100644 index 0000000..b42a17a --- /dev/null +++ b/darkice/tags/darkice-0_2/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/darkice/tags/darkice-0_2/Makefile.am b/darkice/tags/darkice-0_2/Makefile.am new file mode 100644 index 0000000..070742b --- /dev/null +++ b/darkice/tags/darkice-0_2/Makefile.am @@ -0,0 +1,11 @@ +SUBDIRS = src +EXTRA_DIST = stl doc darkice.cfg + +dist-hook: kdocs + +kdocs: src + cd src; kdoc --private --strip-h-path --name DarkIce --outputdir ../doc/ *.h + +kdocs_clean: + rm -rf doc/ + diff --git a/darkice/tags/darkice-0_2/NEWS b/darkice/tags/darkice-0_2/NEWS new file mode 100644 index 0000000..8646c64 --- /dev/null +++ b/darkice/tags/darkice-0_2/NEWS @@ -0,0 +1,9 @@ + +18-11-2000: DarkIce 0.2 released + + o code cleanup + o first real tests made + + +13-11-2000: DarkIce 0.1 released + diff --git a/darkice/tags/darkice-0_2/README b/darkice/tags/darkice-0_2/README new file mode 100644 index 0000000..deabca3 --- /dev/null +++ b/darkice/tags/darkice-0_2/README @@ -0,0 +1,134 @@ +DarkIce 0.2 live audio streamer, http://darkice.sourceforge.net +Copyright (C) 2000, Tyrell Hungary, http://tyrell.hu + + +Contents +-------- + +1. Compiling and installing +2. Configuration file format +2.1 Section [general] +2.2 Section [input] +2.3 Section [lamex] +3. Supported encoders +4. Kown bugs and issues + + + +1. Compiling and installing +--------------------------- + +On how to compile and install, please read the file INSTALL. If you're +impatient, try: + +./configure +make +make install + +The executable built is src/darkice. + +For command line syntax, try: + +darkice --help + +It is recommended to run DarkIce as root, with a nice level of -10, like: + +nice --10 darkice [options] + + +2. Configuration file format +---------------------------- + +DarkIce requires a configuration file. Please take a look at the supplied +darkice.cfg sample configuration file. + +The file has to following general format: + +[section1] +# this is a whole line comment +key = value +an ugly key name = long value # this end is a comment too + +[section2] +# this is a whole line comment in section 2 +key = value +an ugly key name = long value # this end is a comment too + + +In particular, the following sections and values are required: + + +2.1 Section [general] +--------------------- +This section describes general operational parameters. + +Required values: + +duration Time for DarkIce to run, in seconds. +bufferSecs Data read from the sound card is buffered before sent to + the mp3 encoder. Each buffer will be able to hold this + many seconds of samples. + + +2.2 Section [input] +--------------------- +This section describes the input. + +Required values: + +device OSS DSP audio device to record from (e.g. /dev/dsp) +sampleRate The sample rate to record with, samples per second + (e.g. 44100 for 44.1kHz CD-quality audio) +bitsPerSample Bites to use for each sample (e.g. 8 bits or 16 bits) +channel Number of channels to record (e.g. 1 for mono, 2 for stereo) + + +2.3 Section [lamex] +--------------------- +This section describes an output to an IceCast server, while encoding +with a lame encoder. There may be at most 8 outputs, numbered from 0 ... 7. +The number is included in the section name (e.g. [lame0] ... [lame7]). + +Required values: + +encoder The command used to invoke the encoder +bitrate Bit rate to encode to in kBits / sec (e.g. 96) +server The IceCast server's name (e.g. yp.sourserver.com) +port The port to connect to the IceCast server (e.g. 8000) +password The password to use to connet to the IceCast server +mountPoint Mount point for the stream on the server +name Name of the stream +description Description of the stream +url Url related to the stream +genre Genre of the stream +public "yes" or "no", wether the stream is public + +Optional values: + +remoteDumpFile The file the IceCast server should dump the contents of + this stream on its side. +lowpass Lowpass filter setting for the lame encoder. If not set, + the encoder's default behaviour is used +highpass Highpass filter setting for the lame encoder. If not set, + the encoder's default behaviour is used + + + +3. Supported encoders +--------------------- + +Currently the lame encoder is supported (http://www.mp3dev.org/mp3/). +Tests were made with version 3.86. + + + +4. Kown bugs and issues +----------------------- + +Lots of bugs, this is the first release. + +You must have write permissions in the directory you execute DarkIce. + +DarkIce was only tested under RedHat Linux + + diff --git a/darkice/tags/darkice-0_2/aclocal.m4 b/darkice/tags/darkice-0_2/aclocal.m4 new file mode 100644 index 0000000..f23ba29 --- /dev/null +++ b/darkice/tags/darkice-0_2/aclocal.m4 @@ -0,0 +1,127 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN(AM_CONFIG_HEADER, +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + diff --git a/darkice/tags/darkice-0_2/configure.h.in b/darkice/tags/darkice-0_2/configure.h.in new file mode 100644 index 0000000..138e711 --- /dev/null +++ b/darkice/tags/darkice-0_2/configure.h.in @@ -0,0 +1,74 @@ +/* configure.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SOUNDCARD_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + diff --git a/darkice/tags/darkice-0_2/configure.in b/darkice/tags/darkice-0_2/configure.in new file mode 100644 index 0000000..e23abe4 --- /dev/null +++ b/darkice/tags/darkice-0_2/configure.in @@ -0,0 +1,19 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src/DarkIce.cpp) +AM_INIT_AUTOMAKE(darkice, 0.2) + +AM_CONFIG_HEADER(configure.h) + +AC_PROG_CXX +AC_PROG_INSTALL + +dnl AC_STDC_HEADERS +AC_HAVE_HEADERS(errno.h fcntl.h stdio.h stdlib.h string.h unistd.h limits.h) +AC_HAVE_HEADERS(getopt.h signal.h time.h sys/time.h sys/types.h sys/soundcard.h) +AC_HAVE_HEADERS(netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/stat.h) +AC_HEADER_SYS_WAIT() + +AC_TYPE_PID_T() +AC_TYPE_SIZE_T() + +AC_OUTPUT(Makefile src/Makefile) diff --git a/darkice/tags/darkice-0_2/darkice.cfg b/darkice/tags/darkice-0_2/darkice.cfg new file mode 100644 index 0000000..b64f051 --- /dev/null +++ b/darkice/tags/darkice-0_2/darkice.cfg @@ -0,0 +1,41 @@ +[general] +duration = 60 +bufferSecs = 5 + +[input] +device = /dev/dsp +sampleRate = 22050 +bitsPerSample = 16 +channel = 2 + +[lame0] +encoder = notlame +bitrate = 96 + +server = yp.yourserver.com +port = 8000 +password = hackme +mountPoint = live96 +name = DarkIce trial +description = This is only a trial +url = http://www.yourserver.com +genre = live +public = no +remoteDumpFile = /tmp/live96.mp3 + +[lame1] +encoder = notlame +bitrate = 24 +lowpass = 8500 + +server = yp.yourserver.com +port = 8000 +password = hackme +mountPoint = live24 +name = DarkIce trial +description = This is only a trial +url = http://www.yourserver.com +genre = live +public = no +remoteDumpFile = /tmp/live24.mp3 + diff --git a/darkice/tags/darkice-0_2/install-sh b/darkice/tags/darkice-0_2/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/darkice/tags/darkice-0_2/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/darkice/tags/darkice-0_2/missing b/darkice/tags/darkice-0_2/missing new file mode 100755 index 0000000..7789652 --- /dev/null +++ b/darkice/tags/darkice-0_2/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# 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, 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., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/darkice/tags/darkice-0_2/mkinstalldirs b/darkice/tags/darkice-0_2/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/darkice/tags/darkice-0_2/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/darkice/tags/darkice-0_2/src/AudioEncoder.h b/darkice/tags/darkice-0_2/src/AudioEncoder.h new file mode 100644 index 0000000..54c0624 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/AudioEncoder.h @@ -0,0 +1,370 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : AudioEncoder.h + Version : $Revision$ + Author : $Author$ + Location : $AudioEncoder$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef AUDIO_ENCODER_H +#define AUDIO_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "AudioSource.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio encoder + * + * @author $Author$ + * @version $Revision$ + */ +class AudioEncoder : public virtual Referable +{ + private: + + /** + * Sample rate of the input. + */ + unsigned int inSampleRate; + + /** + * Number of bits per sample of the input. + */ + unsigned int inBitsPerSample; + + /** + * Number of channels of the input. + */ + unsigned int inChannel; + + /** + * Bit rate of the output. (bits/sec) + */ + unsigned int outBitrate; + + /** + * Sample rate of the output. + */ + unsigned int outSampleRate; + + /** + * Number of channels of the output. + */ + unsigned int outChannel; + + /** + * Initialize the object. + * + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param outBitrate bit rate of the output. + * @param outSampleRate sample rate of the output. + * @param outChannel number of channels of the output. + * @exception Exception + */ + inline void + init ( unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + unsigned int outBitrate, + unsigned int outSampleRate, + unsigned int outChannel ) throw ( Exception ) + { + this->inSampleRate = inSampleRate; + this->inBitsPerSample = inBitsPerSample; + this->inChannel = inChannel; + this->outBitrate = outBitrate; + this->outSampleRate = outSampleRate; + this->outChannel = outChannel; + } + + /** + * De-iitialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + AudioEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Constructor. + * + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param outBitrate bit rate of the output (bits/sec). + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @exception Exception + */ + inline + AudioEncoder ( unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception ) + { + init ( inSampleRate, + inBitsPerSample, + inChannel, + outBitrate, + outSampleRate ? outSampleRate : inSampleRate, + outChannel ? outChannel : inChannel ); + } + + /** + * Constructor. + * + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outBitrate bit rate of the output (bits/sec). + * @param outSampleRate sample rate of the output. + * If 0, input sample rate is used. + * @param outChannel number of channels of the output. + * If 0, input channel is used. + * @exception Exception + */ + inline + AudioEncoder ( const AudioSource * as, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception) + { + init( as->getSampleRate(), + as->getBitsPerSample(), + as->getChannel(), + outBitrate, + outSampleRate ? outSampleRate : as->getSampleRate(), + outChannel ? outChannel : as->getChannel() ); + } + + /** + * Copy constructor. + * + * @param encoder the AudioEncoder to copy. + */ + inline + AudioEncoder ( const AudioEncoder & encoder ) throw ( Exception ) + { + init ( encoder.inSampleRate, + encoder.inBitsPerSample, + encoder.inChannel, + encoder.outBitrate, + encoder.outSampleRate, + encoder.outChannel ); + } + + /** + * Assignment operator. + * + * @param encoder the AudioEncoder to assign this to. + * @return a reference to this AudioEncoder. + * @exception Exception + */ + inline virtual AudioEncoder & + operator= ( const AudioEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + + init ( encoder.inSampleRate, + encoder.inBitsPerSample, + encoder.inChannel, + encoder.outBitrate, + encoder.outSampleRate, + encoder.outChannel ); + } + + return *this; + } + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~AudioEncoder ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Get the number of channels of the input. + * + * @return the number of channels of the input. + */ + inline int + getInChannel ( void ) const throw () + { + return inChannel; + } + + /** + * Get the sample rate of the input. + * + * @return the sample rate of the input. + */ + inline int + getInSampleRate ( void ) const throw () + { + return inSampleRate; + } + + /** + * Get the number of bits per sample of the input. + * + * @return the number of bits per sample of the input. + */ + inline int + getInBitsPerSample ( void ) const throw () + { + return inBitsPerSample; + } + + /** + * Get the number of channels of the output. + * + * @return the number of channels of the output. + */ + inline int + getOutChannel ( void ) const throw () + { + return outChannel; + } + + /** + * Get the sample rate of the output. + * + * @return the sample rate of the output. + */ + inline int + getOutSampleRate ( void ) const throw () + { + return outSampleRate; + } + + /** + * Get the bit rate of the output. (bits/sec) + * + * @return the bit rate of the output. + */ + inline int + getOutBitrate ( void ) const throw () + { + return outBitrate; + } + + /** + * Check wether encoding is in progress. + * + * @return true if encoding is in progress, false otherwise. + */ + virtual bool + isRunning ( void ) const throw () = 0; + + /** + * Start encoding. This function returns as soon as possible, + * with encoding started in the background. + * + * @return true if encoding has started, false otherwise. + * @exception Exception + */ + virtual bool + start ( void ) throw ( Exception ) = 0; + + /** + * Stop encoding. Stops the encoding running in the background. + * + * @exception Exception + */ + virtual void + stop ( void ) throw ( Exception ) = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* AUDIO_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:47 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/AudioSource.h b/darkice/tags/darkice-0_2/src/AudioSource.h new file mode 100644 index 0000000..48f5414 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/AudioSource.h @@ -0,0 +1,234 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : AudioSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef AUDIO_SOURCE_H +#define AUDIO_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Source.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Audio data input + * + * @author $Author$ + * @version $Revision$ + */ +class AudioSource : public Source +{ + private: + + /** + * Number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.) + */ + unsigned int channel; + + /** + * Samples per second (e.g. 44100 for 44.1kHz CD quality) + */ + unsigned int sampleRate; + + /** + * Bits per sample (e.g. 8 bits, 16 bits, etc.) + */ + unsigned int bitsPerSample; + + /** + * Initialize the object. + * + * @param sampleRate samples per second. + * @param bitsPerSample bits per sample. + * @param channel number of channels of the audio source. + * @exception Exception + */ + inline void + init ( unsigned int sampleRate, + unsigned int bitsPerSample, + unsigned int channel ) throw ( Exception ) + { + this->sampleRate = sampleRate; + this->bitsPerSample = bitsPerSample; + this->channel = channel; + } + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Constructor. + * Because all values have defaults, this is also the default + * constructor. + * + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + AudioSource ( unsigned int sampleRate = 44100, + unsigned int bitsPerSample = 16, + unsigned int channel = 2 ) + throw ( Exception ) + { + init ( sampleRate, bitsPerSample, channel); + } + + /** + * Copy Constructor. + * + * @param source the object to copy. + * @exception Exception + */ + inline + AudioSource ( const AudioSource & as ) throw ( Exception ) + : Source( as ) + { + init ( as.sampleRate, as.bitsPerSample, as.channel); + } + + /** + * Destructor. + * + * @exception Exception + */ + virtual inline + ~AudioSource ( void ) throw ( Exception ) + { + } + + /** + * Assignment operator. + * + * @param as the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual AudioSource & + operator= ( const AudioSource & as ) throw ( Exception ) + { + if ( this != &as ) { + strip(); + Source::operator=( as ); + init ( as.sampleRate, as.bitsPerSample, as.channel); + } + + return *this; + } + + + public: + + /** + * Get the number of channels for this AudioSource. + * + * @return the number of channels. + */ + inline unsigned int + getChannel ( void ) const throw () + { + return channel; + } + + /** + * Get the sample rate per seconds for this AudioSource. + * + * @return the sample rate per seconds. + */ + inline unsigned int + getSampleRate ( void ) const throw () + { + return sampleRate; + } + + + /** + * Get the number of bits per sample for this AudioSource. + * + * @return the number of bits per sample. + */ + inline unsigned int + getBitsPerSample ( void ) const throw () + { + return bitsPerSample; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* AUDIO_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:47 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/BufferedSink.cpp b/darkice/tags/darkice-0_2/src/BufferedSink.cpp new file mode 100644 index 0000000..7395a2d --- /dev/null +++ b/darkice/tags/darkice-0_2/src/BufferedSink.cpp @@ -0,0 +1,389 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : BufferedSink.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + the buffer is filled like this: + + buffer bufferEnd + | | + +----------+--------------------------+--------------+ + |<---- valid data -------->| + outp inp + + buffer bufferEnd + | | + +----------------+--------------+--------------------+ + -- valid data -->| |--- valid data -----> + inp outp + + + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + + +#include "Exception.h" +#include "BufferedSink.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +BufferedSink :: init ( Sink * sink, + unsigned int size, + unsigned int chunkSize ) throw ( Exception ) +{ + if ( !sink ) { + throw Exception( __FILE__, __LINE__, "no sink"); + } + + this->sink = sink; // create a reference + this->chunkSize = chunkSize ? chunkSize : 1; + this->bufferSize = size; + // make bufferSize a multiple of chunkSize + this->bufferSize -= this->bufferSize % this->chunkSize; + this->peak = 0; + this->misalignment = 0; + this->buffer = new unsigned char[bufferSize]; + this->bufferEnd = buffer + bufferSize; + this->inp = buffer; + this->outp = buffer; +} + + +/*------------------------------------------------------------------------------ + * Copy Constructor + *----------------------------------------------------------------------------*/ +BufferedSink :: BufferedSink ( const BufferedSink & buffer ) + throw ( Exception ) +{ + init( buffer.sink.get(), buffer.bufferSize, buffer.chunkSize); + + this->peak = buffer.peak; + this->misalignment = buffer.misalignment; + memcpy( this->buffer, buffer.buffer, this->bufferSize); +} + + +/*------------------------------------------------------------------------------ + * De-initalize the object + *----------------------------------------------------------------------------*/ +void +BufferedSink :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + sink = 0; // delete the reference + delete buffer; +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +BufferedSink & +BufferedSink :: operator= ( const BufferedSink & buffer ) + throw ( Exception ) +{ + if ( this != &buffer ) { + strip(); + Sink::operator=( buffer ); + init( buffer.sink.get(), buffer.bufferSize, buffer.chunkSize); + + this->peak = buffer.peak; + this->misalignment = buffer.misalignment; + memcpy( this->buffer, buffer.buffer, this->bufferSize); + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Store bufferSize bytes into the buffer + * All data is consumed. The return value is less then bufferSize only + * if the BufferedSink's internal buffer is smaller than bufferSize, + * thus can't hold that much + * The data to be stored is treated as parts with chunkSize size + * Only full chunkSize sized parts are stored + *----------------------------------------------------------------------------*/ +unsigned int +BufferedSink :: store ( const void * buffer, + unsigned int bufferSize ) throw ( Exception ) +{ + const unsigned char * buf; + unsigned int size; + unsigned int i; + unsigned char * oldInp; + + if ( !buffer ) { + throw Exception( __FILE__, __LINE__, "buffer is null"); + } + + if ( !bufferSize ) { + return 0; + } + + oldInp = inp; + buf = (const unsigned char *) buffer; + + // adjust so it is a multiple of chunkSize + bufferSize -= bufferSize % chunkSize; + + // cut the front of the supplied buffer if it wouldn't fit + if ( bufferSize > this->bufferSize ) { + size = this->bufferSize - 1; + size -= size % chunkSize; // keep it a multiple of chunkSize + buf += bufferSize - size; + } else { + size = bufferSize; + } + + // copy the data into the buffer + i = bufferEnd - inp; + if ( (i % chunkSize) != 0 ) { + throw Exception( __FILE__, __LINE__, "copy quantity not aligned", i); + } + + if ( size <= i ) { + // the place between inp and bufferEnd is + // big enough to hold the data + + memcpy( inp, buf, size); + inp = slidePointer( inp, size); + + // adjust outp, lose the data that was overwritten, if any + if ( outp > oldInp && outp <= inp ) { + outp = slidePointer( inp, chunkSize); + } + + } else { + // the place between inp and bufferEnd is not + // big enough to hold the data + // writing will take place in two turns, once from + // inp -> bufferEnd, then from buffer -> + + memcpy( inp, buf, i); + i = size - i; + if ( (i % chunkSize) != 0 ) { + throw Exception(__FILE__, __LINE__, "copy quantity not aligned", i); + } + memcpy( this->buffer, buf, i); + inp = slidePointer( this->buffer, i); + + // adjust outp, lose the data that was overwritten, if any + if ( outp <= oldInp ) { + if ( outp < inp ) { + outp = slidePointer( inp, chunkSize); + } + } else { + outp = slidePointer( inp, chunkSize); + } + } + + updatePeak(); + + if ( ((inp - this->buffer) % chunkSize) != 0 ) { + throw Exception( __FILE__, __LINE__, + "inp not aligned", inp - this->buffer); + } + if ( ((outp - this->buffer) % chunkSize) != 0 ) { + throw Exception( __FILE__, __LINE__, + "outp not aligned", outp - this->buffer); + } + + return size; +} + + +/*------------------------------------------------------------------------------ + * Write some data to the sink + * if len == 0, try to flush the buffer + *----------------------------------------------------------------------------*/ +unsigned int +BufferedSink :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + unsigned int length; + unsigned int soFar; + unsigned char * b = (unsigned char *) buf; + + if ( !buf ) { + throw Exception( __FILE__, __LINE__, "buf is null"); + } + + if ( !isOpen() ) { + return 0; + } + + if ( !align() ) { + return 0; + } + + // make it a multiple of chunkSize + len -= len % chunkSize; + + // try to write data from the buffer first, if any + if ( inp != outp ) { + unsigned int size = 0; + unsigned int total = 0; + + if ( outp > inp ) { + // valuable data is between outp -> bufferEnd and buffer -> inp + // try to write the outp -> bufferEnd + // the rest will be written in the next if + + size = bufferEnd - outp - 1; + size -= size % chunkSize; + soFar = 0; + + while ( outp > inp && soFar < size && sink->canWrite( 0, 0) ) { + length = sink->write( outp + soFar, size - soFar); + outp = slidePointer( outp, length); + soFar += length; + } + + total += soFar; + } + + if ( outp < inp ) { + // valuable data is between outp and inp + // if the previous if wrote all data from the end + // this part will write the rest + + size = inp - outp; + soFar = 0; + + while ( soFar < size && sink->canWrite( 0, 0) ) { + length = sink->write( outp + soFar, size - soFar); + outp = slidePointer( outp, length); + soFar += length; + } + + total += soFar; + } + + while ( (outp - buffer) % chunkSize ) { + slidePointer( outp, 1); + } + + // calulate the misalignment to chunkSize boundaries + misalignment = (chunkSize - (total % chunkSize)) % chunkSize; + } + + if ( !align() ) { + return 0; + } + + // the internal buffer is empty, try to write the fresh data + soFar = 0; + if ( inp != outp ) { + while ( soFar < len && sink->canWrite( 0, 0) ) { + soFar += sink->write( b + soFar, len - soFar); + } + } + length = soFar; + + // calulate the misalignment to chunkSize boundaries + misalignment = (chunkSize - (length % chunkSize)) % chunkSize; + + if ( length < len ) { + // if not all fresh could be written, store the remains + + store( b + length, len - length); + } + + // tell them we ate everything up to chunkSize alignment + return len; +} + + +/*------------------------------------------------------------------------------ + * Close the sink, lose all pending data + *----------------------------------------------------------------------------*/ +void +BufferedSink :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + flush(); + sink->close(); + inp = outp = buffer; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/BufferedSink.h b/darkice/tags/darkice-0_2/src/BufferedSink.h new file mode 100644 index 0000000..7dc33b7 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/BufferedSink.h @@ -0,0 +1,412 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : BufferedSink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef BUFFERED_SINK_H +#define BUFFERED_SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Ref.h" +#include "Reporter.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A Sink First-In First-Out buffer. + * This buffer can always be written to, it overwrites any + * data contained if needed. + * The class is not thread-safe. + * + * @author $Author$ + * @version $Revision$ + */ +class BufferedSink : public Sink, public virtual Reporter +{ + private: + + /** + * The buffer. + */ + unsigned char * buffer; + + /** + * The end of the buffer. + */ + unsigned char * bufferEnd; + + /** + * The size of the buffer. + */ + unsigned int bufferSize; + + /** + * The highest usage of the buffer. + */ + unsigned int peak; + + /** + * All data written to this BufferedSink is handled by chuncks + * of this size. + */ + unsigned int chunkSize; + + /** + * Number of bytes the underlying stream is misaligned with + * chunkSize. (It needs this many bytes more to be aligned.) + */ + unsigned int misalignment; + + /** + * Start of free territory in buffer. + */ + unsigned char * inp; + + /** + * Start of sensible data in buffer. + */ + unsigned char * outp; + + + /** + * The underlying Sink. + */ + Ref sink; + + /** + * Initialize the object. + * + * @param sink the Sink to attach this BufferedSink to. + * @param size the size of the internal buffer to use. + * @param chunkSize size of chunks to handle data in. + * @exception Exception + */ + void + init ( Sink * sink, + unsigned int size, + unsigned int chunkSize ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + /** + * Slide a pointer in the internal buffer by offset. If the pointer + * would reach beyond the end of the buffer, it goes wraps around. + * + * @param p the pointer to slide. + * @param offset the amount to slide with. + * @return pointer p + offset, wrapped around if needed. + */ + inline unsigned char * + slidePointer ( + unsigned char * p, + unsigned int offset ) throw () + { + p += offset; + while ( p >= bufferEnd ) { + p -= bufferSize; + } + + return p; + } + + /** + * Update the peak buffer usage indicator. + * + * @see #peak + */ + inline void + updatePeak ( void ) throw () + { + unsigned int u; + + u = outp <= inp ? inp - outp : (bufferEnd - outp) + (inp - buffer); + if ( peak < u ) { + reportEvent( 4, "BufferedSink, new peak:", peak); + reportEvent( 4, "BufferedSink, remaining:", bufferSize - peak); + peak = u; + } + } + + /** + * If the underlying Sink is misaligned on chunkSize, write as + * many 0s as needed to get it aligned. + * + * @see #misalignment + * @see #chunkSize + */ + inline bool + align ( void ) + { + char b[] = { 0 }; + + while ( misalignment ) { + if ( sink->canWrite( 0, 0) ) { + unsigned int ret; + + if ( !(ret = sink->write( b, 1)) ) { + return false; + } + --misalignment; + + } else { + return false; + } + } + + return true; + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + BufferedSink ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Get the size of the buffer. + * + * @return the size of the buffer. + */ + inline unsigned int + getSize ( void ) const throw () + { + return bufferSize; + } + + /** + * Store data in the internal buffer. If there is not enough space, + * discard all in the buffer and the beginning of the supplied + * buffer if needed. + * + * @param buffer the data to store. + * @param bufferSize the amount of data to store in bytes. + * @return number of bytes really stored. + */ + unsigned int + store ( const void * buffer, + unsigned int bufferSize ) throw ( Exception ); + + + public: + + /** + * Constructor by an underlying Sink, buffer size and chunk size. + * + * @param sink the Sink to attach this BufferSink to. + * @param size the size of the buffer to use for buffering. + * @param chunkSize hanlde all data in write() as chunks of + * chunkSize + * @exception Exception + */ + inline + BufferedSink ( Sink * sink, + unsigned int size, + unsigned int chunkSize = 1 ) throw ( Exception ) + { + init( sink, size, chunkSize); + } + + /** + * Copy constructor. + * + * @param buffer the object to copy. + * @exception Exception + */ + BufferedSink ( const BufferedSink & buffer ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~BufferedSink ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param bs the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + virtual BufferedSink & + operator= ( const BufferedSink & bs ) throw ( Exception ); + + /** + * Get the peak usage of the internal buffer. + * + * @return the peak usage of the internal buffer. + */ + inline unsigned int + getPeak ( void ) const throw () + { + return peak; + } + + /** + * Open the BufferedSink. Opens the underlying Sink. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + inline virtual bool + open ( void ) throw ( Exception ) + { + return sink->open(); + } + + /** + * Check if a BufferedSink is open. + * + * @return true if the BufferedSink is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return sink->isOpen(); + } + + /** + * Check if the BufferedSink is ready to accept data. + * Always returns true immediately. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + return true; + } + + /** + * Write data to the BufferedSink. + * Always reads the maximum number of chunkSize chunks buf + * holds. If the data can not be written to the underlying + * stream, it is buffered. If the buffer overflows, the oldest + * data is discarded. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the BufferedSink to the + * underlying Sink. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + unsigned char b[0]; + + write( b, 0); + } + + /** + * Close the BufferedSink. Closes the underlying Sink. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* BUFFERED_SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2000/11/15 18:08:42 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/CastSink.cpp b/darkice/tags/darkice-0_2/src/CastSink.cpp new file mode 100644 index 0000000..49aff9c --- /dev/null +++ b/darkice/tags/darkice-0_2/src/CastSink.cpp @@ -0,0 +1,150 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : CastSink.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "Util.h" +#include "Exception.h" +#include "CastSink.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +CastSink :: init ( TcpSocket * socket, + const char * password, + const char * mountPoint, + const char * remoteDumpFile, + const char * name, + const char * description, + const char * url, + const char * genre, + unsigned int bitRate, + bool isPublic, + unsigned int bufferDuration ) + throw ( Exception ) +{ + this->socket = socket; + this->password = Util::strDup( password); + this->mountPoint = Util::strDup( mountPoint); + this->remoteDumpFile = remoteDumpFile ? Util::strDup( remoteDumpFile) : 0; + this->name = Util::strDup( name); + this->description = Util::strDup( description); + this->url = Util::strDup( url); + this->genre = Util::strDup( genre); + this->bitRate = bitRate; + this->isPublic = isPublic; + this->bufferDuration = bufferDuration; + + bufferedSink = new BufferedSink( socket, + (bitRate * 1024 / 8) * bufferDuration); + +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +CastSink :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] password; + delete[] mountPoint; + if ( remoteDumpFile ) { + delete[] remoteDumpFile; + } + delete[] name; + delete[] description; + delete[] url; + delete[] genre; +} + + +/*------------------------------------------------------------------------------ + * Open the connection + *----------------------------------------------------------------------------*/ +bool +CastSink :: open ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( !bufferedSink->open() ) { + return false; + } + + if ( !sendLogin() ) { + close(); + return false; + } + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/CastSink.h b/darkice/tags/darkice-0_2/src/CastSink.h new file mode 100644 index 0000000..324f285 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/CastSink.h @@ -0,0 +1,533 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : CastSink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CAST_SINK_H +#define CAST_SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Ref.h" +#include "Sink.h" +#include "TcpSocket.h" +#include "BufferedSink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Data output to a ShoutCast / IceCast / etc. server + * This is an abstract class. A subclass should override at least + * the sendLogin() function. + * + * @author $Author$ + * @version $Revision$ + */ +class CastSink : public Sink +{ + private: + + /** + * The socket connection to the server. + */ + Ref socket; + + /** + * The BufferedSink encapsulating the socket connection to the server. + */ + Ref bufferedSink; + + /** + * Duration of the BufferedSink buffer in seconds. + */ + unsigned int bufferDuration; + + /** + * Password to the server. + */ + char * password; + + /** + * Mount point of the stream on the server. + */ + char * mountPoint; + + /** + * Remote dump file if any. + */ + char * remoteDumpFile; + + /** + * Name of the stream. + */ + char * name; + + /** + * Description of the stream. + */ + char * description; + + /** + * URL associated with the stream. + */ + char * url; + + /** + * Genre of the stream. + */ + char * genre; + + /** + * Bitrate of the stream (e.g. mp3 bitrate). + */ + unsigned int bitRate; + + /** + * Is the stream public? + */ + bool isPublic; + + /** + * Initalize the object. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param mountPoint mount point of the stream on the server. + * @param remoteDumpFile remote dump file (may be NULL). + * @param name name of the stream. + * @param description description of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + void + init ( TcpSocket * socket, + const char * password, + const char * mountPoint, + const char * remoteDumpFile, + const char * name, + const char * description, + const char * url, + const char * genre, + unsigned int bitRate, + bool isPublic, + unsigned int bufferDuration ) + throw ( Exception ); + + /** + * De-initalize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + CastSink ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Log in to the server using the socket avialable. + * + * @return true if login was successful, false otherwise. + * @exception Exception + */ + virtual bool + sendLogin ( void ) throw ( Exception ) = 0; + + /** + * Get the Sink underneath this CastSink. + * + * @return pointer to the Sink underneath this CastSink. + */ + inline Sink * + getSink ( void ) const throw () + { + return bufferedSink.get(); + } + + /** + * Get the TcpSocket underneath this CastSink. + * + * @return pointer to the TcpSocket underneath this CastSink. + */ + inline TcpSocket * + getSocket ( void ) const throw () + { + return socket.get(); + } + + + public: + + /** + * Constructor. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param mountPoint mount point of the stream on the server. + * @param remoteDumpFile remote dump file (may be NULL). + * @param name name of the stream. + * @param description description of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + inline + CastSink ( TcpSocket * socket, + const char * password, + const char * mountPoint, + const char * remoteDumpFile, + const char * name, + const char * description, + const char * url, + const char * genre, + unsigned int bitRate, + bool isPublic, + unsigned int bufferDuration = 10 ) + throw ( Exception ) + { + init( socket, + password, + mountPoint, + remoteDumpFile, + name, + description, + url, + genre, + bitRate, + isPublic, + bufferDuration ); + } + + /** + * Copy constructor. + * + * @param cs the CastSink to copy. + */ + inline + CastSink( const CastSink & cs ) throw ( Exception ) + : Sink( cs ) + { + init( cs.socket.get(), + cs.password, + cs.mountPoint, + cs.remoteDumpFile, + cs.name, + cs.description, + cs.url, + cs.genre, + cs.bitRate, + cs.isPublic, + cs.bufferDuration ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~CastSink( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param cs the CastSink to assign this to. + * @return a reference to this CastSink. + * @exception Exception + */ + inline virtual CastSink & + operator= ( const CastSink & cs ) throw ( Exception ) + { + if ( this != &cs ) { + strip(); + Sink::operator=( cs ); + init( cs.socket.get(), + cs.password, + cs.mountPoint, + cs.remoteDumpFile, + cs.name, + cs.description, + cs.url, + cs.genre, + cs.bitRate, + cs.isPublic, + cs.bufferDuration ); + } + return *this; + } + + /** + * Open the CastSink. + * Logs in to the server. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the CastSink is open. + * + * @return true if the CastSink is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return bufferedSink->isOpen(); + } + + /** + * Check if the CastSink is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the CastSink is ready to accept data, + * false otherwise. + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + return getSink()->canWrite( sec, usec); + } + + /** + * Write data to the CastSink. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + inline virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ) + { + return getSink()->write( buf, len); + } + + /** + * Flush all data that was written to the CastSink to the server. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + return getSink()->flush(); + } + + /** + * Close the CastSink. + * + * @exception Exception + */ + inline virtual void + close ( void ) throw ( Exception ) + { + return getSink()->close(); + } + + /** + * Get the password to the server. + * + * @return the password to the server. + */ + inline const char * + getPassword ( void ) const throw () + { + return password; + } + + /** + * Get the mount point of the stream on the server. + * + * @return the mount point of the stream on the server. + */ + inline const char * + getMountPoint ( void ) const throw () + { + return mountPoint; + } + + /** + * Get the remote dump file if any. + * + * @return the remote dump file. May be NULL. + */ + inline const char * + getRemoteDumpFile ( void ) const throw () + { + return remoteDumpFile; + } + + /** + * Get the name of the stream. + * + * @return the name of the stream. + */ + inline const char * + getName ( void ) const throw () + { + return name; + } + + /** + * Get the description of the stream. + * + * @return the description of the stream. + */ + inline const char * + getDescription ( void ) const throw () + { + return description; + } + + /** + * Get the URL associated with the stream. + * + * @return the URL associated with the stream. + */ + inline const char * + getUrl ( void ) const throw () + { + return url; + } + + /** + * Get the genre of the stream. + * + * @return the genre of the stream. + */ + inline const char * + getGenre ( void ) const throw () + { + return genre; + } + + /** + * Get the bitrate of the stream (e.g. mp3 bitrate). + * + * @return the bitrate of the stream (e.g. mp3 bitrate). + */ + inline unsigned int + getBitRate ( void ) const throw () + { + return bitRate; + } + + /** + * Get wether this stream is public. + * + * @return true if the stream is public, false otherwise. + */ + inline bool + getIsPublic ( void ) const throw () + { + return isPublic; + } + + /** + * Get the duration of the BufferedSink buffer in seconds. + * + * @return the the duration of the BufferedSink buffer in seconds. + */ + inline unsigned int + getBufferDuration ( void ) const throw () + { + return bufferDuration; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CAST_SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Config.cpp b/darkice/tags/darkice-0_2/src/Config.cpp new file mode 100644 index 0000000..2f89e31 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Config.cpp @@ -0,0 +1,177 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Config + + File : Config.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include + +#include + + +#include "Config.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Max line size + *----------------------------------------------------------------------------*/ +#define LINE_SIZE 256 + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Get a value for a key + *----------------------------------------------------------------------------*/ +const ConfigSection * +Config :: get ( const char * key ) const throw ( Exception ) +{ + if ( !key ) { + throw Exception( __FILE__, __LINE__, "no key"); + } + + TableType::const_iterator it = table.find( key); + if ( it == table.end() ) { + return 0; + } + return &(it->second); +} + + +/*------------------------------------------------------------------------------ + * Add a configuration line + *----------------------------------------------------------------------------*/ +bool +Config :: addLine ( const char * line ) throw ( Exception ) +{ + if ( !line ) { + throw Exception( __FILE__, __LINE__, "no line"); + } + + string::size_type ix; + string str( line); + + /* delete everything after the first # */ + if ( (ix = str.find( '#')) != str.npos ) { + str.erase( ix); + } + /* eat up all white space from the front */ + if ( (ix = str.find_first_not_of( ' ')) != str.npos ) { + str.erase( 0, ix); + } + /* eat up all white space from the end */ + if ( (ix = str.find_last_not_of( ' ')) != str.npos ) { + str.erase( ix + 1); + } + + if ( str[0] == '[' && str[str.size()-1] == ']' ) { + // a new section starts + + string section( str, 1, str.size()-2); + ConfigSection cSection; + pair element( section, cSection); + pair res; + + res = table.insert( element); + + currentSection = section; + return res.second; + } else { + // it's a line for the current section + + TableType::iterator it = table.find( currentSection); + if ( it == table.end() ) { + throw Exception( __FILE__, __LINE__, "no current section"); + } + + return it->second.addLine( line); + } +} + + +/*------------------------------------------------------------------------------ + * Add a configuration line + *----------------------------------------------------------------------------*/ +void +Config :: read ( istream & is ) throw ( Exception ) +{ + char line[LINE_SIZE]; + unsigned int num; + + for ( num = 0; !is.fail() && !is.eof(); ++num ) { + is.getline( line, LINE_SIZE); + if ( is.eof() ) { + break; + } else if ( is.fail() ) { + throw Exception( __FILE__, __LINE__, "line too long", num); + } + + addLine( line); + } +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Config.h b/darkice/tags/darkice-0_2/src/Config.h new file mode 100644 index 0000000..f13740a --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Config.h @@ -0,0 +1,230 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Config + + File : Config.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CONFIG_H +#define CONFIG_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include +#include + +#include + +#include "Referable.h" +#include "ConfigSection.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A configuration file representation. The file is of the syntax: + * + *
+ *  [section1]
+ *  # this is a whole line comment
+ *  key = value
+ *  an ugly key name = long value    # this end is a comment too
+ *
+ *  [section2]
+ *  # this is a whole line comment in section 2
+ *  key = value
+ *  an ugly key name = long value    # this end is a comment too
+ *  
+ * + * also empty lines are ignored and all white space is removed + * from the front and end of keys / values + * + * Knwon problem: you can't use '#' in any part of a key / value pair + * + * @author $Author$ + * @version $Revision$ + */ +class Config : public virtual Referable +{ + private: + + /** + * Type declaration of the hash table type. + */ + typedef hash_map TableType; + + /** + * Hash table holding the configuration sections. + * + * @see ConfigSection + */ + TableType table; + + /** + * Hash table holding the configuration sections. + * + * @see ConfigSection + */ + string currentSection; + + + protected: + + + public: + + /** + * Default constructor. + * + * @exception Exception + */ + inline + Config ( void ) throw ( Exception ) + { + } + + /** + * Constructor based on an input stream. + * + * @param is configuration will be read from this input stream + * until end of stream is reached. + * @exception Exception + */ + inline + Config ( istream & is ) throw ( Exception ) + { + read( is ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Config ( void ) throw ( Exception ) + { + } + + +/* TODO + + inline + Config ( const Config & di ) throw ( Exception ) + { + } + + + inline Config & + operator= ( const Config * di ) throw ( Exception ) + { + } +*/ + + /** + * Delete the configuration information stored in the object. + * Resets the object to a clean state. + * + * @exception Exception + */ + inline virtual void + reset ( void ) throw ( Exception ) + { + table.clear(); + currentSection = ""; + } + + /** + * Read a line of confiugration information. + * + * @param line the line to read. + * @return true if the line was correct, false otherwise. + * @exception Exception + */ + virtual bool + addLine ( const char * line ) throw ( Exception ); + + /** + * Read a line of confiugration information. + * + * @param line the line to read. + * @return true if the line was correct, false otherwise. + * @exception Exception + */ + virtual void + read ( istream & is ) throw ( Exception ); + + /** + * Get a ConfigSection by name. + * + * @param key the name of the ConfigSection + * @return the ConfigSection requested, or NULL if it doesn't exists. + * @exception Exception + */ + virtual const ConfigSection * + get ( const char * key ) const throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CONFIG_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/09 22:07:19 darkeye + added constructor with istream + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/ConfigSection.cpp b/darkice/tags/darkice-0_2/src/ConfigSection.cpp new file mode 100644 index 0000000..4ac69c9 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/ConfigSection.cpp @@ -0,0 +1,188 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell ConfigSection + + File : ConfigSection.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include + +#include + + +#include "ConfigSection.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Add a key / value pair + *----------------------------------------------------------------------------*/ +bool +ConfigSection :: add ( const char * key, + const char * value ) throw ( Exception ) +{ + if ( !key || !value ) { + throw Exception( __FILE__, __LINE__, "no key or value"); + } + + pair element( key, value); + pair res; + + res = table.insert( element); + + return res.second; +} + + +/*------------------------------------------------------------------------------ + * Get a value for a key + *----------------------------------------------------------------------------*/ +const char * +ConfigSection :: get ( const char * key ) const throw ( Exception ) +{ + if ( !key ) { + throw Exception( __FILE__, __LINE__, "no key"); + } + + TableType::const_iterator it = table.find( key); + if ( it == table.end() ) { + return 0; + } + return it->second.c_str(); +} + + +/*------------------------------------------------------------------------------ + * Get a value for a key, in the key does not exist, throw an exception + *----------------------------------------------------------------------------*/ +const char * +ConfigSection :: getForSure ( const char * key, + const char * message1 = 0, + const char * message2 = 0, + int code = 0 ) const + throw ( Exception ) +{ + const char * value; + + if ( !(value = get( key)) ) { + throw Exception( __FILE__, __LINE__, key, message1, message2, code); + } + + return value; +} + + +/*------------------------------------------------------------------------------ + * Add a configuration line + *----------------------------------------------------------------------------*/ +bool +ConfigSection :: addLine ( const char * line ) throw ( Exception ) +{ + if ( !line ) { + throw Exception( __FILE__, __LINE__, "no line"); + } + + string::size_type ix; + string str( line); + + /* delete everything after the first # */ + if ( (ix = str.find( '#')) != str.npos ) { + str.erase( ix); + } + /* eat up all white space from the front */ + if ( (ix = str.find_first_not_of( ' ')) != str.npos ) { + str.erase( 0, ix); + } + /* eat up all white space from the end */ + if ( (ix = str.find_last_not_of( ' ')) != str.npos ) { + str.erase( ix + 1); + } + + /* find the '=' delimiter between key and value */ + if ( (ix = str.find( '=')) == str.npos ) { + return false; + } + + string key( str, 0, ix); + string value( str, ix + 1); + + /* eat up all white space from the front of value */ + if ( (ix = value.find_first_not_of( ' ')) != value.npos ) { + value.erase( 0, ix); + } + /* eat up all white space from the end of key */ + if ( (ix = key.find_last_not_of( ' ')) != key.npos ) { + key.erase( ix + 1); + } + + /* now add the new key / value pair */ + return add( key.c_str(), value.c_str()); +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/09 22:08:17 darkeye + added function getForSure + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/ConfigSection.h b/darkice/tags/darkice-0_2/src/ConfigSection.h new file mode 100644 index 0000000..da553e8 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/ConfigSection.h @@ -0,0 +1,205 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell ConfigSection + + File : ConfigSection.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CONFIG_SECTION_H +#define CONFIG_SECTION_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include +#include + +#include "Referable.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A configuration file representation. The file is of the syntax: + * + *
+ *  # this is a whole line comment
+ *  key = value
+ *  an ugly key name = long value    # this end is a comment too
+ *  
+ * + * also empty lines are ignored and all white space is removed + * from the front and end of keys / values + * + * Knwon problem: you can't use '#' in any part of a key / value pair + * + * @author $Author$ + * @version $Revision$ + */ +class ConfigSection : public virtual Referable +{ + private: + + /** + * Type of the hash table used in this class. + */ + typedef hash_map TableType; + + /** + * Hash table holding the configuration information. + */ + TableType table; + + + protected: + + + public: + + /** + * Default constructor. + * + * @exception Exception + */ + inline + ConfigSection ( void ) throw ( Exception ) + { + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~ConfigSection ( void ) throw ( Exception ) + { + } + + +/* TODO + + inline + ConfigSection ( const ConfigSection & di ) throw ( Exception ) + { + } + + + inline ConfigSection & + operator= ( const ConfigSection * di ) throw ( Exception ) + { + } +*/ + + /** + * Add a key / value pair to the configuration information. + * + * @param key the key to add the value by + * @param value the value to add for the key + * @return true if adding was successful, false otherwise + * @exception Exception + */ + virtual bool + add ( const char * key, + const char * value ) throw ( Exception ); + + /** + * Get a value for a key. + * + * @param key the key to get the value for + * @return the value for the key, or NULL if the key doesn't exist. + * @exception Exception + */ + virtual const char * + get ( const char * key ) const throw ( Exception ); + + /** + * Get a value for a key, or throw an Exception. + * + * @param key the key to get the value for + * @param message1 message part 1 of the Exception to be thrown. + * @param message2 message part 2 of the Exception to be thrown. + * @param code error code of the Exception to be thrown. + * @return the value for the key. The return value is never NULL. + * @exception Exception + */ + virtual const char * + getForSure ( const char * key, + const char * message1 = 0, + const char * message2 = 0, + int code = 0 ) const + throw ( Exception ); + + /** + * Add a line of configuration information. + * + * @param line the line to add. + * @return true if a new key was added, false otherwise. + * @exception Exception + */ + virtual bool + addLine ( const char * line ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CONFIG_SECTION_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/09 22:08:17 darkeye + added function getForSure + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Connector.cpp b/darkice/tags/darkice-0_2/src/Connector.cpp new file mode 100644 index 0000000..4971441 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Connector.cpp @@ -0,0 +1,351 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Connector.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "Exception.h" +#include "Connector.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +Connector :: init ( Source * source ) throw ( Exception ) +{ + this->source = source; + this->sinks = 0; + this->numSinks = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +Connector :: strip ( void ) throw ( Exception ) +{ + source = 0; + + if ( sinks ) { + unsigned int u; + + for ( u = 0; u < numSinks; ++u ) { + sinks[u] = 0; + } + + delete[] sinks; + } +} + + +/*------------------------------------------------------------------------------ + * Constructor + *----------------------------------------------------------------------------*/ +Connector :: Connector ( const Connector & connector ) throw ( Exception ) +{ + unsigned int u; + + init( connector.source.get()); + + for ( u = 0; u < connector.numSinks; ++u ) { + attach( connector.sinks[u].get() ); + } +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +Connector & +Connector :: operator= ( const Connector & connector ) throw ( Exception ) +{ + if ( this != &connector ) { + unsigned int u; + + /* first free everything */ + strip(); + + /* then fill in */ + init( connector.source.get() ); + + for ( u = 0; u < connector.numSinks; ++u ) { + attach( connector.sinks[u].get() ); + } + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Attach a sink to the connector + *----------------------------------------------------------------------------*/ +void +Connector :: attach ( Sink * sink ) throw ( Exception ) +{ + if ( !sinks ) { + + numSinks = 1; + sinks = new Ref[1]; + sinks[0] = sink; + + } else { + + unsigned int u; + Ref * s = new Ref[numSinks + 1]; + + for ( u = 0; u < numSinks; ++u ) { + s[u] = sinks[u].get(); + } + + s[numSinks] = sink; + delete[] sinks; + sinks = s; + ++numSinks; + } +} + + +/*------------------------------------------------------------------------------ + * Detach a sink to the connector + *----------------------------------------------------------------------------*/ +bool +Connector :: detach ( Sink * sink ) throw ( Exception ) +{ + if ( numSinks == 0 ) { + + return false; + + } else if ( numSinks == 1 ) { + + sinks[0] = 0; + delete[] sinks; + sinks = 0; + + return true; + + } else { + + unsigned int u; + unsigned int v; + unsigned int ix; + Ref * s; + + ix = numSinks; + for ( u = 0; u < numSinks; ++u ) { + + if ( sinks[u].get() == sink ) { + ix = u; + break; + } + } + + if ( ix == numSinks ) { + return false; + } + + s = new Ref[numSinks - 1]; + for ( u = 0, v = 0; u < numSinks; ++u ) { + + if ( u != ix ) { + s[v++] = sinks[u]; + } + } + + sinks[ix] = 0; + delete[] sinks; + sinks = s; + --numSinks; + + return true; + } +} + + +/*------------------------------------------------------------------------------ + * Open the source and all the sinks if needed + *----------------------------------------------------------------------------*/ +bool +Connector :: open ( void ) throw ( Exception ) +{ + unsigned int u; + + if ( !source->isOpen() ) { + if ( !source->open() ) { + return false; + } + } + + for ( u = 0; u < numSinks; ++u ) { + if ( !sinks[u]->isOpen() ) { + if ( !sinks[u]->open() ) { + break; + } + } + } + + /* if not all could be opened, close those that were */ + if ( u < numSinks ) { + unsigned int v; + + for ( v = 0; v < u; ++v ) { + sinks[v]->close(); + } + + source->close(); + + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Transfer some data from the source to the sink + *----------------------------------------------------------------------------*/ +unsigned int +Connector :: transfer ( unsigned long bytes, + unsigned int bufSize, + unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + unsigned int u; + unsigned long b; + unsigned char buf[bufSize]; + + if ( numSinks == 0 ) { + return 0; + } + + if ( bufSize == 0 ) { + return 0; + } + + reportEvent( 6, "Connector :: tranfer, bytes", bytes); + + for ( b = 0; b < bytes; ) { + unsigned int d = 0; + unsigned int e = 0; + + if ( source->canRead( sec, usec) ) { + d = source->read( buf, bufSize); + + /* check for EOF */ + if ( d == 0 ) { + reportEvent( 3, "Connector :: transfer, EOF"); + break; + } + + for ( u = 0; u < numSinks; ++u ) { + + if ( sinks[u]->canWrite( sec, usec) ) { + e = sinks[u]->write( buf, d); + } else { + sinks[u]->close(); + detach( sinks[u].get() ); + /* with the call to detach, numSinks gets 1 lower, + * and the next sink comes to sinks[u] */ + --u; + + reportEvent( 5, + "Connector :: transfer, sink removed, remaining", u); + + if ( numSinks == 0 ) { + reportEvent( 4, "Connector :: transfer, no more sinks"); + break; + } + } + } + + b += d; + } else { + reportEvent( 3, "Connector :: transfer, can't read"); + break; + } + } + + return b; +} + + +/*------------------------------------------------------------------------------ + * Open the source and all the sinks if needed + *----------------------------------------------------------------------------*/ +void +Connector :: close ( void ) throw ( Exception ) +{ + unsigned int u; + + source->close(); + for ( u = 0; u < numSinks; ++u ) { + sinks[u]->close(); + } +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/15 18:37:37 darkeye + changed the transferable number of bytes to unsigned long + + Revision 1.3 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.2 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Connector.h b/darkice/tags/darkice-0_2/src/Connector.h new file mode 100644 index 0000000..60b3c73 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Connector.h @@ -0,0 +1,276 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Connector.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CONNECTOR_H +#define CONNECTOR_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "Ref.h" +#include "Reporter.h" +#include "Source.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Connects a source to one or more sinks. + * + * @author $Author$ + * @version $Revision$ + */ +class Connector : public virtual Referable, public virtual Reporter +{ + private: + + /** + * The source to read from. + */ + Ref source; + + /** + * The sinks to connect the source to. + */ + Ref * sinks; + + /** + * Total number of sinks. + */ + unsigned int numSinks; + + /** + * Initialize the object. + * + * @param source the source to read from. + * @exception Exception + */ + void + init ( Source * source ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + Connector ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor based on a Source. + * + * @param source the source to connect to the sinks. + * @exception Exception + */ + inline + Connector ( Source * source ) throw ( Exception ) + { + init( source); + } + + /** + * Constructor based on a Source and a Sink. + * + * @param source the source to connect to the sinks. + * @param sink a sink to connect to the source. + * @exception Exception + */ + inline + Connector ( Source * source, + Sink * sink ) throw ( Exception ) + { + init( source); + attach( sink); + } + + /** + * Copy constructor. + * + * @param connector the object to copy. + * @exception Exception + */ + Connector ( const Connector & connector ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Connector( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param connector the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + virtual Connector & + operator= ( const Connector & connector ) throw ( Exception ); + + /** + * Get the number of Sinks in the Connector. + * + * @return the number of Sinks in the Connector. + * @exception Exception + */ + inline unsigned int + getNumSinks ( void ) const throw () + { + return numSinks; + } + + /** + * Attach a Sink to the Source of this Connector. + * + * @param sink the Sink to attach. + * @exception Exception + */ + void + attach ( Sink * sink ) throw ( Exception ); + + /** + * Detach an already attached Sink from the Source of this Connector. + * + * @param sink the Sink to detach. + * @return true if the detachment was successful, false otherwise. + * @exception Exception + */ + bool + detach ( Sink * sink ) throw ( Exception ); + + /** + * Open the connector. Opens the Source and the Sinks if necessary. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + bool + open ( void ) throw ( Exception ); + + /** + * Transfer a given amount of data from the Source to all the + * Sinks attached. + * If an attached Sink closes or encounteres an error during the + * process, it is detached and the function carries on with the + * rest of the Sinks. If no Sinks remain, or an error is encountered + * with the Source, the function returns prematurely. + * + * @param bytes the amount of data to transfer, in bytes + * @param bufSize the size of the buffer to use for transfering. + * This amount of data is read from the Source and + * written to each Sink on each turn. + * @param sec the number of seconds to wait for the Source to have + * data available in each turn, and the number of seconds + * to wait for the Sinks to accept data. + * @param usec the number of micros seconds to wait for the Source to + * have data available in each turn, and the number of + * micro seconds to wait for the Sinks to accept data. + * @return the number of bytes read from the Source. + * @exception Exception + */ + unsigned int + transfer ( unsigned long bytes, + unsigned int bufSize, + unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Close the Connector. The Source and all Sinks are closed. + * + * @exception Exception + */ + void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CONNECTOR_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/15 18:37:37 darkeye + changed the transferable number of bytes to unsigned long + + Revision 1.3 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.2 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/DarkIce.cpp b/darkice/tags/darkice-0_2/src/DarkIce.cpp new file mode 100644 index 0000000..24ab35e --- /dev/null +++ b/darkice/tags/darkice-0_2/src/DarkIce.cpp @@ -0,0 +1,429 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : DarkIce.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_STDLIB_H +#include +#else +#error need stdlib.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_SYS_WAIT_H +#include +#else +#error need sys/wait.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + + +#include +#include + + +#include "Util.h" +#include "DarkIce.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Make sure wait-related stuff is what we expect + *----------------------------------------------------------------------------*/ +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +DarkIce :: init ( const Config & config ) throw ( Exception ) +{ + unsigned int bufferSecs; + const ConfigSection * cs; + const char * str; + unsigned int sampleRate; + unsigned int bitsPerSample; + unsigned int channel; + const char * device; + unsigned int u; + + // the [general] section + if ( !(cs = config.get( "general")) ) { + throw Exception( __FILE__, __LINE__, "no section [general] in config"); + } + str = cs->getForSure( "duration", " missing in section [general]"); + duration = Util::strToL( str); + str = cs->getForSure( "bufferSecs", " missing in section [general]"); + bufferSecs = Util::strToL( str); + + + // the [input] section + if ( !(cs = config.get( "input")) ) { + throw Exception( __FILE__, __LINE__, "no section [general] in config"); + } + + str = cs->getForSure( "sampleRate", " missing in section [input]"); + sampleRate = Util::strToL( str); + str = cs->getForSure( "bitsPerSample", " missing in section [input]"); + bitsPerSample = Util::strToL( str); + str = cs->getForSure( "channel", " missing in section [input]"); + channel = Util::strToL( str); + device = cs->getForSure( "device", " missing in section [input]"); + + dsp = new OssDspSource( device, + sampleRate, + bitsPerSample, + channel ); + encConnector = new Connector( dsp.get()); + + + // look for lame encoder output streams, sections [lame0], [lame1], etc. + char lame[] = "lame "; + size_t lameLen = Util::strLen( lame); + char * pipeOutExt = ".out"; + size_t pipeOutExtLen = Util::strLen( pipeOutExt); + char * pipeInExt = ".in"; + size_t pipeInExtLen = Util::strLen( pipeInExt); + + for ( u = 0; u < maxOutput; ++u ) { + // ugly hack to change the section name to "lame0", "lame1", etc. + lame[lameLen-1] = '0' + u; + + if ( !(cs = config.get( lame)) ) { + break; + } + + const char * encoder = 0; + unsigned int bitrate = 0; + const char * server = 0; + unsigned int port = 0; + const char * password = 0; + const char * mountPoint = 0; + const char * remoteDumpFile = 0; + const char * name = 0; + const char * description = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + unsigned int lowpass = 0; + unsigned int highpass = 0; + + encoder = cs->getForSure( "encoder", " missing in section ", lame); + str = cs->getForSure( "bitrate", " missing in section ", lame); + bitrate = Util::strToL( str); + server = cs->getForSure( "server", " missing in section ", lame); + str = cs->getForSure( "port", " missing in section ", lame); + port = Util::strToL( str); + password = cs->getForSure( "password", " missing in section ", lame); + mountPoint = cs->getForSure( "mountPoint"," missing in section ",lame); + remoteDumpFile = cs->get( "remoteDumpFile"); + name = cs->getForSure( "name", " missing in section ", lame); + description = cs->getForSure("description"," missing in section ",lame); + url = cs->getForSure( "url", " missing in section ", lame); + genre = cs->getForSure( "genre", " missing in section ", lame); + str = cs->getForSure( "public", " missing in section ", lame); + isPublic = Util::strEq( str, "yes") ? true : false; + str = cs->get( "lowpass"); + lowpass = str ? Util::strToL( str) : 0; + str = cs->get( "highpass"); + highpass = str ? Util::strToL( str) : 0; + + // generate the pipe names + char pipeOutName[lameLen + pipeOutExtLen + 1]; + char pipeInName[lameLen + pipeInExtLen + 1]; + + Util::strCpy( pipeOutName, lame); + Util::strCat( pipeOutName, pipeOutExt); + Util::strCpy( pipeInName, lame); + Util::strCat( pipeInName, pipeInExt); + + // go on and create the things + + outputs[u].pid = 0; + + // the pipes + outputs[u].encOutPipe = new PipeSource( pipeOutName); + outputs[u].encInPipe = new PipeSink( pipeInName); + + if ( !outputs[u].encOutPipe->exists() ) { + if ( !outputs[u].encOutPipe->create() ) { + throw Exception( __FILE__, __LINE__, + "can't create out pipe ", + pipeOutName ); + } + } + + if ( !outputs[u].encInPipe->exists() ) { + if ( !outputs[u].encInPipe->create() ) { + throw Exception( __FILE__, __LINE__, + "can't create in pipe", + pipeInName ); + } + } + + // encoder related stuff + unsigned int bs = bufferSecs * + (bitsPerSample / 8) * channel * sampleRate; + outputs[u].encIn = new BufferedSink( outputs[u].encInPipe.get(), + bs, + (bitsPerSample / 8) * channel ); + reportEvent( 6, "using buffer size", bs); + + encConnector->attach( outputs[u].encIn.get()); + outputs[u].encoder = new LameEncoder( encoder, + outputs[u].encInPipe->getFileName(), + dsp.get(), + outputs[u].encOutPipe->getFileName(), + bitrate, + sampleRate, + channel, + lowpass, + highpass ); + + + // streaming related stuff + outputs[u].socket = new TcpSocket( server, port); + outputs[u].ice = new IceCast( outputs[u].socket.get(), + password, + mountPoint, + remoteDumpFile, + name, + description, + url, + genre, + bitrate, + isPublic ); + outputs[u].shoutConnector = new Connector( outputs[u].encOutPipe.get(), + outputs[u].ice.get()); + } + + noOutputs = u; +} + + +/*------------------------------------------------------------------------------ + * Run the encoder + *----------------------------------------------------------------------------*/ +bool +DarkIce :: encode ( void ) throw ( Exception ) +{ + unsigned int len; + unsigned int u; + unsigned long bytes; + + for ( u = 0; u < noOutputs; ++u ) { + outputs[u].encoder->start(); + } + + sleep( 1 ); + + if ( !encConnector->open() ) { + throw Exception( __FILE__, __LINE__, "can't open connector"); + } + + bytes = dsp->getSampleRate() * + (dsp->getBitsPerSample() / 8UL) * + dsp->getChannel() * + duration; + + len = encConnector->transfer( bytes, + 4096, + 1, + 0 ); + + reportEvent( 1, len, "bytes transfered to the encoders"); + + encConnector->close(); + + for ( u = 0; u < noOutputs; ++u ) { + outputs[u].encoder->stop(); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Run the encoder + *----------------------------------------------------------------------------*/ +bool +DarkIce :: shout ( unsigned int ix ) throw ( Exception ) +{ + unsigned int len; + unsigned long bytes; + + if ( ix >= noOutputs ) { + return false; + } + + if ( !outputs[ix].shoutConnector->open() ) { + throw Exception( __FILE__, __LINE__, "can't open connector"); + } + + bytes = outputs[ix].encoder->getOutBitrate() * (1024UL / 8UL) * duration; + len = outputs[ix].shoutConnector->transfer ( bytes, 4096, 10, 0 ); + + reportEvent( 1, len, "bytes transfered to stream", ix); + + outputs[ix].shoutConnector->close(); + + return true; +} + + +/*------------------------------------------------------------------------------ + * Run + *----------------------------------------------------------------------------*/ +int +DarkIce :: run ( void ) throw ( Exception ) +{ + unsigned int u; + + for ( u = 0; u < noOutputs; ++u ) { + outputs[u].pid = fork(); + + if ( outputs[u].pid == -1 ) { + throw Exception( __FILE__, __LINE__, "fork error", errno); + + } else if ( outputs[u].pid == 0 ) { + // this is the child + + sleep ( 1 ); + + reportEvent( 3, "shouting", u); + shout( u); + reportEvent( 3, "shouting ends", u); + + exit(0); + } + } + + // this is the parent + + reportEvent( 3, "encoding"); + encode(); + reportEvent( 3, "encoding ends"); + + for ( u = 0; u < noOutputs; ++u ) { + int status; + + waitpid( outputs[u].pid, &status, 0); + + if ( !WIFEXITED(status) ) { + throw Exception( __FILE__, __LINE__, + "child exited abnormally", WEXITSTATUS(status)); + } + } + + return 0; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.11 2000/11/18 11:13:27 darkeye + removed direct reference to cout, except from main.cpp + all class use the Reporter interface to report events + + Revision 1.10 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.9 2000/11/15 18:37:37 darkeye + changed the transferable number of bytes to unsigned long + + Revision 1.8 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.7 2000/11/13 19:38:55 darkeye + moved command line parameter parsing from DarkIce.cpp to main.cpp + + Revision 1.6 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.5 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.4 2000/11/09 22:09:46 darkeye + added multiple outputs + added configuration reading + added command line processing + + Revision 1.3 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/DarkIce.h b/darkice/tags/darkice-0_2/src/DarkIce.h new file mode 100644 index 0000000..15ebe29 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/DarkIce.h @@ -0,0 +1,262 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : DarkIce.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef DARK_ICE_H +#define DARK_ICE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#include + +#include "Referable.h" +#include "Reporter.h" +#include "Exception.h" +#include "Ref.h" +#include "OssDspSource.h" +#include "PipeSink.h" +#include "BufferedSink.h" +#include "Connector.h" +#include "LameEncoder.h" +#include "PipeSource.h" +#include "TcpSocket.h" +#include "IceCast.h" +#include "Config.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Program main object. + * + * @author $Author$ + * @version $Revision$ + */ +class DarkIce : public virtual Referable, public virtual Reporter +{ + private: + + /** + * The maximum number of supported outputs. + */ + static const unsigned int maxOutput = 8; + + /** + * Type describing each output. + */ + typedef struct { + Ref encInPipe; + Ref encIn; + Ref encoder; + Ref encOutPipe; + Ref socket; + Ref ice; + Ref shoutConnector; + pid_t pid; + } Output; + + /** + * Duration of playing, in seconds. + */ + unsigned int duration; + + /** + * The dsp to record from. + */ + Ref dsp; + + /** + * The encoding Connector, connecting the dsp to the encoders. + */ + Ref encConnector; + + /** + * The outputs. + */ + Output outputs[maxOutput]; + + /** + * Number of outputs. + */ + unsigned int noOutputs; + + /** + * Initialize the object. + * + * @param config the config Object to read initialization + * information from. + * @exception Exception + */ + void + init ( const Config & config ) throw ( Exception ); + + /** + * Start encoding. Spawns all encoders, opens the dsp and + * starts sending data to the encoders. + * + * @return if encoding was successful. + * @exception Exception + */ + bool + encode ( void ) throw ( Exception ); + + /** + * Start shouting. fork()-s a process for each output, reads + * the output of the encoders and sends them to an IceCast server. + * + * @return if shouting was successful. + * @exception Exception + */ + bool + shout ( unsigned int ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + DarkIce ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor based on a configuration object. + * + * @param config the config Object to read initialization + * information from. + * @exception Exception + */ + inline + DarkIce ( const Config & config ) throw ( Exception ) + { + init( config); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~DarkIce ( void ) throw ( Exception ) + { + } + +/* TODO + + inline + DarkIce ( const DarkIce & di ) throw ( Exception ) + { + } + + + inline DarkIce & + operator= ( const DarkIce * di ) throw ( Exception ) + { + } +*/ + + /** + * Run the process of recording / encoding / sending to the servers. + * + * @return 0 on success + * @exception Exception + */ + virtual int + run ( void ) throw ( Exception ); + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* DARK_ICE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.6 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.5 2000/11/13 19:38:55 darkeye + moved command line parameter parsing from DarkIce.cpp to main.cpp + + Revision 1.4 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.2 2000/11/09 22:09:46 darkeye + added multiple outputs + added configuration reading + added command line processing + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Exception.cpp b/darkice/tags/darkice-0_2/src/Exception.cpp new file mode 100644 index 0000000..d0855d9 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Exception.cpp @@ -0,0 +1,220 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Exception.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + + +#include "Exception.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Constructor + *----------------------------------------------------------------------------*/ +Exception :: Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + int code = 0 ) throw () +{ + size_t len = 0; + + if ( description1 ) { + len += strlen( description1); + } + if ( description2 ) { + len += strlen( description2); + } + + if ( len ) { + char str[len+1]; + + str[0] = '\0'; + if ( description1 ) { + strcat( str, description1); + } + if ( description2 ) { + strcat( str, description2); + } + + init( file, line, str, code); + + } else { + + init( file, line, 0, code); + } +} + + +/*------------------------------------------------------------------------------ + * Constructor + *----------------------------------------------------------------------------*/ +Exception :: Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + const char * description3, + int code = 0 ) throw () +{ + size_t len = 0; + + if ( description1 ) { + len += strlen( description1); + } + if ( description2 ) { + len += strlen( description2); + } + if ( description3 ) { + len += strlen( description3); + } + + if ( len ) { + char str[len+1]; + + str[0] = '\0'; + if ( description1 ) { + strcat( str, description1); + } + if ( description2 ) { + strcat( str, description2); + } + if ( description3 ) { + strcat( str, description3); + } + + init( file, line, str, code); + + } else { + + init( file, line, 0, code); + } +} + + +/*------------------------------------------------------------------------------ + * Initialize the class + *----------------------------------------------------------------------------*/ +void +Exception :: init ( const char * file, + unsigned int line, + const char * description = 0, + int code = 0 ) throw () +{ + if ( !file ) { + this->file = 0; + } else { + size_t len; + + len = strlen( file ) + 1; + this->file = new char[len]; + if ( this->file ) { + memcpy( this->file, file, len); + } + } + + if ( !description ) { + this->description = 0; + } else { + size_t len; + + len = strlen( description ) + 1; + this->description = new char[len]; + if ( this->description ) { + memcpy( this->description, description, len); + } + } + + this->line = line; + this->code = code; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the class + *----------------------------------------------------------------------------*/ +void +Exception :: strip ( void ) throw () +{ + if ( description ) { + delete[] description; + } + + if ( file ) { + delete[] file; + } +} + + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/09 22:05:44 darkeye + added multiple-string constructors + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Exception.h b/darkice/tags/darkice-0_2/src/Exception.h new file mode 100644 index 0000000..5fd6125 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Exception.h @@ -0,0 +1,322 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Exception.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef EXCEPTION_H +#define EXCEPTION_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An exception class. + * + * This class should not depend on any other class + * should not throw any exceptions itself. + * + * Typical usage: + * + *
+ *  throw Exception( __FILE__, __LINE__, "describe the exception", code);
+ *  
+ * + * @author $Author$ + * @version $Revision$ + */ +class Exception +{ + private: + + /** + * Source file the exception was thrown in. + */ + char * file; + + /** + * Line number in the source file the exception was thrown in. + */ + unsigned int line; + + /** + * Textual description of the exception. + */ + char * description; + + /** + * Numerical error code. + */ + int code; + + /** + * Initalize the object. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description textual description of the exception. + * @param code numerical error code. + */ + void + init ( const char * file, + unsigned int line, + const char * description, + int code ) throw (); + + /** + * De-initalize the object. + */ + void + strip () throw (); + + + protected: + + + public: + + /** + * Default constructor. + */ + inline + Exception ( void ) throw () + { + init( 0, 0, 0, 0); + } + + /** + * Copy constructor. + */ + inline + Exception ( const Exception & e ) throw () + { + init( e.file, e.line, e.description, e.code); + } + + /** + * Construct by a description and error code. + * + * @param description textual description of the exception. + * @param code numerical error code. + */ + inline + Exception ( const char * description, + int code = 0 ) throw () + { + init( 0, 0, description, code); + } + + /** + * Construct by source file information, a description and error code. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description textual description of the exception. + * @param code numerical error code. + */ + inline + Exception ( const char * file, + unsigned int line, + const char * description = 0, + int code = 0 ) throw () + { + init( file, line, description, code); + } + + /** + * Construct by source file information, a description and error code. + * The description is constructed from two strings, any of which + * may be NULL. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description1 textual description of the exception part 1. + * @param description2 textual description of the exception part 2. + * @param code numerical error code. + */ + Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + int code = 0 ) throw (); + + /** + * Construct by source file information, a description and error code. + * The description is constructed from three strings, any of + * which may be NULL. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description1 textual description of the exception part 1. + * @param description2 textual description of the exception part 2. + * @param description3 textual description of the exception part 3. + * @param code numerical error code. + */ + Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + const char * description3, + int code = 0 ) throw (); + + /** + * Desctructor. + */ + inline + ~Exception ( void ) throw () + { + strip(); + } + + /** + * Assignment operator. + * + * @param e the Exception to assign this to. + * @return a reference to this Exception. + */ + inline Exception & + operator= ( const Exception & e ) throw () + { + if ( this != &e ) { + strip(); + init( e.file, e.line, e.description, e.code); + } + + return *this; + } + + /** + * Return the textual description of the Exception. + * + * @return the textual description of the Exception. + */ + inline const char * + getDescription( void ) const throw () + { + return description; + } + + /** + * Return the line number in the source file this Exception was + * thrown in. + * + * @return the line number in the source file this Exception was + * thrown in. + */ + inline unsigned int + getLine ( void ) const throw () + { + return line; + } + + /** + * Return the source file this Exception was thrown in. + * + * @return the source file this Exception was thrown in. + */ + inline const char * + getFile ( void ) const throw () + { + return file; + } + + /** + * Return the numerical code of the Exception. + * + * @return the numerical code of the Exception. + */ + inline int + getCode ( void ) const throw () + { + return code; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + +/** + * Print an Exception to an ostream. + * + * @param os the output stream to print to. + * @param e the Exception to print. + * @return a reference to the supplied output stream. + */ +inline ostream & +operator<< ( ostream & os, + const Exception & e ) +{ + os << e.getFile() << ":" << e.getLine() << ": " + << e.getDescription() << " [" << e.getCode() << "]"; + + return os; +} + + + +#endif /* EXCEPTION_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2000/11/17 15:33:54 darkeye + bug fix: ostream << operator overload didn't return the ostream + + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/09 22:05:44 darkeye + added multiple-string constructors + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/ExternalEncoder.cpp b/darkice/tags/darkice-0_2/src/ExternalEncoder.cpp new file mode 100644 index 0000000..0a4fb89 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/ExternalEncoder.cpp @@ -0,0 +1,218 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : ExternalEncoder.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_SIGNAL_H +#include +#else +#error need signal.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + + +#include "Exception.h" +#include "Util.h" +#include "ExternalEncoder.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +#define ARG_LEN 64 + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the class + *----------------------------------------------------------------------------*/ +void +ExternalEncoder :: init ( const char * encoderName, + const char * inFileName, + const char * outFileName ) throw ( Exception ) +{ + unsigned int u; + + for ( u = 0; u < numCmdArgs; ++u ) { + cmdArgs[u] = 0; + } + + this->encoderName = Util::strDup( encoderName); + this->inFileName = Util::strDup( inFileName); + this->outFileName = Util::strDup( outFileName); + this->child = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the class + *----------------------------------------------------------------------------*/ +void +ExternalEncoder :: strip ( void ) throw ( Exception ) +{ + unsigned int u; + + if ( isRunning() ) { + stop(); + } + + for ( u = 0; u < numCmdArgs; ++u ) { + if ( cmdArgs[u] ) { + delete[] cmdArgs[u]; + } + } + + delete[] encoderName; + delete[] inFileName; + delete[] outFileName; + child = 0; +} + + +/*------------------------------------------------------------------------------ + * Set the nth command line argument + *----------------------------------------------------------------------------*/ +void +ExternalEncoder :: setArg ( const char * str, + unsigned int index ) throw ( Exception ) +{ + if ( index >= numCmdArgs ) { + throw Exception( __FILE__, __LINE__, "index >= numCmdArgs", index); + } + + cmdArgs[index] = str ? Util::strDup( str) : 0; +} + + +/*------------------------------------------------------------------------------ + * Start the encoding + *----------------------------------------------------------------------------*/ +bool +ExternalEncoder :: start ( void ) throw ( Exception ) +{ + pid_t pid; + + if ( isRunning() ) { + return false; + } + + pid = fork(); + + if ( pid == -1 ) { + throw Exception( __FILE__, __LINE__, "fork error"); + } else if ( pid == 0 ) { + reportEvent( 5, "child process", getpid(), "started"); + + makeArgs(); + execvp( getEncoderName(), cmdArgs); + + throw Exception( __FILE__, __LINE__, "exec returned"); + } else { + child = pid; + reportEvent( 5, "parent", getpid(), "started child process", child); + + return true; + } +} + + +/*------------------------------------------------------------------------------ + * End the encoding + *----------------------------------------------------------------------------*/ +void +ExternalEncoder :: stop ( void ) throw ( Exception ) +{ + if ( !isRunning() ) { + return; + } + + if ( kill( child, SIGHUP) == -1 ) { + throw Exception( __FILE__, __LINE__, "kill", errno); + } +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/18 11:13:27 darkeye + removed direct reference to cout, except from main.cpp + all class use the Reporter interface to report events + + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/ExternalEncoder.h b/darkice/tags/darkice-0_2/src/ExternalEncoder.h new file mode 100644 index 0000000..008fa5f --- /dev/null +++ b/darkice/tags/darkice-0_2/src/ExternalEncoder.h @@ -0,0 +1,382 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : ExternalEncoder.h + Version : $Revision$ + Author : $Author$ + Location : $ExternalEncoder$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef EXTERNAL_ENCODER_H +#define EXTERNAL_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + + +#include "Exception.h" +#include "Reporter.h" +#include "AudioEncoder.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A class representing an external audio encoder which is invoked + * with a frok() and an exec() call + * + * @author $Author$ + * @version $Revision$ + */ +class ExternalEncoder : public AudioEncoder, public virtual Reporter +{ + private: + + /** + * Name of the encoder (the command to invoke the encoder with). + */ + char * encoderName; + + /** + * Input file parameter for the encoder. + */ + char * inFileName; + + /** + * Output file parameter for the encoder. + */ + char * outFileName; + + /** + * Maximum number of command line arguments. + */ + static const unsigned int numCmdArgs = 64; + + /** + * Array of command line arguments. + */ + char * cmdArgs[numCmdArgs]; + + /** + * Process ID of the encoder process. + */ + pid_t child; + + /** + * Initialize the object. + * + * @param encoderName name of the encoder. + * @param inFileName input file parameter for the encoder. + * @param outFileName output file parameter for the encoder. + * @exception Exception + */ + void + init ( const char * encoderName, + const char * inFileName, + const char * outFileName ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + ExternalEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Set a command line argument in the argument array. + * + * @param str the argument to set. + * @param index the place in the array to set the argument. + * @exception Exception + */ + void + setArg ( const char * str, + unsigned int index ) throw ( Exception ); + + /** + * Fill in the list of command line arguments. Puts a 0 + * as the last in the list of args. + * + * @return the number of arguments filled. + * @exception Exception + */ + virtual unsigned int + makeArgs ( void ) throw ( Exception ) = 0; + + + public: + + /** + * Constructor. + * + * @param encoderName name of the encoder. + * (the command to invoke the encoder with) + * @param inFileName input file parameter for the encoder. + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param outFileName output file parameter for the encoder. + * @param outBitrate bit rate of the output (bits/sec). + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @exception Exception + */ + inline + ExternalEncoder ( const char * encoderName, + const char * inFileName, + unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + const char * outFileName, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception ) + + : AudioEncoder ( inSampleRate, + inBitsPerSample, + inChannel, + outBitrate, + outSampleRate, + outChannel ) + { + init ( encoderName, inFileName, outFileName ); + } + + /** + * Constructor. + * + * @param encoderName name of the encoder. + * (the command to invoke the encoder with) + * @param inFileName input file parameter for the encoder. + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outFileName output file parameter for the encoder. + * @param outBitrate bit rate of the output (bits/sec). + * @param outSampleRate sample rate of the output. + * If 0, input sample rate is used. + * @param outChannel number of channels of the output. + * If 0, input channel is used. + * @exception Exception + */ + inline + ExternalEncoder ( const char * encoderName, + const char * inFileName, + const AudioSource * as, + const char * outFileName, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception ) + + : AudioEncoder ( as, + outBitrate, + outSampleRate, + outChannel ) + { + init ( encoderName, inFileName, outFileName ); + } + + /** + * Copy constructor. + * + * @param encoder the ExternalEncoder to copy. + */ + inline + ExternalEncoder ( const ExternalEncoder & encoder ) + throw ( Exception ) + : AudioEncoder( encoder ) + { + init( encoder.encoderName, + encoder.inFileName, + encoder.outFileName ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~ExternalEncoder ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param encoder the ExternalEncoder to assign this to. + * @return a reference to this ExternalEncoder. + * @exception Exception + */ + inline virtual ExternalEncoder & + operator= ( const ExternalEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + AudioEncoder::operator=( encoder); + init( encoder.encoderName, + encoder.inFileName, + encoder.outFileName ); + } + + return *this; + } + + /** + * Get the name of the encoder + * (the command to invoke the encoder with). + * + * @return the name of the encoder. + */ + const char * + getEncoderName ( void ) const throw () + { + return encoderName; + } + + /** + * Get the input file parameter for the encoder. + * + * @return the input file parameter for the encoder. + */ + const char * + getInFileName ( void ) const throw () + { + return inFileName; + } + + /** + * Get the output file parameter for the encoder. + * + * @return the output file parameter for the encoder. + */ + const char * + getOutFileName ( void ) const throw () + { + return outFileName; + } + + /** + * Check wether encoding is in progress. + * + * @return true if encoding is in progress, false otherwise. + */ + inline virtual bool + isRunning ( void ) const throw () + { + return child != 0; + } + + /** + * Start encoding. This function returns as soon as possible, + * with encoding started as a separate process in the + * background. + * + * @return true if encoding has started, false otherwise. + * @exception Exception + */ + virtual bool + start ( void ) throw ( Exception ); + + /** + * Stop encoding. Stops the encoding running in the background. + * + * @exception Exception + */ + virtual void + stop ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* EXTERNAL_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2000/11/18 11:13:27 darkeye + removed direct reference to cout, except from main.cpp + all class use the Reporter interface to report events + + Revision 1.4 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/FileSink.cpp b/darkice/tags/darkice-0_2/src/FileSink.cpp new file mode 100644 index 0000000..f6a74a8 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/FileSink.cpp @@ -0,0 +1,320 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileSink.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_STDLIB_H +#include +#else +#error need stdlib.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + + +#include "Util.h" +#include "Exception.h" +#include "FileSink.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +FileSink :: init ( const char * name ) throw ( Exception ) +{ + fileName = Util::strDup( name); + fileDescriptor = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +FileSink :: strip ( void) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] fileName; +} + + +/*------------------------------------------------------------------------------ + * Copy Constructor + *----------------------------------------------------------------------------*/ +FileSink :: FileSink ( const FileSink & fs ) throw ( Exception ) + : Sink( fs ) +{ + int fd; + + init( fs.fileName); + + if ( (fd = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + fileDescriptor = fd; +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +FileSink & +FileSink :: operator= ( const FileSink & fs ) throw ( Exception ) +{ + if ( this != &fs ) { + int fd; + + /* first strip */ + strip(); + + + /* then build up */ + Sink::operator=( fs ); + + init( fs.fileName); + + if ( (fd = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + fileDescriptor = fd; + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Check wether a file exists + *----------------------------------------------------------------------------*/ +bool +FileSink :: exists ( void ) const throw () +{ + struct stat st; + + if ( stat( (const char*)fileName, &st) == -1 ) { + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Create a file, truncate if already exists + *----------------------------------------------------------------------------*/ +bool +FileSink :: create ( void ) throw ( Exception ) +{ + int fd; + + if ( isOpen() ) { + return false; + } + + if ( (fd = ::creat( fileName, S_IRUSR | S_IWUSR)) == -1 ) { + throw Exception( __FILE__, __LINE__, "creat error", errno); + } + + ::close( fd); + return true; +} + + +/*------------------------------------------------------------------------------ + * Open the file + *----------------------------------------------------------------------------*/ +bool +FileSink :: open ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( (fileDescriptor = ::open( fileName, O_WRONLY | O_TRUNC, 0)) == -1 ) { + fileDescriptor = 0; + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +FileSink :: canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( fileDescriptor, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( fileDescriptor + 1, NULL, &fdset, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +FileSink :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + ssize_t ret; + + if ( !isOpen() ) { + return 0; + } + + ret = ::write( fileDescriptor, buf, len); + + if ( ret == -1 ) { + if ( errno == EAGAIN ) { + ret = 0; + } else { + throw Exception( __FILE__, __LINE__, "write error", errno); + } + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +FileSink :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + flush(); + ::close( fileDescriptor); + fileDescriptor = 0; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:51 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/FileSink.h b/darkice/tags/darkice-0_2/src/FileSink.h new file mode 100644 index 0000000..2eecf38 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/FileSink.h @@ -0,0 +1,264 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileSink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef FILE_SINK_H +#define FILE_SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * File data output + * + * @author $Author$ + * @version $Revision$ + */ +class FileSink : public Sink +{ + private: + + /** + * Name of the file represented by the FileSink. + */ + char * fileName; + + /** + * Initialize the object. + * + * @param name name of the file to be represented by the object. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Low-level file descriptor for the file represented by this object. + */ + int fileDescriptor; + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + FileSink ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor by a file name. + * + * @param name name of the file to be represented by the object. + * @exception Exception + */ + inline + FileSink( const char * name ) throw ( Exception ) + { + init( name); + } + + /** + * Copy constructor. + * + * @param fsink the FileSink to copy. + * @exception Exception + */ + FileSink( const FileSink & fsink ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~FileSink( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param fs the FileSink to assign to this object. + * @return a reference to this object. + * @exception Exception + */ + virtual FileSink & + operator= ( const FileSink & fs ) throw ( Exception ); + + /** + * Get the file name this FileSink represents. + * + * @return the file name this FileSink represents. + */ + inline const char * + getFileName ( void ) const throw () + { + return fileName; + } + + /** + * Check for the existence of the file this FileSink represents. + * + * @return true if the file exists, false otherwise. + */ + virtual bool + exists ( void ) const throw (); + + /** + * Create the file. + * + * @return true if creation was successful, false otherwise. + * @exception Exception + */ + virtual bool + create ( void ) throw ( Exception ); + + /** + * Open the file. Truncates the file. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the FileSink is open. + * + * @return true if the FileSink is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return fileDescriptor != 0; + } + + /** + * Check if the FileSink is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the Sink is ready to accept data, false otherwise. + * @exception Exception + */ + virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Write data to the FileSink. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * This is a no-op in this FileSink. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + } + + /** + * Close the FileSink. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* FILE_SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:51 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/FileSource.cpp b/darkice/tags/darkice-0_2/src/FileSource.cpp new file mode 100644 index 0000000..2f7dfb9 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/FileSource.cpp @@ -0,0 +1,270 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + + +#include "Exception.h" +#include "Util.h" +#include "FileSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +FileSource :: init ( const char * name ) throw ( Exception ) +{ + fileName = Util::strDup( name); + fileDescriptor = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +FileSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] fileName; + fileDescriptor = 0; +} + + +/*------------------------------------------------------------------------------ + * Copy Constructor + *----------------------------------------------------------------------------*/ +FileSource :: FileSource ( const FileSource & fs ) throw ( Exception ) +{ + init( fs.fileName); + + fileDescriptor = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0; + + if ( fileDescriptor == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +FileSource & +FileSource :: operator= ( const FileSource & fs ) throw ( Exception ) +{ + if ( this != &fs ) { + init( fs.fileName); + + fileDescriptor = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0; + + if ( fileDescriptor == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Check wether a file exists + *----------------------------------------------------------------------------*/ +bool +FileSource :: exists ( void ) const throw () +{ + struct stat st; + + if ( stat( (const char*)fileName, &st) == -1 ) { + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Open the source + *----------------------------------------------------------------------------*/ +bool +FileSource :: open ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) { + fileDescriptor = 0; + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +FileSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( fileDescriptor, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +FileSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + ssize_t ret; + + if ( !isOpen() ) { + return 0; + } + + ret = ::read( fileDescriptor, buf, len); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "read error"); + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +FileSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + ::close( fileDescriptor); + fileDescriptor = 0; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:51 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/FileSource.h b/darkice/tags/darkice-0_2/src/FileSource.h new file mode 100644 index 0000000..99b4cb7 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/FileSource.h @@ -0,0 +1,243 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef FILE_SOURCE_H +#define FILE_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Source.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A data source based on a file + * + * @author $Author$ + * @version $Revision$ + */ +class FileSource : public Source +{ + private: + + /** + * Name of the file represented by the FileSource. + */ + char * fileName; + + /** + * Initialize the object. + * + * @param name name of the file to be represented by the object. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Low-level file descriptor for the file represented by this object. + */ + int fileDescriptor; + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + FileSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor by a file name. + * + * @param name name of the file to be represented by the object. + * @exception Exception + */ + inline + FileSource ( const char * name ) throw ( Exception ) + { + init( name); + } + + /** + * Copy constructor. + * + * @param fs the FileSource to copy. + * @exception Exception + */ + FileSource ( const FileSource & fs ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline + ~FileSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param fs the FileSource to assign to this object. + * @return a reference to this object. + * @exception Exception + */ + inline virtual FileSource & + operator= ( const FileSource & fs ) throw ( Exception ); + + /** + * Get the file name this FileSource represents. + * + * @return the file name this FileSource represents. + */ + inline virtual const char * + getFileName ( void ) const throw () + { + return fileName; + } + + /** + * Check for the existence of the file this FileSource represents. + * + * @return true if the file exists, false otherwise. + */ + virtual bool + exists ( void ) const throw (); + + /** + * Open the file. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the FileSource is open. + * + * @return true if the FileSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return fileDescriptor != 0; + } + + /** + * Check if the FileSource has data available. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the FileSource has data to be read, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the FileSource. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the FileSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* FILE_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:51 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/IceCast.cpp b/darkice/tags/darkice-0_2/src/IceCast.cpp new file mode 100644 index 0000000..fd5ff06 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/IceCast.cpp @@ -0,0 +1,203 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : IceCast.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_STDIO_H +#include +#else +#error need stdio.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + + +#include "Exception.h" +#include "Source.h" +#include "Sink.h" +#include "IceCast.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Size of string conversion buffer + *----------------------------------------------------------------------------*/ +#define STRBUF_SIZE 32 + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +bool +IceCast :: sendLogin ( void ) throw ( Exception ) +{ + Sink * sink = getSink(); + Source * source = getSocket(); + const char * str; + char resp[STRBUF_SIZE]; + unsigned int len; + + if ( !source->isOpen() ) { + return false; + } + if ( !sink->isOpen() ) { + return false; + } + + /* send the request, a string like: + * "SOURCE /\n\n" */ + str = "SOURCE "; + sink->write( str, strlen( str)); + str = getPassword(); + sink->write( str, strlen( str)); + str = " /"; + sink->write( str, strlen( str)); + str = getMountPoint(); + sink->write( str, strlen( str)); + str = "\n\n"; + sink->write( str, strlen( str)); + sink->flush(); + + /* read the anticipated response: "OK" */ + len = source->read( resp, STRBUF_SIZE); + if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { + return false; + } + + /* suck anything that the other side has to say */ + while ( source->canRead( 0, 0) && + (len = source->read( resp, STRBUF_SIZE)) ) { + ; + } + + /* send the x-audiocast headers */ + str = "x-audiocast-name: "; + sink->write( str, strlen( str)); + str = getName(); + sink->write( str, strlen( str)); + + str = "\nx-audiocast-description: "; + sink->write( str, strlen( str)); + str = getDescription(); + sink->write( str, strlen( str)); + + str = "\nx-audiocast-url: "; + sink->write( str, strlen( str)); + str = getUrl(); + sink->write( str, strlen( str)); + + str = "\nx-audiocast-genre: "; + sink->write( str, strlen( str)); + str = getGenre(); + sink->write( str, strlen( str)); + + str = "\nx-audiocast-bitrate: "; + sink->write( str, strlen( str)); + if ( snprintf( resp, STRBUF_SIZE, "%d", getBitRate()) == -1 ) { + throw Exception( __FILE__, __LINE__, "snprintf overflow"); + } + sink->write( resp, strlen( resp)); + + str = "\nx-audiocast-public: "; + sink->write( str, strlen( str)); + str = getIsPublic() ? "yes" : "no"; + sink->write( str, strlen( str)); + + if ( getRemoteDumpFile() ) { + str = "\nx-audiocast-dumpfile: "; + sink->write( str, strlen( str)); + str = getRemoteDumpFile(); + sink->write( str, strlen( str)); + } + + str = "\n\n"; + sink->write( str, strlen( str)); + sink->flush(); + + /* read the anticipated response: "OK" */ + len = source->read( resp, STRBUF_SIZE); + if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { + return false; + } + + /* suck anything that the other side has to say */ + while ( source->canRead( 0, 0) && + (len = source->read( resp, STRBUF_SIZE)) ) { + ; + } + + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/IceCast.h b/darkice/tags/darkice-0_2/src/IceCast.h new file mode 100644 index 0000000..21e10d3 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/IceCast.h @@ -0,0 +1,201 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : IceCast.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef ICE_CAST_H +#define ICE_CAST_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Sink.h" +#include "TcpSocket.h" +#include "CastSink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Class representing output to an IceCast server with + * x-audiocast login + * + * @author $Author$ + * @version $Revision$ + */ +class IceCast : public CastSink +{ + private: + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + IceCast ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Log in to the server using the socket avialable. + * + * @return true if login was successful, false otherwise. + * @exception Exception + */ + virtual bool + sendLogin ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param mountPoint mount point of the stream on the server. + * @param remoteDumpFile remote dump file (may be NULL). + * @param name name of the stream. + * @param description description of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + inline + IceCast ( TcpSocket * socket, + const char * password, + const char * mountPoint, + const char * remoteDumpFile, + const char * name, + const char * description, + const char * url, + const char * genre, + unsigned int bitRate, + bool isPublic, + unsigned int bufferDuration = 10 ) + throw ( Exception ) + : CastSink( socket, + password, + mountPoint, + remoteDumpFile, + name, + description, + url, + genre, + bitRate, + isPublic, + bufferDuration ) + { + } + + /** + * Copy constructor. + * + * @param cs the IceCast to copy. + */ + inline + IceCast( const IceCast & cs ) throw ( Exception ) + : CastSink( cs ) + { + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~IceCast( void ) throw ( Exception ) + { + } + + /** + * Assignment operator. + * + * @param cs the IceCast to assign this to. + * @return a reference to this IceCast. + * @exception Exception + */ + inline virtual IceCast & + operator= ( const IceCast & cs ) throw ( Exception ) + { + if ( this != &cs ) { + CastSink::operator=( cs ); + } + return *this; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* ICE_CAST_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/LameEncoder.cpp b/darkice/tags/darkice-0_2/src/LameEncoder.cpp new file mode 100644 index 0000000..d442748 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/LameEncoder.cpp @@ -0,0 +1,160 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : LameEncoder.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_STDIO_H +#include +#else +#error need stdio.h +#endif + + +#include "Exception.h" +#include "LameEncoder.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +#define ARG_LEN 64 + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize command line parameters + *----------------------------------------------------------------------------*/ +unsigned int +LameEncoder :: makeArgs ( void ) throw ( Exception ) +{ + unsigned int u; + char str[ARG_LEN]; + + u = 0; + + setArg( getEncoderName(), u++); // name of the command + setArg( "-S", u++); // make it silent + setArg( "-r", u++); // input is raw PCM + setArg( "-x", u++); // input is little endian + setArg( "-h", u++); // high quality + + /* set input sample rate */ + if ( snprintf( str, ARG_LEN, "%.3f", + ((double)getInSampleRate()) / 1000.0 ) == -1 ) { + throw Exception( __FILE__, __LINE__, "snprintf overflow"); + } + setArg( "-s", u++); + setArg( str, u++); + + /* set stereo / mono */ + setArg( "-m", u++); + setArg( getOutChannel() == 1 ? "m" : "j", u++); + + /* set output bitrate */ + if ( snprintf( str, ARG_LEN, "%d", getOutBitrate()) == -1 ) { + throw Exception( __FILE__, __LINE__, "snprintf overflow"); + } + setArg( "-b", u++); + setArg( str, u++); + + /* set output sample rate */ + if ( snprintf( str, ARG_LEN, "%.3f", + ((double)getOutSampleRate()) / 1000.0 ) == -1 ) { + throw Exception( __FILE__, __LINE__, "snprintf overflow"); + } + setArg( "--resample", u++); + setArg( str, u++); + + /* set lowpass filter if needed */ + if ( lowpass ) { + if ( snprintf( str, ARG_LEN, "%.3f", + ((double)getLowpass()) / 1000.0 ) == -1 ) { + throw Exception( __FILE__, __LINE__, "snprintf overflow"); + } + setArg( "--lowpass", u++); + setArg( str, u++); + } + + /* set highpass filter if needed */ + if ( highpass ) { + if ( snprintf( str, ARG_LEN, "%.3f", + ((double)getHighpass()) / 1000.0 ) == -1 ) { + throw Exception( __FILE__, __LINE__, "snprintf overflow"); + } + setArg( "--highpass", u++); + setArg( str, u++); + } + + setArg( getInFileName(), u++); // input file + setArg( getOutFileName(), u++); // output file + + setArg( 0, u++); // terminating zero + + + return u; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/LameEncoder.h b/darkice/tags/darkice-0_2/src/LameEncoder.h new file mode 100644 index 0000000..a169c5a --- /dev/null +++ b/darkice/tags/darkice-0_2/src/LameEncoder.h @@ -0,0 +1,362 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : LameEncoder.h + Version : $Revision$ + Author : $Author$ + Location : $LameEncoder$ + + Abstract : + + A class representing the lame mp3 encoder + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + +------------------------------------------------------------------------------*/ +#ifndef LAME_ENCODER_H +#define LAME_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Exception.h" +#include "ExternalEncoder.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A class representing the lame mp3 encoder + * + * @author $Author$ + * @version $Revision$ + */ +class LameEncoder : public ExternalEncoder +{ + private: + + /** + * Highpass filter. Sound frequency in Hz, from where up the + * input is cut. + */ + unsigned int lowpass; + + /** + * Lowpass filter. Sound frequency in Hz, from where down the + * input is cut. + */ + unsigned int highpass; + + protected: + + /** + * Fill in the list of command line arguments. Puts a 0 + * as the last in the list of args. + * + * @return the number of arguments filled. + * @exception Exception + */ + virtual unsigned int + makeArgs ( void ) throw ( Exception ); + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + LameEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object. + * + * @param lowpass lowpass filter range. + * @param highpass highpass filter range. + * @exception Exception + */ + inline void + init ( unsigned int lowpass, + unsigned int highpass ) throw ( Exception ) + { + this->lowpass = lowpass; + this->highpass = highpass; + } + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + public: + + /** + * Constructor. + * + * @param encoderName name of the encoder. + * (the command to invoke the encoder with) + * @param inFileName input file parameter for the encoder. + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param outFileName output file parameter for the encoder. + * @param outBitrate bit rate of the output (bits/sec). + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @param highpass frequency threshold for the highpass filter. + * Input below this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + LameEncoder ( const char * encoderName, + const char * inFileName, + unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + const char * outFileName, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + unsigned int lowpass = 0, + unsigned int highpass = 0 ) + throw ( Exception ) + + : ExternalEncoder ( encoderName, + inFileName, + inSampleRate, + inBitsPerSample, + inChannel, + outFileName, + outBitrate, + outSampleRate, + outChannel ) + { + init( lowpass, highpass); + } + + /** + * Constructor. + * + * @param encoderName name of the encoder. + * (the command to invoke the encoder with) + * @param inFileName input file parameter for the encoder. + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outFileName output file parameter for the encoder. + * @param outBitrate bit rate of the output (bits/sec). + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @param highpass frequency threshold for the highpass filter. + * Input below this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + LameEncoder ( const char * encoderName, + const char * inFileName, + const AudioSource * as, + const char * outFileName, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + unsigned int lowpass = 0, + unsigned int highpass = 0 ) + throw ( Exception ) + + : ExternalEncoder ( encoderName, + inFileName, + as, + outFileName, + outBitrate, + outSampleRate, + outChannel ) + { + init( lowpass, highpass); + } + + /** + * Copy constructor. + * + * @param encoder the LameEncoder to copy. + */ + inline + LameEncoder ( const LameEncoder & encoder ) throw ( Exception ) + : ExternalEncoder( encoder ) + { + init( encoder.lowpass, encoder.highpass); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~LameEncoder ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param encoder the LameEncoder to assign this to. + * @return a reference to this LameEncoder. + * @exception Exception + */ + inline virtual LameEncoder & + operator= ( const LameEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + ExternalEncoder::operator=( encoder); + init( encoder.lowpass, encoder.highpass); + } + + return *this; + } + + /** + * Get the lowpass filter threshold. Sound frequency in Hz, + * from where up the input is cut. + * + * @return the lowpass filter threshold. + */ + inline unsigned int + getLowpass ( void ) const throw () + { + return lowpass; + } + + /** + * Set the lowpass filter threshold. Sound frequency in Hz, + * from where up the input is cut. + * Can be only set if encoding is not in progress. + * + * @param lowpass the lowpass filter threshold. + * @return if setting is successful. + */ + inline bool + setLowpass ( unsigned int lowpass ) throw () + { + if ( isRunning() ) { + return false; + } else { + this->lowpass = lowpass; + return true; + } + } + + /** + * Get the highpass filter threshold. Sound frequency in Hz, + * from where down the input is cut. + * + * @return the highpass filter threshold. + */ + inline unsigned int + getHighpass ( void ) const throw () + { + return highpass; + } + + /** + * Set the highpass filter threshold. Sound frequency in Hz, + * from where down the input is cut. + * Can be only set if encoding is not in progress. + * + * @param highpass the highpass filter threshold. + * @return if setting is successful. + */ + inline bool + setHighpass ( unsigned int highpass ) throw () + { + if ( isRunning() ) { + return false; + } else { + this->highpass = highpass; + return true; + } + } + + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* LAME_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Makefile.am b/darkice/tags/darkice-0_2/src/Makefile.am new file mode 100644 index 0000000..252f7a6 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Makefile.am @@ -0,0 +1,48 @@ +bin_PROGRAMS = darkice +INCLUDES = -I../stl +CXXFLAGS = -g -Wall + +darkice_SOURCES = AudioEncoder.h\ + AudioSource.h\ + BufferedSink.cpp\ + BufferedSink.h\ + CastSink.cpp\ + CastSink.h\ + Connector.cpp\ + Connector.h\ + DarkIce.cpp\ + DarkIce.h\ + Exception.cpp\ + Exception.h\ + ExternalEncoder.cpp\ + ExternalEncoder.h\ + FileSink.cpp\ + FileSink.h\ + FileSource.cpp\ + FileSource.h\ + IceCast.cpp\ + IceCast.h\ + LameEncoder.cpp\ + LameEncoder.h\ + OssDspSource.cpp\ + OssDspSource.h\ + PipeSink.cpp\ + PipeSink.h\ + PipeSource.cpp\ + PipeSource.h\ + Ref.h\ + Referable.h\ + Sink.h\ + Source.h\ + TcpSocket.cpp\ + TcpSocket.h\ + Util.cpp\ + Util.h\ + ConfigSection.h\ + ConfigSection.cpp\ + Config.h\ + Config.cpp\ + Reporter.h\ + Reporter.cpp\ + main.cpp + diff --git a/darkice/tags/darkice-0_2/src/OssDspSource.cpp b/darkice/tags/darkice-0_2/src/OssDspSource.cpp new file mode 100644 index 0000000..59c02d9 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/OssDspSource.cpp @@ -0,0 +1,286 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : OssDspSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#else +#error need sys/ioctl.h +#endif + +#ifdef HAVE_SYS_SOUNDCARD_H +#include +#else +#error need sys/soundcard.h +#endif + + +#include "Util.h" +#include "Exception.h" +#include "OssDspSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +OssDspSource :: init ( const char * name ) throw ( Exception ) +{ + fileName = Util::strDup( name); + fileDescriptor = 0; + running = false; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +OssDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] fileName; +} + + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +OssDspSource :: open ( void ) throw ( Exception ) +{ + int format; + int i; + unsigned int u; + + if ( isOpen() ) { + return false; + } + + switch ( getBitsPerSample() ) { + case 8: + format = AFMT_U8; + break; + + case 16: + format = AFMT_S16_LE; + break; + + default: + return false; + } + + if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) { + fileDescriptor = 0; + return false; + } + + i = format; + if ( ioctl( fileDescriptor, SNDCTL_DSP_SETFMT, &i) == -1 || + i != format ) { + + close(); + throw Exception( __FILE__, __LINE__, "can't set format", i); + } + + u = getChannel(); + if ( ioctl( fileDescriptor, SNDCTL_DSP_CHANNELS, &u) == -1 || + u != getChannel() ) { + + close(); + throw Exception( __FILE__, __LINE__, "can't set channels", i); + } + + u = getSampleRate(); + if ( ioctl( fileDescriptor, SNDCTL_DSP_SPEED, &u) == -1 || + u != getSampleRate() ) { + + close(); + throw Exception( __FILE__, __LINE__, "can't set speed", i); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +OssDspSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + if ( !running ) { + /* ugly workaround to get the dsp into recording state */ + unsigned char b[getChannel()*getBitsPerSample()/8]; + + read( b, getChannel()*getBitsPerSample()/8); + } + + FD_ZERO( &fdset); + FD_SET( fileDescriptor, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +OssDspSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + ssize_t ret; + + if ( !isOpen() ) { + return 0; + } + + ret = ::read( fileDescriptor, buf, len); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "read error"); + } + + running = true; + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +OssDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + ::close( fileDescriptor); + fileDescriptor = 0; + running = false; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.4 2000/11/13 20:05:07 darkeye + changed to workaround to start recording so that it reads one sample + per channel, as opposed to only one sample (which misalignes the channels) + + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/OssDspSource.h b/darkice/tags/darkice-0_2/src/OssDspSource.h new file mode 100644 index 0000000..4684fa9 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/OssDspSource.h @@ -0,0 +1,264 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : OssDspSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef OSS_DSP_SOURCE_H +#define OSS_DSP_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "AudioSource.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio input based on /dev/dsp-like raw devices + * + * @author $Author$ + * @version $Revision$ + */ +class OssDspSource : public AudioSource +{ + private: + + /** + * The file name of the OSS DSP device (e.g. /dev/dsp or /dev/dsp0). + */ + char * fileName; + + /** + * The low-level file descriptor of the OSS DSP device. + */ + int fileDescriptor; + + /** + * Indicates wether the low-level OSS DSP device is in a recording + * state. + */ + bool running; + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + OssDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @param name the file name of the OSS DSP device. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-iitialize the object + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param name the file name of the OSS DSP device + * (e.g. /dev/dsp or /dev/dsp0). + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + OssDspSource ( const char * name, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2 ) + throw ( Exception ) + + : AudioSource( sampleRate, bitsPerSample, channel) + { + init( name); + } + + /** + * Copy Constructor. + * + * @param source the object to copy. + * @exception Exception + */ + inline + OssDspSource ( const OssDspSource & ds ) throw ( Exception ) + : AudioSource( ds ) + { + init( ds.fileName); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~OssDspSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ds the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual OssDspSource & + operator= ( const OssDspSource & ds ) throw ( Exception ) + { + if ( this != &ds ) { + strip(); + AudioSource::operator=( ds); + init( ds.fileName); + } + return *this; + } + + /** + * Open the OssDspSource. + * This does not put the OSS DSP device into recording mode. + * To start getting samples, call either canRead() or read(). + * + * @return true if opening was successful, false otherwise + * @exception Exception + * + * @see #canRead + * @see #read + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the OssDspSource is open. + * + * @return true if the OssDspSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return fileDescriptor != 0; + } + + /** + * Check if the OssDspSource can be read from. + * Blocks until the specified time for data to be available. + * Puts the OSS DSP device into recording mode. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the OssDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the OssDspSource. + * Puts the OSS DSP device into recording mode. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the OssDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* OSS_DSP_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/PipeSink.cpp b/darkice/tags/darkice-0_2/src/PipeSink.cpp new file mode 100644 index 0000000..21fe06a --- /dev/null +++ b/darkice/tags/darkice-0_2/src/PipeSink.cpp @@ -0,0 +1,144 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : PipeSink.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + + +#include "Exception.h" +#include "PipeSink.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Create a pipe + *----------------------------------------------------------------------------*/ +bool +PipeSink :: create ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( mkfifo( getFileName(), S_IRUSR | S_IWUSR) == -1 ) { + if ( errno == EEXIST ) { + return true; + } + throw Exception( __FILE__, __LINE__, "mkfifo error", errno); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Open the file + *----------------------------------------------------------------------------*/ +bool +PipeSink :: open ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( (fileDescriptor = ::open( getFileName(), O_WRONLY, 0)) == -1 ) { + fileDescriptor = 0; + return false; + } + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/10 20:10:46 darkeye + changed from non-blocking to blocking + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/PipeSink.h b/darkice/tags/darkice-0_2/src/PipeSink.h new file mode 100644 index 0000000..4904519 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/PipeSink.h @@ -0,0 +1,174 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : PipeSink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef PIPE_SINK_H +#define PIPE_SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "FileSink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * FIFO pipe data output + * + * @author $Author$ + * @version $Revision$ + */ +class PipeSink : public FileSink +{ + private: + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + PipeSink ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor by a pipe name. + * + * @param name name of the pipe to be represented by the object. + * @exception Exception + */ + inline + PipeSink ( const char * name ) throw ( Exception ) + : FileSink( name ) + { + } + + /** + * Copy constructor. + * + * @param fsink the PipeSink to copy. + * @exception Exception + */ + inline + PipeSink ( const PipeSink & ps ) throw ( Exception ) + : FileSink( ps ) + { + } + + /** + * Assignment operator. + * + * @param ps the PipeSink to assign to this object. + * @return a reference to this object. + * @exception Exception + */ + inline virtual PipeSink & + operator= ( const PipeSink & ps ) throw ( Exception ) + { + if ( this != &ps ) { + FileSink::operator=( ps ); + } + + return *this; + } + + /** + * Destructor. + * + * @exception Exception + */ + virtual inline + ~PipeSink( void ) throw ( Exception ) + { + } + + /** + * Create the pipe. + * + * @return true if creation was successful, false otherwise. + * @exception Exception + */ + virtual bool + create ( void ) throw ( Exception ); + + /** + * Open the pipe. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* PIPE_SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/PipeSource.cpp b/darkice/tags/darkice-0_2/src/PipeSource.cpp new file mode 100644 index 0000000..3a0b1a9 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/PipeSource.cpp @@ -0,0 +1,122 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : PipeSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + + +#include "Exception.h" +#include "PipeSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Create a pipe + *----------------------------------------------------------------------------*/ +bool +PipeSource :: create ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( mkfifo( getFileName(), S_IRUSR | S_IWUSR) == -1 ) { + if ( errno == EEXIST ) { + return true; + } + throw Exception( __FILE__, __LINE__, "mkfifo error", errno); + } + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/PipeSource.h b/darkice/tags/darkice-0_2/src/PipeSource.h new file mode 100644 index 0000000..66540ce --- /dev/null +++ b/darkice/tags/darkice-0_2/src/PipeSource.h @@ -0,0 +1,169 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : PipeSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Abstract : + + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + +------------------------------------------------------------------------------*/ +#ifndef PIPE_SOURCE_H +#define PIPE_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "FileSource.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * FIFO pipe data input + * + * @author $Author$ + * @version $Revision$ + */ +class PipeSource : public FileSource +{ + private: + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + PipeSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor by a file name. + * + * @param name name of the file to be represented by the object. + * @exception Exception + */ + inline + PipeSource ( const char * name ) throw ( Exception ) + : FileSource( name ) + { + } + + /** + * Copy constructor. + * + * @param ps the PipeSource to copy. + * @exception Exception + */ + inline + PipeSource ( const PipeSource & ps ) throw ( Exception ) + : FileSource( ps ) + { + } + + /** + * Assignment operator. + * + * @param ps the PipeSource to assign to this object. + * @return a reference to this object. + * @exception Exception + */ + inline virtual PipeSource & + operator= ( const PipeSource & ps ) throw ( Exception ) + { + if ( this != &ps ) { + FileSource::operator=( ps ); + } + + return *this; + } + + /** + * Destructor. + * + * @exception Exception + */ + virtual inline + ~PipeSource( void ) throw ( Exception ) + { + } + + /** + * Create the pipe. + * + * @return true if creation was successful, false otherwise. + * @exception Exception + */ + virtual bool + create ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* PIPE_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Ref.h b/darkice/tags/darkice-0_2/src/Ref.h new file mode 100644 index 0000000..e32b723 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Ref.h @@ -0,0 +1,288 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Ref.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef REF_H +#define REF_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Java-like object reference class. + * Objects used with this reference class have to be descandents + * of class Referable. + * + * sample usage: + * + *
+ *  #include "Ref.h"
+ *  #include "Referable.h"
+ *
+ *  class  A : public virtual Referable;
+ *
+ *  ...
+ *   
+ *  A        * a = new A();
+ *  Ref     ref1 = a;       // 1 reference to a
+ *  Ref     ref2 = ref1;    // 2 references to a
+ *
+ *  ref1 = 0;      // 1 reference to a
+ *  ref2 = 0;      // at this point object a is destroyed
+ *  
+ * + * Based on Tima Saarinen's work, + * http://gamma.nic.fi/~timosa/comp/refcount.html + * + * @ref Referable + * + * @author $Author$ + * @version $Revision$ + */ +template +class Ref +{ + private: + + /** + * The object referenced by this Ref. + * Must be a descandant of Referable. + */ + T* object; + + + protected: + + + public: + + /** + * Default constructor. + */ + inline + Ref ( void ) throw () + { + object = NULL; + } + + /** + * Copy constructor. + * + * @param other the Ref to copy. + * @exception Exception + */ + inline + Ref ( const Ref & other ) throw ( Exception ) + { + object = NULL; + set( other.object); + } + + /** + * Constructor based on an object to reference. + * + * @param obj the object to reference. + * @exception Exception + */ + inline + Ref ( T * obj ) throw ( Exception ) + { + object = obj; + obj->increaseReferenceCount(); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Ref ( void ) throw ( Exception ) + { + set( 0 ); + } + + /** + * Operator overload to make the reference seem like a pointer. + * + * @return the pointer to the object referenced. + */ + inline T* + operator->() const throw () + { + if ( !object ) { + throw Exception( __FILE__, __LINE__, + "reference to NULL object"); + } + return object; + } + + /** + * Assignment operator. + * + * @param other the Ref to assign to this one. + * @return a reference to this Ref. + * @exception Exception + */ + inline Ref & + operator= ( Ref other ) throw ( Exception ) + { + set( other.object); + return *this; + } + + /** + * Assignment operator. + * + * @param obj pointer to the object to assign to this Ref. + * @return a reference to this Ref. + * @exception Exception + */ + inline Ref & + operator= ( T* obj ) throw ( Exception ) + { + set( obj); + return *this; + } + + /** + * Set the object referenced. + * Deletes the old referenced object is this was it's last reference. + * + * @param newobj pointer to the object to reference by this Ref. + * @exception Exception + */ + inline void + set ( T* newobj ) throw ( Exception ) + { + // If equal do nothing + if ( newobj == object ) { + return; + } + + // Increase reference count + if ( newobj ) { + newobj->increaseReferenceCount(); + } + + // Decrease the reference count of the old referable + if ( object ) { + if ( object->decreaseReferenceCount() == 0 ) { + delete object; + } + } + + // Assign + object = newobj; + } + + /** + * Return object pointer. This method should be used with + * care because it breaks the encapsulation. + * Typically this method is needed for the method calls + * which require literal object pointer. + * + * It may not be bad idea to pass the Ref + * objects as method arguments. + * + * @return Object pointer or NULL. + */ + inline T* + get ( void ) const throw () + { + return object; + } + + /** + * Equality operator. + * + * @param other the Ref to compare this with. + * @return true is the two Refs refer to the same object, + * false otherwise. + */ + inline bool + operator== ( const Ref & other ) const throw () + { + return object == other.object; + } + + /** + * Unequality operator. + * + * @param other the Ref to compare this with. + * @return false is the two Refs refer to the same object, + * true otherwise. + */ + inline bool + operator!= ( const Ref & other ) const throw () + { + return object != other.object; + } +}; + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* REF_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/11 14:55:31 darkeye + minor bugfix + + Revision 1.2 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Referable.h b/darkice/tags/darkice-0_2/src/Referable.h new file mode 100644 index 0000000..87ef065 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Referable.h @@ -0,0 +1,185 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Referable.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef REFERABLE_H +#define REFERABLE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Base class for an object for which references can be made + * with the reference class Ref. + * + * usage: + * + *
+ *  class A : public virtual Referable
+ *  {
+ *     ...
+ *  };
+ *  
+ * + * @ref Ref + * + * @author $Author$ + * @version $Revision$ + */ +class Referable +{ + private: + + /** + * Number of references to the object. + */ + unsigned int referenceCount; + + /** + * Maximum number of references before an overflow occurs. + */ + static const + unsigned int maxCount = ~((unsigned int)0); + + + protected: + + /** + * Default constructor. + */ + inline + Referable ( void ) throw () + { + referenceCount = 0; + } + + + /** + * Desctructor. + * + * @exception Exception + */ + inline virtual + ~Referable ( void ) throw ( Exception ) + { + if ( referenceCount > 0 ) { + throw Exception( __FILE__, __LINE__, + "reference count positive in destructor", + referenceCount); + } + } + + + public: + + /** + * Increase reference count. + * + * @return the new reference count. + * @exception Exception + */ + inline unsigned int + increaseReferenceCount ( void ) throw ( Exception ) + { + if ( referenceCount >= maxCount ) { + throw Exception( __FILE__, + __LINE__, + "reference count overflow", + referenceCount ); + } + return ++referenceCount; + } + + /** + * Decrease reference count. + * + * @return the new reference count. + * @exception Exception + */ + inline unsigned int + decreaseReferenceCount ( void ) throw ( Exception ) + { + if ( referenceCount == 0 ) { + throw Exception( __FILE__, __LINE__, + "reference count underflow", + referenceCount ); + } + return --referenceCount; + } + + /** + * Get the reference count. + * + * @return the reference count. + */ + inline unsigned int + getReferenceCount ( void ) const throw () + { + return referenceCount; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* REFERABLE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Reporter.cpp b/darkice/tags/darkice-0_2/src/Reporter.cpp new file mode 100644 index 0000000..beb670d --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Reporter.cpp @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Reporter + + File : Reporter.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include + +#include "Reporter.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Initial values for static members of the class + *----------------------------------------------------------------------------*/ +unsigned int Reporter::verbosity = 1; +ostream * Reporter::os = &cout; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2000/11/16 08:48:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Reporter.h b/darkice/tags/darkice-0_2/src/Reporter.h new file mode 100644 index 0000000..a4a4ff3 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Reporter.h @@ -0,0 +1,313 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Reporter + + File : Reporter.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef REPORTER_H +#define REPORTER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistdt.h +#endif + +#ifdef HAVE_TIME_H +#include +#else +#error need time.h +#endif + + +#include + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Class for reporting events. All objects of this class share + * the same verbosity level. Typical usage is to inherit this class + * and use the report() function to report events. Only reports + * which are of suffucient importance are really reported. + * + * The default verbosity is 1, and the default ostream is cout. + * + * Known problems: this class is not thread-safe. + * + * @author $Author$ + * @version $Revision$ + */ +class Reporter +{ + + + private: + + /** + * Verbosity level shared among all Reporter objects + */ + static unsigned int verbosity; + + /** + * The output stream to report to. + */ + static ostream * os; + + /** + * Print a prefix to each report. + */ + void + printPrefix( void ) throw () + { + char str[32]; + time_t now; + + now = time(NULL); + strftime( str, 32, "%H:%M:%S: ", localtime(&now) ); + (*(Reporter::os)) << str; + } + + + protected: + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Reporter ( void ) throw () + { + (Reporter::os)->flush(); + } + + /** + * Set the verbosity level. This sets the verbosity for all + * Reporter objects. + * + * @param verbosity the new verbosity level. + */ + inline void + setReportVerbosity ( unsigned int verbosity ) throw () + { + Reporter::verbosity = verbosity; + } + + /** + * Get the verbosity level. + * + * @return the current verbosity level. + */ + inline unsigned int + getReportVerbosity ( void ) throw () + { + return Reporter::verbosity; + } + + /** + * Set the output stream to report to. This setting effects all + * Reporter objects. + * + * @param os the output stream + */ + inline void + setReportOutputStream ( ostream & os ) throw () + { + Reporter::os = &os; + } + + /** + * Get the output stream to report to. + * + * @return the output stream + */ + inline ostream & + getReportOutputStream ( void ) throw () + { + return *(Reporter::os); + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + */ + template + inline void + reportEvent ( unsigned int verbosity, + const T t ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << endl; + } + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object 1 to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + * @param u the object 2 to report. Must have an + * ostream & operator<<( ostream&, const U) + * operator overload. + */ + template + inline void + reportEvent ( unsigned int verbosity, + const T t, + const U u ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << " " + << u << endl; + } + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object 1 to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + * @param u the object 2 to report. Must have an + * ostream & operator<<( ostream&, const U) + * operator overload. + * @param v the object 3 to report. Must have an + * ostream & operator<<( ostream&, const V) + * operator overload. + */ + template + inline void + reportEvent ( unsigned int verbosity, + const T t, + const U u, + const V v ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << " " + << u << " " + << v << endl; + } + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object 1 to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + * @param u the object 2 to report. Must have an + * ostream & operator<<( ostream&, const U) + * operator overload. + * @param v the object 3 to report. Must have an + * ostream & operator<<( ostream&, const V) + * operator overload. + * @param w the object 4 to report. Must have an + * ostream & operator<<( ostream&, const W) + * operator overload. + */ + template + inline void + reportEvent ( unsigned int verbosity, + const T t, + const U u, + const V v, + const W w ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << " " + << u << " " + << v << " " + << w << endl; + } + } +}; + + + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* REPORTER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/18 11:12:01 darkeye + added timestamp display, removed process id display in reports + changed reportEvent functions to template functions + + Revision 1.1 2000/11/16 08:48:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Sink.h b/darkice/tags/darkice-0_2/src/Sink.h new file mode 100644 index 0000000..fac29e6 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Sink.h @@ -0,0 +1,198 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Sink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef SINK_H +#define SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A general data sink + * + * @author $Author$ + * @version $Revision$ + */ +class Sink : public virtual Referable +{ + private: + + + protected: + + /** + * Default constructor. + */ + inline + Sink ( void ) throw () + { + } + + /** + * Copy constructor. + * + * @param sink the Sink to copy. + */ + inline + Sink ( const Sink & sink ) throw () + { + } + + /** + * Assignment operator. + * + * @param sink the Sink to assign this to. + * @return a reference to this Sink. + * @exception Exception + */ + inline virtual Sink & + operator= ( const Sink & sink ) throw ( Exception ) + { + return *this; + } + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Sink ( void ) throw ( Exception ) + { + } + + /** + * Open the sink. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ) = 0; + + /** + * Check if the Sink is open. + * + * @return true if the Sink is open, false otherwise. + */ + virtual bool + isOpen ( void ) const throw () = 0; + + /** + * Check if the Sink is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the Sink is ready to accept data, false otherwise. + * @exception Exception + */ + virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) = 0; + + /** + * Write data to the Sink. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ) = 0; + + /** + * Flush all data that was written to the Sink to the underlying + * construct. + * + * @exception Exception + */ + virtual void + flush ( void ) throw ( Exception ) = 0; + + /** + * Close the Sink. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ) = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/12 14:54:25 darkeye + added Exception to throws clause for the destructor and assignment operator + + Revision 1.3 2000/11/12 13:31:16 darkeye + minor change in documentation + + Revision 1.2 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Source.h b/darkice/tags/darkice-0_2/src/Source.h new file mode 100644 index 0000000..a8cac63 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Source.h @@ -0,0 +1,186 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Source.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef SOURCE_H +#define SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A general data source + * + * @author $Author$ + * @version $Revision$ + */ +class Source : public virtual Referable +{ + private: + + protected: + + /** + * Default Constructor. + * + * @exception Exception + */ + inline + Source ( void ) throw ( Exception ) + { + } + + /** + * Copy Constructor. + * + * @param source the object to copy. + * @exception Exception + */ + inline + Source ( const Source & source ) throw ( Exception ) + { + } + + /** + * Assignment operator. + * + * @param source the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual Source & + operator= ( const Source & source ) throw ( Exception ) + { + return *this; + } + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Source ( void ) throw ( Exception ) + { + } + + /** + * Open the Source. + * + * @return true if opening was successful, false otherwise + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ) = 0; + + /** + * Check if the Source is open. + * + * @return true if the Source is open, false otherwise. + */ + virtual bool + isOpen ( void ) const throw () = 0; + + /** + * Check if the Source can be read from. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the Source is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) = 0; + + /** + * Read from the Source. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ) = 0; + + /** + * Close the Source. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ) = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/TcpSocket.cpp b/darkice/tags/darkice-0_2/src/TcpSocket.cpp new file mode 100644 index 0000000..8a15295 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/TcpSocket.cpp @@ -0,0 +1,365 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : TcpSocket.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#else +#error need sys/socket.h +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#else +#error need netinet/in.h +#endif + +#ifdef HAVE_NETDB_H +#include +#else +#error need netdb.h +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + + +#include "Util.h" +#include "Exception.h" +#include "TcpSocket.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +TcpSocket :: init ( const char * host, + unsigned short port ) throw ( Exception ) +{ + this->host = Util::strDup( host); + this->port = port; + this->sockfd = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +TcpSocket :: strip ( void) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] host; +} + + +/*------------------------------------------------------------------------------ + * Copy Constructor + *----------------------------------------------------------------------------*/ +TcpSocket :: TcpSocket ( const TcpSocket & ss ) throw ( Exception ) + : Source( ss), Sink( ss ) +{ + int fd; + + init( ss.host, ss.port); + + if ( (fd = ss.sockfd ? dup( ss.sockfd) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + sockfd = fd; +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +TcpSocket & +TcpSocket :: operator= ( const TcpSocket & ss ) throw ( Exception ) +{ + if ( this != &ss ) { + int fd; + + /* first strip */ + strip(); + + + /* then build up */ + Sink::operator=( ss ); + Source::operator=( ss ); + + init( ss.host, ss.port); + + if ( (fd = ss.sockfd ? dup( ss.sockfd) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + sockfd = fd; + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Open the file + *----------------------------------------------------------------------------*/ +bool +TcpSocket :: open ( void ) throw ( Exception ) +{ + struct sockaddr_in addr; + struct hostent * pHostEntry; + + if ( isOpen() ) { + return false; + } + + if ( !(pHostEntry = gethostbyname( host)) ) { + throw Exception( __FILE__, __LINE__, "gethostbyname error", errno); + } + + if ( (sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ) { + throw Exception( __FILE__, __LINE__, "socket error", errno); + } + + memset( &addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = *((long*) pHostEntry->h_addr_list[0]); + + if ( connect( sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1 ) { + ::close( sockfd); + throw Exception( __FILE__, __LINE__, "connect error", errno); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +TcpSocket :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( sockfd, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( sockfd + 1, &fdset, NULL, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Read from the socket + *----------------------------------------------------------------------------*/ +unsigned int +TcpSocket :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + int ret; + + if ( !isOpen() ) { + return 0; + } + + ret = recv( sockfd, buf, len, 0); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "recv error", errno); + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +TcpSocket :: canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( sockfd, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( sockfd + 1, NULL, &fdset, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Write to the socket + *----------------------------------------------------------------------------*/ +unsigned int +TcpSocket :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + int ret; + + if ( !isOpen() ) { + return 0; + } + +// ret = send( sockfd, buf, len, MSG_DONTWAIT); + ret = send( sockfd, buf, len, 0); + + if ( ret == -1 ) { + if ( errno == EAGAIN ) { + ret = 0; + } else { + throw Exception( __FILE__, __LINE__, "send error", errno); + } + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the socket + *----------------------------------------------------------------------------*/ +void +TcpSocket :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + flush(); + ::close( sockfd); + sockfd = 0; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/TcpSocket.h b/darkice/tags/darkice-0_2/src/TcpSocket.h new file mode 100644 index 0000000..df8d4cb --- /dev/null +++ b/darkice/tags/darkice-0_2/src/TcpSocket.h @@ -0,0 +1,297 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : TcpSocket.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef TCP_SOCKET_H +#define TCP_SOCKET_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Source.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A TCP network socket + * + * @author $Author$ + * @version $Revision$ + */ +class TcpSocket : public Source, public Sink +{ + private: + + /** + * Name of the host this socket connects to. + */ + char * host; + + /** + * Port to connect to. + */ + unsigned short port; + + /** + * Low-level socket descriptor. + */ + int sockfd; + + /** + * Initialize the object. + * + * @param host name of the host this socket connects to. + * @param port port to connect to. + * @exception Exception + */ + void + init ( const char * host, + unsigned short port ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + TcpSocket ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor. + * + * @param host name of the host this socket connects to. + * @param port port to connect to. + * @exception Exception + */ + inline + TcpSocket( const char * host, + unsigned short port ) throw ( Exception ) + { + init( host, port); + } + + /** + * Copy constructor. + * + * @param ss the TcpSocket to copy. + * @exception Exception + */ + TcpSocket( const TcpSocket & ss ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~TcpSocket( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ss the TcpSocket to assign this to. + * @return a reference to this TcpSocket. + * @exception Exception + */ + inline virtual TcpSocket & + operator= ( const TcpSocket & ss ) throw ( Exception ); + + /** + * Get the host this socket connects to. + * + * @return the host this socket connects to. + */ + inline const char * + getHost ( void ) const throw () + { + return host; + } + + /** + * Get the port this socket connects to. + * + * @return the port this socket connects to. + */ + inline unsigned int + getPort ( void ) const throw () + { + return port; + } + + /** + * Open the TcpSocket. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the TcpSocket is open. + * + * @return true if the TcpSocket is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return sockfd != 0; + } + + /** + * Check if the TcpScoket can be read from. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the TcpSocket is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the TcpSocket. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + + /** + * Check if the TcpSocket is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the TcpSocket is ready to accept data, + * false otherwise. + * @exception Exception + */ + virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Write data to the TcpSocket. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the TcpSocket to the underlying + * connection. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + } + + /** + * Close the TcpSocket. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* TCP_SOCKET_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Util.cpp b/darkice/tags/darkice-0_2/src/Util.cpp new file mode 100644 index 0000000..a7550e0 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Util.cpp @@ -0,0 +1,206 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Util.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_STDLIB_H +#include +#else +#error need stdlib.h +#endif + +#ifdef HAVE_LIMITS_H +#include +#else +#error need limits.h +#endif + + +#include "Util.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Calculate the length of a zero-terminated C string, + * w/o the zero-termination + *----------------------------------------------------------------------------*/ +unsigned int +Util :: strLen( const char * str ) throw ( Exception ) +{ + size_t len; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + len = strlen( str); + + return len; +} + + +/*------------------------------------------------------------------------------ + * Copy the contents of a string into another + *----------------------------------------------------------------------------*/ +void +Util :: strCpy ( char * dest, + const char * src ) throw ( Exception ) +{ + if ( !dest || !src ) { + throw Exception( __FILE__, __LINE__, "no src or dest"); + } + + strcpy( dest, src); +} + + +/*------------------------------------------------------------------------------ + * Concatenate the contents of a string onto another + *----------------------------------------------------------------------------*/ +void +Util :: strCat ( char * dest, + const char * src ) throw ( Exception ) +{ + if ( !dest || !src ) { + throw Exception( __FILE__, __LINE__, "no src or dest"); + } + + strcat( dest, src); +} + + +/*------------------------------------------------------------------------------ + * Duplicate a string by allocating space with new[] + * The returned string must be freed with delete[] + *----------------------------------------------------------------------------*/ +char * +Util :: strDup( const char * str ) throw ( Exception ) +{ + size_t len; + char * s; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + len = strlen( str) + 1; + s = new char[len]; + memcpy( s, str, len); + + return s; +} + + +/*------------------------------------------------------------------------------ + * Check wether two strings are equal + *----------------------------------------------------------------------------*/ +bool +Util :: strEq( const char * str1, + const char * str2 ) throw ( Exception ) +{ + if ( !str1 || !str2 ) { + throw Exception( __FILE__, __LINE__, "no str1 or no str2"); + } + + return !strcmp( str1, str2); +} + + +/*------------------------------------------------------------------------------ + * Convert a string to a long integer + *----------------------------------------------------------------------------*/ +long int +Util :: strToL( const char * str, + int base ) throw ( Exception ) +{ + long int val; + char * s; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + val = strtol( str, &s, base); + if ( s == str || val == LONG_MIN || val == LONG_MAX ) { + throw Exception( __FILE__, __LINE__, "number conversion error"); + } + + return val; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.4 2000/11/09 22:04:33 darkeye + added functions strLen strCpy and strCat + + Revision 1.3 2000/11/09 06:44:21 darkeye + added strEq and strToL functions + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/Util.h b/darkice/tags/darkice-0_2/src/Util.h new file mode 100644 index 0000000..0dbf7a9 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/Util.h @@ -0,0 +1,222 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Util.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef UTIL_H +#define UTIL_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Widely used utilities. + * This class can not be instantiated, but contains useful (?) static + * functions. + * + * Typical usage: + * + *
+ *  #include "Util.h"
+ *  
+ *  char  * str = Util::strDup( otherStr);
+ *  
+ * + * @author $Author$ + * @version $Revision$ + */ +class Util +{ + private: + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + Util ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Copy constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + Util ( const Util & e ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Destructor. Always throws an Exception. + * + * @exception Exception + */ + inline + ~Util ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Assignment operator. Always throws an Exception. + * + * @param u the object to assign to this one. + * @exception Exception + */ + inline Util & + operator= ( const Util & u ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + + public: + + /** + * Determine a C string's length. + * + * @param str a zero-terminated C string. + * @return length of str + * @exception Exception + */ + static unsigned int + strLen ( const char * str ) throw ( Exception ); + + /** + * Copy a C string into another. + * + * @param dest place for the copy. Storage size must be at least + * Util::strLen(src) + 1 long. + * @param str the string to copy. + * @exception Exception + */ + static void + strCpy ( char * dest, + const char * src ) throw ( Exception ); + + /** + * Concatenate a string to another's end. + * + * @param dest the string to concatenate to. + * Storage size of dest must be at least + * Util::strLen(dest) + Util::strLen(src) + 1 long. + * @param str the string to concatenate. + * @exception Exception + */ + static void + strCat ( char * dest, + const char * src ) throw ( Exception ); + + /** + * Duplicate a string by allocating space with new[]. + * The returned string must be freed with delete[]. + * + * @param str the string to duplicate. + * @exception Exception + */ + static char * + strDup ( const char * str ) throw ( Exception ); + + /** + * Determine wether two string are equal. + * + * @param str1 one of the strings. + * @param str2 the other string. + * @return true if the two strings are equal, false othersize. + * @exception Exception + */ + static bool + strEq ( const char * str1, + const char * str2 ) throw ( Exception ); + + /** + * Convert a string to long. + * + * @param str the string to convert. + * @param base numeric base of number in str. + * @return the value of str as a long int + * @exception Exception + */ + static long int + strToL ( const char * str, + int base = 10 ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* UTIL_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/09 22:04:33 darkeye + added functions strLen strCpy and strCat + + Revision 1.2 2000/11/09 06:44:21 darkeye + added strEq and strToL functions + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/src/main.cpp b/darkice/tags/darkice-0_2/src/main.cpp new file mode 100644 index 0000000..3dfe279 --- /dev/null +++ b/darkice/tags/darkice-0_2/src/main.cpp @@ -0,0 +1,192 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : main.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Abstract : + + Program entry point + + Copyright notice: + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#ifdef HAVE_GETOPT_H +#include +#else +#error need getopt.h +#endif + +#include +#include + +#include "Ref.h" +#include "Exception.h" +#include "Util.h" +#include "DarkIce.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + +/*------------------------------------------------------------------------------ + * Show program usage + *----------------------------------------------------------------------------*/ +static void +showUsage ( ostream & os ); + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Program entry point + *----------------------------------------------------------------------------*/ +int +main ( + int argc, + char * argv[] ) +{ + int res = -1; + + cout << "DarkIce " << VERSION + << " live audio streamer, http://darkice.sourceforge.net" << endl; + cout << "Copyright (C) 2000, Tyrell Hungary, http://tyrell.hu" << endl; + cout << endl; + + try { + const char * configFileName = 0; + unsigned int verbosity = 1; + int i; + const char opts[] = "hc:v:"; + static struct option long_options[] = { + { "config", 1, 0, 'c'}, + { "help", 0, 0, 'h'}, + { "verbosity", 1, 0, 'v'}, + { 0, 0, 0, 0} + }; + + + while ( (i = getopt_long( argc, argv, opts, long_options, 0)) != -1 ) { + switch ( i ) { + case 'c': + configFileName = optarg; + break; + + case 'v': + verbosity = Util::strToL( optarg); + break; + + default: + case ':': + case '?': + case 'h': + showUsage( cout); + return 1; + } + } + + if ( !configFileName ) { + throw Exception( __FILE__, __LINE__, + "no configuration file specified"); + } + + cout << "Using config file: " << configFileName << endl; + + ifstream configFile( configFileName); + Config config( configFile); + Ref di = new DarkIce( config); + di->setReportVerbosity( verbosity ); + di->setReportOutputStream( cout ); + + res = di->run(); + + } catch ( Exception & e ) { + cout << "DarkIce: " << e << endl << flush; + } + + return res; +} + + +/*------------------------------------------------------------------------------ + * Show program usage + *----------------------------------------------------------------------------*/ +static void +showUsage ( ostream & os ) +{ + os + << "usage: darkice -c config.file" + << endl + << endl + << "options:" + << endl + << " -c, --config=config.file use configuration file config.file" + << endl + << " -v, --verbosity=number verbosity level (0 = silent, 10 = loud)" + << endl + << " -h, --help print this message and exit" + << endl + << endl; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.4 2000/11/13 20:21:29 darkeye + added program version display on startup + + Revision 1.3 2000/11/13 19:38:55 darkeye + moved command line parameter parsing from DarkIce.cpp to main.cpp + + Revision 1.2 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_2/stamp-h.in b/darkice/tags/darkice-0_2/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/darkice/tags/darkice-0_2/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/darkice/tags/darkice-0_2/stl/algo.h b/darkice/tags/darkice-0_2/stl/algo.h new file mode 100644 index 0000000..1707868 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/algo.h @@ -0,0 +1,114 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ALGO_H +#define __SGI_STL_ALGO_H + +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES + +// Names from +using __STD::for_each; +using __STD::find; +using __STD::find_if; +using __STD::adjacent_find; +using __STD::count; +using __STD::count_if; +using __STD::search; +using __STD::search_n; +using __STD::swap_ranges; +using __STD::transform; +using __STD::replace; +using __STD::replace_if; +using __STD::replace_copy; +using __STD::replace_copy_if; +using __STD::generate; +using __STD::generate_n; +using __STD::remove; +using __STD::remove_if; +using __STD::remove_copy; +using __STD::remove_copy_if; +using __STD::unique; +using __STD::unique_copy; +using __STD::reverse; +using __STD::reverse_copy; +using __STD::rotate; +using __STD::rotate_copy; +using __STD::random_shuffle; +using __STD::random_sample; +using __STD::random_sample_n; +using __STD::partition; +using __STD::stable_partition; +using __STD::sort; +using __STD::stable_sort; +using __STD::partial_sort; +using __STD::partial_sort_copy; +using __STD::nth_element; +using __STD::lower_bound; +using __STD::upper_bound; +using __STD::equal_range; +using __STD::binary_search; +using __STD::merge; +using __STD::inplace_merge; +using __STD::includes; +using __STD::set_union; +using __STD::set_intersection; +using __STD::set_difference; +using __STD::set_symmetric_difference; +using __STD::min_element; +using __STD::max_element; +using __STD::next_permutation; +using __STD::prev_permutation; +using __STD::find_first_of; +using __STD::find_end; +using __STD::is_sorted; +using __STD::is_heap; + +// Names from stl_heap.h +using __STD::push_heap; +using __STD::pop_heap; +using __STD::make_heap; +using __STD::sort_heap; + +// Names from +using __STD::accumulate; +using __STD::inner_product; +using __STD::partial_sum; +using __STD::adjacent_difference; +using __STD::power; +using __STD::iota; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ALGO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/algobase.h b/darkice/tags/darkice-0_2/stl/algobase.h new file mode 100644 index 0000000..f35e7af --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/algobase.h @@ -0,0 +1,71 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ALGOBASE_H +#define __SGI_STL_ALGOBASE_H + +#ifndef __SGI_STL_PAIR_H +#include +#endif +#ifndef __SGI_STL_ITERATOR_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_ALGOBASE_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +// Names from stl_algobase.h +using __STD::iter_swap; +using __STD::swap; +using __STD::min; +using __STD::max; +using __STD::copy; +using __STD::copy_backward; +using __STD::copy_n; +using __STD::fill; +using __STD::fill_n; +using __STD::mismatch; +using __STD::equal; +using __STD::lexicographical_compare; +using __STD::lexicographical_compare_3way; + +// Names from stl_uninitialized.h +using __STD::uninitialized_copy; +using __STD::uninitialized_copy_n; +using __STD::uninitialized_fill; +using __STD::uninitialized_fill_n; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/algorithm b/darkice/tags/darkice-0_2/stl/algorithm new file mode 100644 index 0000000..1ba584f --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/algorithm @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ALGORITHM +#define __SGI_STL_ALGORITHM + +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_ALGORITHM */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/alloc.h b/darkice/tags/darkice-0_2/stl/alloc.h new file mode 100644 index 0000000..f99a862 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/alloc.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ALLOC_H +#define __SGI_STL_ALLOC_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_ALLOC_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::__malloc_alloc_template; +using __STD::malloc_alloc; +using __STD::simple_alloc; +using __STD::debug_alloc; +using __STD::__default_alloc_template; +using __STD::alloc; +using __STD::single_client_alloc; +#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG +using __STD::__malloc_alloc_oom_handler; +#endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */ +#ifdef __STL_USE_STD_ALLOCATORS +using __STD::allocator; +#endif /* __STL_USE_STD_ALLOCATORS */ + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/bitset b/darkice/tags/darkice-0_2/stl/bitset new file mode 100644 index 0000000..8328b20 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/bitset @@ -0,0 +1,1074 @@ +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_BITSET +#define __SGI_STL_BITSET + +// A bitset of size N has N % (sizeof(unsigned long) * CHAR_BIT) unused +// bits. (They are the high- order bits in the highest word.) It is +// a class invariant of class bitset<> that those unused bits are +// always zero. + +// Most of the actual code isn't contained in bitset<> itself, but in the +// base class _Base_bitset. The base class works with whole words, not with +// individual bits. This allows us to specialize _Base_bitset for the +// important special case where the bitset is only a single word. + +// The C++ standard does not define the precise semantics of operator[]. +// In this implementation the const version of operator[] is equivalent +// to test(), except that it does no range checking. The non-const version +// returns a reference to a bit, again without doing any range checking. + + +#include // for size_t +#include // for memset +#include +#include // for invalid_argument, out_of_range, overflow_error + +#ifdef __STL_USE_NEW_IOSTREAMS +#include +#else +#include // for istream, ostream +#endif + +#define __BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long)) +#define __BITSET_WORDS(__n) \ + ((__n) < 1 ? 1 : ((__n) + __BITS_PER_WORD - 1)/__BITS_PER_WORD) + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +// structure to aid in counting bits +template +struct _Bit_count { + static unsigned char _S_bit_count[256]; +}; + +// Mapping from 8 bit unsigned integers to the index of the first one +// bit: +template +struct _First_one { + static unsigned char _S_first_one[256]; +}; + +// +// Base class: general case. +// + +template +struct _Base_bitset { + typedef unsigned long _WordT; + + _WordT _M_w[_Nw]; // 0 is the least significant word. + + _Base_bitset( void ) { _M_do_reset(); } + _Base_bitset(unsigned long __val) { + _M_do_reset(); + _M_w[0] = __val; + } + + static size_t _S_whichword( size_t __pos ) + { return __pos / __BITS_PER_WORD; } + static size_t _S_whichbyte( size_t __pos ) + { return (__pos % __BITS_PER_WORD) / CHAR_BIT; } + static size_t _S_whichbit( size_t __pos ) + { return __pos % __BITS_PER_WORD; } + static _WordT _S_maskbit( size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& _M_getword(size_t __pos) { return _M_w[_S_whichword(__pos)]; } + _WordT _M_getword(size_t __pos) const { return _M_w[_S_whichword(__pos)]; } + + _WordT& _M_hiword() { return _M_w[_Nw - 1]; } + _WordT _M_hiword() const { return _M_w[_Nw - 1]; } + + void _M_do_and(const _Base_bitset<_Nw>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] &= __x._M_w[__i]; + } + } + + void _M_do_or(const _Base_bitset<_Nw>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] |= __x._M_w[__i]; + } + } + + void _M_do_xor(const _Base_bitset<_Nw>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] ^= __x._M_w[__i]; + } + } + + void _M_do_left_shift(size_t __shift); + void _M_do_right_shift(size_t __shift); + + void _M_do_flip() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = ~_M_w[__i]; + } + } + + void _M_do_set() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = ~static_cast<_WordT>(0); + } + } + + void _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); } + + bool _M_is_equal(const _Base_bitset<_Nw>& __x) const { + for (size_t __i = 0; __i < _Nw; ++__i) { + if (_M_w[__i] != __x._M_w[__i]) + return false; + } + return true; + } + + bool _M_is_any() const { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + if ( _M_w[__i] != static_cast<_WordT>(0) ) + return true; + } + return false; + } + + size_t _M_do_count() const { + size_t __result = 0; + const unsigned char* __byte_ptr = (const unsigned char*)_M_w; + const unsigned char* __end_ptr = (const unsigned char*)(_M_w+_Nw); + + while ( __byte_ptr < __end_ptr ) { + __result += _Bit_count::_S_bit_count[*__byte_ptr]; + __byte_ptr++; + } + return __result; + } + + unsigned long _M_do_to_ulong() const; + + // find first "on" bit + size_t _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t _M_do_find_next(size_t __prev, size_t __not_found) const; +}; + +// +// Definitions of non-inline functions from _Base_bitset. +// + +template +void _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) +{ + if (__shift != 0) { + const size_t __wshift = __shift / __BITS_PER_WORD; + const size_t __offset = __shift % __BITS_PER_WORD; + + if (__offset == 0) + for (size_t __n = _Nw - 1; __n >= __wshift; --__n) + _M_w[__n] = _M_w[__n - __wshift]; + + else { + const size_t __sub_offset = __BITS_PER_WORD - __offset; + for (size_t __n = _Nw - 1; __n > __wshift; --__n) + _M_w[__n] = (_M_w[__n - __wshift] << __offset) | + (_M_w[__n - __wshift - 1] >> __sub_offset); + _M_w[__wshift] = _M_w[0] << __offset; + } + + fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); + } +} + +template +void _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) +{ + if (__shift != 0) { + const size_t __wshift = __shift / __BITS_PER_WORD; + const size_t __offset = __shift % __BITS_PER_WORD; + const size_t __limit = _Nw - __wshift - 1; + + if (__offset == 0) + for (size_t __n = 0; __n <= __limit; ++__n) + _M_w[__n] = _M_w[__n + __wshift]; + + else { + const size_t __sub_offset = __BITS_PER_WORD - __offset; + for (size_t __n = 0; __n < __limit; ++__n) + _M_w[__n] = (_M_w[__n + __wshift] >> __offset) | + (_M_w[__n + __wshift + 1] << __sub_offset); + _M_w[__limit] = _M_w[_Nw-1] >> __offset; + } + + fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); + } +} + +template +unsigned long _Base_bitset<_Nw>::_M_do_to_ulong() const +{ + for (size_t __i = 1; __i < _Nw; ++__i) + if (_M_w[__i]) + __STL_THROW(overflow_error("bitset")); + + return _M_w[0]; +} + +template +size_t _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const +{ + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _WordT __thisword = _M_w[__i]; + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORD + __j*CHAR_BIT + + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + } + // not found, so return an indication of failure. + return __not_found; +} + +template +size_t +_Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const +{ + // make bound inclusive + ++__prev; + + // check out of bounds + if ( __prev >= _Nw * __BITS_PER_WORD ) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = _M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + // get first byte into place + __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; + for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORD + __j*CHAR_BIT + + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + + // check subsequent words + __i++; + for ( ; __i < _Nw; __i++ ) { + _WordT __thisword = _M_w[__i]; + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORD + __j*CHAR_BIT + + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + } + + // not found, so return an indication of failure. + return __not_found; +} // end _M_do_find_next + + +// ------------------------------------------------------------ + +// +// Base class: specialization for a single word. +// + +__STL_TEMPLATE_NULL struct _Base_bitset<1> { + typedef unsigned long _WordT; + _WordT _M_w; + + _Base_bitset( void ) : _M_w(0) {} + _Base_bitset(unsigned long __val) : _M_w(__val) {} + + static size_t _S_whichword( size_t __pos ) + { return __pos / __BITS_PER_WORD; } + static size_t _S_whichbyte( size_t __pos ) + { return (__pos % __BITS_PER_WORD) / CHAR_BIT; } + static size_t _S_whichbit( size_t __pos ) + { return __pos % __BITS_PER_WORD; } + static _WordT _S_maskbit( size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& _M_getword(size_t) { return _M_w; } + _WordT _M_getword(size_t) const { return _M_w; } + + _WordT& _M_hiword() { return _M_w; } + _WordT _M_hiword() const { return _M_w; } + + void _M_do_and(const _Base_bitset<1>& __x) { _M_w &= __x._M_w; } + void _M_do_or(const _Base_bitset<1>& __x) { _M_w |= __x._M_w; } + void _M_do_xor(const _Base_bitset<1>& __x) { _M_w ^= __x._M_w; } + void _M_do_left_shift(size_t __shift) { _M_w <<= __shift; } + void _M_do_right_shift(size_t __shift) { _M_w >>= __shift; } + void _M_do_flip() { _M_w = ~_M_w; } + void _M_do_set() { _M_w = ~static_cast<_WordT>(0); } + void _M_do_reset() { _M_w = 0; } + + bool _M_is_equal(const _Base_bitset<1>& __x) const + { return _M_w == __x._M_w; } + bool _M_is_any() const + { return _M_w != 0; } + + size_t _M_do_count() const { + size_t __result = 0; + const unsigned char* __byte_ptr = (const unsigned char*)&_M_w; + const unsigned char* __end_ptr + = ((const unsigned char*)&_M_w)+sizeof(_M_w); + while ( __byte_ptr < __end_ptr ) { + __result += _Bit_count::_S_bit_count[*__byte_ptr]; + __byte_ptr++; + } + return __result; + } + + unsigned long _M_do_to_ulong() const { return _M_w; } + + size_t _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t _M_do_find_next(size_t __prev, size_t __not_found) const; + +}; + +// +// Definitions of non-inline functions from the single-word version of +// _Base_bitset. +// + +size_t _Base_bitset<1>::_M_do_find_first(size_t __not_found) const +{ + _WordT __thisword = _M_w; + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + // not found, so return a value that indicates failure. + return __not_found; +} + +size_t _Base_bitset<1>::_M_do_find_next(size_t __prev, size_t __not_found ) const +{ + // make bound inclusive + ++__prev; + + // check out of bounds + if ( __prev >= __BITS_PER_WORD ) + return __not_found; + + // search first (and only) word + _WordT __thisword = _M_w; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + // get first byte into place + __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; + for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + + // not found, so return a value that indicates failure. + return __not_found; +} // end _M_do_find_next + + +// ------------------------------------------------------------ +// Helper class to zero out the unused high-order bits in the highest word. + +template struct _Sanitize { + static void _M_do_sanitize(unsigned long& __val) + { __val &= ~((~static_cast(0)) << _Extrabits); } +}; + +__STL_TEMPLATE_NULL struct _Sanitize<0> { + static void _M_do_sanitize(unsigned long) {} +}; + + + +// ------------------------------------------------------------ +// Class bitset. +// _Nb may be any nonzero number of type size_t. + +template +class bitset : private _Base_bitset<__BITSET_WORDS(_Nb)> +{ +private: + typedef _Base_bitset<__BITSET_WORDS(_Nb)> _Base; + typedef unsigned long _WordT; + +private: + void _M_do_sanitize() { + _Sanitize<_Nb%__BITS_PER_WORD>::_M_do_sanitize(this->_M_hiword()); + } + +public: + + // bit reference: + class reference; + friend class reference; + + class reference { + friend class bitset; + + _WordT *_M_wp; + size_t _M_bpos; + + // left undefined + reference(); + + public: + reference( bitset& __b, size_t __pos ) { + _M_wp = &__b._M_getword(__pos); + _M_bpos = _Base::_S_whichbit(__pos); + } + + ~reference() {} + + // for b[i] = __x; + reference& operator=(bool __x) { + if ( __x ) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + + return *this; + } + + // for b[i] = b[__j]; + reference& operator=(const reference& __j) { + if ( (*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)) ) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + + return *this; + } + + // flips the bit + bool operator~() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } + + // for __x = b[i]; + operator bool() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } + + // for b[i].flip(); + reference& flip() { + *_M_wp ^= _Base::_S_maskbit(_M_bpos); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() {} + bitset(unsigned long __val) : _Base_bitset<__BITSET_WORDS(_Nb)>(__val) + { _M_do_sanitize(); } + +#ifdef __STL_MEMBER_TEMPLATES + template + explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __pos = 0) + : _Base() + { + if (__pos > __s.size()) + __STL_THROW(out_of_range("bitset")); + _M_copy_from_string(__s, __pos, + basic_string<_CharT, _Traits, _Alloc>::npos); + } + template + bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __pos, + size_t __n) + : _Base() + { + if (__pos > __s.size()) + __STL_THROW(out_of_range("bitset")); + _M_copy_from_string(__s, __pos, __n); + } +#else /* __STL_MEMBER_TEMPLATES */ + explicit bitset(const basic_string& __s, + size_t __pos = 0, + size_t __n = basic_string::npos) + : _Base() + { + if (__pos > __s.size()) + __STL_THROW(out_of_range("bitset")); + _M_copy_from_string(__s, __pos, __n); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + // 23.3.5.2 bitset operations: + bitset<_Nb>& operator&=(const bitset<_Nb>& __rhs) { + this->_M_do_and(__rhs); + return *this; + } + + bitset<_Nb>& operator|=(const bitset<_Nb>& __rhs) { + this->_M_do_or(__rhs); + return *this; + } + + bitset<_Nb>& operator^=(const bitset<_Nb>& __rhs) { + this->_M_do_xor(__rhs); + return *this; + } + + bitset<_Nb>& operator<<=(size_t __pos) { + this->_M_do_left_shift(__pos); + this->_M_do_sanitize(); + return *this; + } + + bitset<_Nb>& operator>>=(size_t __pos) { + this->_M_do_right_shift(__pos); + this->_M_do_sanitize(); + return *this; + } + + // + // Extension: + // Versions of single-bit set, reset, flip, test with no range checking. + // + + bitset<_Nb>& _Unchecked_set(size_t __pos) { + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& _Unchecked_set(size_t __pos, int __val) { + if (__val) + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + else + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + + return *this; + } + + bitset<_Nb>& _Unchecked_reset(size_t __pos) { + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& _Unchecked_flip(size_t __pos) { + this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); + return *this; + } + + bool _Unchecked_test(size_t __pos) const { + return (this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) + != static_cast<_WordT>(0); + } + + // Set, reset, and flip. + + bitset<_Nb>& set() { + this->_M_do_set(); + this->_M_do_sanitize(); + return *this; + } + + bitset<_Nb>& set(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_set(__pos); + } + + bitset<_Nb>& set(size_t __pos, int __val) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_set(__pos, __val); + } + + bitset<_Nb>& reset() { + this->_M_do_reset(); + return *this; + } + + bitset<_Nb>& reset(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_reset(__pos); + } + + bitset<_Nb>& flip() { + this->_M_do_flip(); + this->_M_do_sanitize(); + return *this; + } + + bitset<_Nb>& flip(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_flip(__pos); + } + + bitset<_Nb> operator~() const { + return bitset<_Nb>(*this).flip(); + } + + // element access: + //for b[i]; + reference operator[](size_t __pos) { return reference(*this,__pos); } + bool operator[](size_t __pos) const { return _Unchecked_test(__pos); } + + unsigned long to_ulong() const { return this->_M_do_to_ulong(); } + +#if defined(__STL_MEMBER_TEMPLATES) && \ + defined(__STL_EXPLICIT_FUNCTION_TMPL_ARGS) + template + basic_string<_CharT, _Traits, _Alloc> to_string() const { + basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } +#endif /* member templates and explicit function template args */ + + // Helper functions for string operations. +#ifdef __STL_MEMBER_TEMPLATES + template + void _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t, + size_t); + + template + void _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; +#else /* __STL_MEMBER_TEMPLATES */ + void _M_copy_from_string(const basic_string&, size_t, size_t); + void _M_copy_to_string(basic_string&) const; +#endif /* __STL_MEMBER_TEMPLATES */ + + size_t count() const { return this->_M_do_count(); } + + size_t size() const { return _Nb; } + + bool operator==(const bitset<_Nb>& __rhs) const { + return this->_M_is_equal(__rhs); + } + bool operator!=(const bitset<_Nb>& __rhs) const { + return !this->_M_is_equal(__rhs); + } + + bool test(size_t __pos) const { + if (__pos > _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_test(__pos); + } + + bool any() const { return this->_M_is_any(); } + bool none() const { return !this->_M_is_any(); } + + bitset<_Nb> operator<<(size_t __pos) const + { return bitset<_Nb>(*this) <<= __pos; } + bitset<_Nb> operator>>(size_t __pos) const + { return bitset<_Nb>(*this) >>= __pos; } + + // + // EXTENSIONS: bit-find operations. These operations are + // experimental, and are subject to change or removal in future + // versions. + // + + // find the index of the first "on" bit + size_t _Find_first() const + { return this->_M_do_find_first(_Nb); } + + // find the index of the next "on" bit after prev + size_t _Find_next( size_t __prev ) const + { return this->_M_do_find_next(__prev, _Nb); } + +}; + +// +// Definitions of non-inline member functions. +// + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void bitset<_Nb> + ::_M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t __pos, + size_t __n) +{ + reset(); + const size_t __nbits = min(_Nb, min(__n, __s.size() - __pos)); + for (size_t __i = 0; __i < __nbits; ++__i) { + switch(__s[__pos + __nbits - __i - 1]) { + case '0': + break; + case '1': + set(__i); + break; + default: + __STL_THROW(invalid_argument("bitset")); + } + } +} + +template +template +void bitset<_Nb> + ::_M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>& __s) const +{ + __s.assign(_Nb, '0'); + + for (size_t __i = 0; __i < _Nb; ++__i) + if (_Unchecked_test(__i)) + __s[_Nb - 1 - __i] = '1'; +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void bitset<_Nb>::_M_copy_from_string(const basic_string& __s, + size_t __pos, size_t __n) +{ + reset(); + size_t __tmp = _Nb; + const size_t __nbits = min(__tmp, min(__n, __s.size() - __pos)); + for (size_t __i = 0; __i < __nbits; ++__i) { + switch(__s[__pos + __nbits - __i - 1]) { + case '0': + break; + case '1': + set(__i); + break; + default: + __STL_THROW(invalid_argument("bitset")); + } + } +} + +template +void bitset<_Nb>::_M_copy_to_string(basic_string& __s) const +{ + __s.assign(_Nb, '0'); + + for (size_t __i = 0; __i < _Nb; ++__i) + if (_Unchecked_test(__i)) + __s[_Nb - 1 - __i] = '1'; +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +// ------------------------------------------------------------ + +// +// 23.3.5.3 bitset operations: +// + +template +inline bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { + bitset<_Nb> __result(__x); + __result &= __y; + return __result; +} + + +template +inline bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { + bitset<_Nb> __result(__x); + __result |= __y; + return __result; +} + +template +inline bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { + bitset<_Nb> __result(__x); + __result ^= __y; + return __result; +} + +#ifdef __STL_USE_NEW_IOSTREAMS + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) +{ + basic_string<_CharT, _Traits> __tmp; + __tmp.reserve(_Nb); + + // Skip whitespace + typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); + if (__sentry) { + basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); + for (size_t __i = 0; __i < _Nb; ++__i) { + static _Traits::int_type __eof = _Traits::eof(); + + typename _Traits::int_type __c1 = __buf->sbumpc(); + if (_Traits::eq_int_type(__c1, __eof)) { + __is.setstate(ios_base::eofbit); + break; + } + else { + char __c2 = _Traits::to_char_type(__c1); + char __c = __is.narrow(__c2, '*'); + + if (__c == '0' || __c == '1') + __tmp.push_back(__c); + else if (_Traits::eq_int_type(__buf->sputbackc(__c2), __eof)) { + __is.setstate(ios_base::failbit); + break; + } + } + } + + if (__tmp.empty()) + __is.setstate(ios_base::failbit); + else + __x._M_copy_from_string(__tmp, static_cast(0), _Nb); + } + + return __is; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) +{ + basic_string<_CharT, _Traits> __tmp; + __x._M_copy_to_string(__tmp); + return __os << __tmp; +} + +#else /* __STL_USE_NEW_IOSTREAMS */ + +template +istream& operator>>(istream& __is, bitset<_Nb>& __x) { + string __tmp; + __tmp.reserve(_Nb); + + if (__is.flags() & ios::skipws) { + char __c; + do + __is.get(__c); + while (__is && isspace(__c)); + if (__is) + __is.putback(__c); + } + + for (size_t __i = 0; __i < _Nb; ++__i) { + char __c; + __is.get(__c); + + if (!__is) + break; + else if (__c != '0' && __c != '1') { + __is.putback(__c); + break; + } + else + __tmp.push_back(__c); + } + + if (__tmp.empty()) + __is.clear(__is.rdstate() | ios::failbit); + else + __x._M_copy_from_string(__tmp, static_cast(0), _Nb); + + return __is; +} + +template +ostream& operator<<(ostream& __os, const bitset<_Nb>& __x) { + string __tmp; + __x._M_copy_to_string(__tmp); + return __os << __tmp; +} + +#endif /* __STL_USE_NEW_IOSTREAMS */ + +// ------------------------------------------------------------ +// Lookup tables for find and count operations. + +template +unsigned char _Bit_count<__dummy>::_S_bit_count[] = { + 0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */ + 2, /* 5 */ 2, /* 6 */ 3, /* 7 */ 1, /* 8 */ 2, /* 9 */ + 2, /* 10 */ 3, /* 11 */ 2, /* 12 */ 3, /* 13 */ 3, /* 14 */ + 4, /* 15 */ 1, /* 16 */ 2, /* 17 */ 2, /* 18 */ 3, /* 19 */ + 2, /* 20 */ 3, /* 21 */ 3, /* 22 */ 4, /* 23 */ 2, /* 24 */ + 3, /* 25 */ 3, /* 26 */ 4, /* 27 */ 3, /* 28 */ 4, /* 29 */ + 4, /* 30 */ 5, /* 31 */ 1, /* 32 */ 2, /* 33 */ 2, /* 34 */ + 3, /* 35 */ 2, /* 36 */ 3, /* 37 */ 3, /* 38 */ 4, /* 39 */ + 2, /* 40 */ 3, /* 41 */ 3, /* 42 */ 4, /* 43 */ 3, /* 44 */ + 4, /* 45 */ 4, /* 46 */ 5, /* 47 */ 2, /* 48 */ 3, /* 49 */ + 3, /* 50 */ 4, /* 51 */ 3, /* 52 */ 4, /* 53 */ 4, /* 54 */ + 5, /* 55 */ 3, /* 56 */ 4, /* 57 */ 4, /* 58 */ 5, /* 59 */ + 4, /* 60 */ 5, /* 61 */ 5, /* 62 */ 6, /* 63 */ 1, /* 64 */ + 2, /* 65 */ 2, /* 66 */ 3, /* 67 */ 2, /* 68 */ 3, /* 69 */ + 3, /* 70 */ 4, /* 71 */ 2, /* 72 */ 3, /* 73 */ 3, /* 74 */ + 4, /* 75 */ 3, /* 76 */ 4, /* 77 */ 4, /* 78 */ 5, /* 79 */ + 2, /* 80 */ 3, /* 81 */ 3, /* 82 */ 4, /* 83 */ 3, /* 84 */ + 4, /* 85 */ 4, /* 86 */ 5, /* 87 */ 3, /* 88 */ 4, /* 89 */ + 4, /* 90 */ 5, /* 91 */ 4, /* 92 */ 5, /* 93 */ 5, /* 94 */ + 6, /* 95 */ 2, /* 96 */ 3, /* 97 */ 3, /* 98 */ 4, /* 99 */ + 3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */ + 4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */ + 5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */ + 5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */ + 4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */ + 6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */ + 2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */ + 4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */ + 3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */ + 3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */ + 4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */ + 5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */ + 2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */ + 4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */ + 4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */ + 6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */ + 4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */ + 5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */ + 6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */ + 4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */ + 3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */ + 5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */ + 4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */ + 6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */ + 5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */ + 4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */ + 5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */ + 6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */ + 4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */ + 6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */ + 6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */ + 8 /* 255 */ +}; // end _Bit_count + +template +unsigned char _First_one<__dummy>::_S_first_one[] = { + 0, /* 0 */ 0, /* 1 */ 1, /* 2 */ 0, /* 3 */ 2, /* 4 */ + 0, /* 5 */ 1, /* 6 */ 0, /* 7 */ 3, /* 8 */ 0, /* 9 */ + 1, /* 10 */ 0, /* 11 */ 2, /* 12 */ 0, /* 13 */ 1, /* 14 */ + 0, /* 15 */ 4, /* 16 */ 0, /* 17 */ 1, /* 18 */ 0, /* 19 */ + 2, /* 20 */ 0, /* 21 */ 1, /* 22 */ 0, /* 23 */ 3, /* 24 */ + 0, /* 25 */ 1, /* 26 */ 0, /* 27 */ 2, /* 28 */ 0, /* 29 */ + 1, /* 30 */ 0, /* 31 */ 5, /* 32 */ 0, /* 33 */ 1, /* 34 */ + 0, /* 35 */ 2, /* 36 */ 0, /* 37 */ 1, /* 38 */ 0, /* 39 */ + 3, /* 40 */ 0, /* 41 */ 1, /* 42 */ 0, /* 43 */ 2, /* 44 */ + 0, /* 45 */ 1, /* 46 */ 0, /* 47 */ 4, /* 48 */ 0, /* 49 */ + 1, /* 50 */ 0, /* 51 */ 2, /* 52 */ 0, /* 53 */ 1, /* 54 */ + 0, /* 55 */ 3, /* 56 */ 0, /* 57 */ 1, /* 58 */ 0, /* 59 */ + 2, /* 60 */ 0, /* 61 */ 1, /* 62 */ 0, /* 63 */ 6, /* 64 */ + 0, /* 65 */ 1, /* 66 */ 0, /* 67 */ 2, /* 68 */ 0, /* 69 */ + 1, /* 70 */ 0, /* 71 */ 3, /* 72 */ 0, /* 73 */ 1, /* 74 */ + 0, /* 75 */ 2, /* 76 */ 0, /* 77 */ 1, /* 78 */ 0, /* 79 */ + 4, /* 80 */ 0, /* 81 */ 1, /* 82 */ 0, /* 83 */ 2, /* 84 */ + 0, /* 85 */ 1, /* 86 */ 0, /* 87 */ 3, /* 88 */ 0, /* 89 */ + 1, /* 90 */ 0, /* 91 */ 2, /* 92 */ 0, /* 93 */ 1, /* 94 */ + 0, /* 95 */ 5, /* 96 */ 0, /* 97 */ 1, /* 98 */ 0, /* 99 */ + 2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */ + 0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */ + 1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */ + 0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */ + 3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */ + 0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */ + 1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */ + 0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */ + 2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */ + 0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */ + 1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */ + 0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */ + 5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */ + 0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */ + 1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */ + 0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */ + 2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */ + 0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */ + 1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */ + 0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */ + 3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */ + 0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */ + 1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */ + 0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */ + 2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */ + 0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */ + 1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */ + 0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */ + 4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */ + 0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */ + 1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */ + 0, /* 255 */ +}; // end _First_one + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + + +#undef __BITS_PER_WORD +#undef __BITSET_WORDS + +#endif /* __SGI_STL_BITSET */ + + +// Local Variables: +// mode:C++ +// End: + diff --git a/darkice/tags/darkice-0_2/stl/bvector.h b/darkice/tags/darkice-0_2/stl/bvector.h new file mode 100644 index 0000000..af494c5 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/bvector.h @@ -0,0 +1,52 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_BVECTOR_H +#define __SGI_STL_BVECTOR_H + +#include +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +#include +#else +#include +#include +#endif + +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::bit_vector; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: + + diff --git a/darkice/tags/darkice-0_2/stl/char_traits.h b/darkice/tags/darkice-0_2/stl/char_traits.h new file mode 100644 index 0000000..091efc2 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/char_traits.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_CHAR_TRAITS_H +#define __SGI_STL_CHAR_TRAITS_H + +#include +#include + +#if defined(__STL_USE_NEW_IOSTREAMS) && !defined(__SGI_STL_IOSFWD) +#include +#endif /* use new iostreams */ + +__STL_BEGIN_NAMESPACE + +// Class __char_traits_base. + +template class __char_traits_base { +public: + typedef _CharT char_type; + typedef _IntT int_type; +#ifdef __STL_USE_NEW_IOSTREAMS + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; +#endif /* __STL_USE_NEW_IOSTREAMS */ + + static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } + static bool eq(const _CharT& __c1, const _CharT& __c2) + { return __c1 == __c2; } + static bool lt(const _CharT& __c1, const _CharT& __c2) + { return __c1 < __c2; } + + static int compare(const _CharT* __s1, const _CharT* __s2, size_t __n) { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return __s1[__i] < __s2[__i] ? -1 : 1; + return 0; + } + + static size_t length(const _CharT* __s) { + const _CharT __nullchar = _CharT(); + size_t __i; + for (__i = 0; !eq(__s[__i], __nullchar); ++__i) + {} + return __i; + } + + static const _CharT* find(const _CharT* __s, size_t __n, const _CharT& __c) + { + for ( ; __n > 0 ; ++__s, --__n) + if (eq(*__s, __c)) + return __s; + return 0; + } + + static _CharT* move(_CharT* __s1, const _CharT* __s2, size_t __n) { + memmove(__s1, __s2, __n * sizeof(_CharT)); + return __s1; + } + + static _CharT* copy(_CharT* __s1, const _CharT* __s2, size_t __n) { + memcpy(__s1, __s2, __n * sizeof(_CharT)); + return __s1; + } + + static _CharT* assign(_CharT* __s, size_t __n, _CharT __c) { + for (size_t __i = 0; __i < __n; ++__i) + __s[__i] = __c; + return __s; + } + + static int_type not_eof(const int_type& __c) { + return !eq_int_type(__c, eof()) ? __c : 0; + } + + static char_type to_char_type(const int_type& __c) { + return static_cast(__c); + } + + static int_type to_int_type(const char_type& __c) { + return static_cast(__c); + } + + static bool eq_int_type(const int_type& __c1, const int_type& __c2) { + return __c1 == __c2; + } + + static int_type eof() { + return static_cast(-1); + } +}; + +// Generic char_traits class. Note that this class is provided only +// as a base for explicit specialization; it is unlikely to be useful +// as is for any particular user-defined type. In particular, it +// *will not work* for a non-POD type. + +template class char_traits + : public __char_traits_base<_CharT, _CharT> +{}; + +// Specialization for char. + +__STL_TEMPLATE_NULL class char_traits + : public __char_traits_base +{ +public: + static char_type to_char_type(const int_type& __c) { + return static_cast(static_cast(__c)); + } + + static int_type to_int_type(const char_type& __c) { + return static_cast(__c); + } + + static int compare(const char* __s1, const char* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t length(const char* __s) { return strlen(__s); } + + static void assign(char& __c1, const char& __c2) { __c1 = __c2; } + + static char* assign(char* __s, size_t __n, char __c) + { memset(__s, __c, __n); return __s; } +}; + +// Specialization for wchar_t. + +__STL_TEMPLATE_NULL class char_traits + : public __char_traits_base +{}; + + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_CHAR_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: + diff --git a/darkice/tags/darkice-0_2/stl/concept_checks.h b/darkice/tags/darkice-0_2/stl/concept_checks.h new file mode 100644 index 0000000..36df283 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/concept_checks.h @@ -0,0 +1,811 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __CONCEPT_CHECKS_H +#define __CONCEPT_CHECKS_H + +/* + Use these macro like assertions, but they assert properties + on types (usually template arguments). In technical terms they + verify whether a type "models" a "concept". + + This set of requirements and the terminology used here is derived + from the book "Generic Programming and the STL" by Matt Austern + (Addison Wesley). For further information please consult that + book. The requirements also are intended to match the ANSI/ISO C++ + standard. + + This file covers the basic concepts and the iterator concepts. + There are several other files that provide the requirements + for the STL containers: + container_concepts.h + sequence_concepts.h + assoc_container_concepts.h + + Jeremy Siek, 1999 + + TO DO: + - some issues with regards to concept classification and mutability + including AssociativeContianer -> ForwardContainer + and SortedAssociativeContainer -> ReversibleContainer + - HashedAssociativeContainer + - Allocator + - Function Object Concepts + + */ + +#ifndef __STL_USE_CONCEPT_CHECKS + +// Some compilers lack the features that are necessary for concept checks. +// On those compilers we define the concept check macros to do nothing. +#define __STL_REQUIRES(__type_var, __concept) do {} while(0) +#define __STL_CLASS_REQUIRES(__type_var, __concept) \ + static int __##__type_var##_##__concept +#define __STL_CONVERTIBLE(__type_x, __type_y) do {} while(0) +#define __STL_REQUIRES_SAME_TYPE(__type_x, __type_y) do {} while(0) +#define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) \ + static int __##__type_x##__type_y##_require_same_type +#define __STL_GENERATOR_CHECK(__func, __ret) do {} while(0) +#define __STL_CLASS_GENERATOR_CHECK(__func, __ret) \ + static int __##__func##__ret##_generator_check +#define __STL_UNARY_FUNCTION_CHECK(__func, __ret, __arg) do {} while(0) +#define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ + static int __##__func##__ret##__arg##_unary_function_check +#define __STL_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ + do {} while(0) +#define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ + static int __##__func##__ret##__first##__second##_binary_function_check +#define __STL_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ + do {} while(0) +#define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ + static int __##__opname##__ret##__first##__second##_require_binary_op + +#else /* __STL_USE_CONCEPT_CHECKS */ + +// This macro tests whether the template argument "__type_var" +// satisfies the requirements of "__concept". Here is a list of concepts +// that we know how to check: +// _Allocator +// _Assignable +// _DefaultConstructible +// _EqualityComparable +// _LessThanComparable +// _TrivialIterator +// _InputIterator +// _OutputIterator +// _ForwardIterator +// _BidirectionalIterator +// _RandomAccessIterator +// _Mutable_TrivialIterator +// _Mutable_ForwardIterator +// _Mutable_BidirectionalIterator +// _Mutable_RandomAccessIterator + +#define __STL_REQUIRES(__type_var, __concept) \ +do { \ + void (*__x)( __type_var ) = __concept##_concept_specification< __type_var >\ + ::__concept##_requirement_violation; __x = __x; } while (0) + +// Use this to check whether type X is convertible to type Y +#define __STL_CONVERTIBLE(__type_x, __type_y) \ +do { \ + void (*__x)( __type_x , __type_y ) = _STL_CONVERT_ERROR< __type_x , \ + __type_y >::__type_X_is_not_convertible_to_type_Y; \ + __x = __x; } while (0) + +// Use this to test whether two template arguments are the same type +#define __STL_REQUIRES_SAME_TYPE(__type_x, __type_y) \ +do { \ + void (*__x)( __type_x , __type_y ) = _STL_SAME_TYPE_ERROR< __type_x, \ + __type_y >::__type_X_not_same_as_type_Y; \ + __x = __x; } while (0) + + +// function object checks +#define __STL_GENERATOR_CHECK(__func, __ret) \ +do { \ + __ret (*__x)( __func&) = \ + _STL_GENERATOR_ERROR< \ + __func, __ret>::__generator_requirement_violation; \ + __x = __x; } while (0) + + +#define __STL_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ +do { \ + __ret (*__x)( __func&, const __arg& ) = \ + _STL_UNARY_FUNCTION_ERROR< \ + __func, __ret, __arg>::__unary_function_requirement_violation; \ + __x = __x; } while (0) + + +#define __STL_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ +do { \ + __ret (*__x)( __func&, const __first&, const __second& ) = \ + _STL_BINARY_FUNCTION_ERROR< \ + __func, __ret, __first, __second>::__binary_function_requirement_violation; \ + __x = __x; } while (0) + + +#define __STL_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ + do { \ + __ret (*__x)( __first&, __second& ) = _STL_BINARY##__opname##_ERROR< \ + __ret, __first, __second>::__binary_operator_requirement_violation; \ + __ret (*__y)( const __first&, const __second& ) = \ + _STL_BINARY##__opname##_ERROR< __ret, __first, __second>:: \ + __const_binary_operator_requirement_violation; \ + __y = __y; __x = __x; } while (0) + + +#ifdef __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE + +#define __STL_CLASS_REQUIRES(__type_var, __concept) +#define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) +#define __STL_CLASS_GENERATOR_CHECK(__func, __ret) +#define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) +#define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) +#define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) + +#else + +// Use this macro inside of template classes, where you would +// like to place requirements on the template arguments to the class +// Warning: do not pass pointers and such (e.g. T*) in as the __type_var, +// since the type_var is used to construct identifiers. Instead typedef +// the pointer type, then use the typedef name for the __type_var. +#define __STL_CLASS_REQUIRES(__type_var, __concept) \ + typedef void (* __func##__type_var##__concept)( __type_var ); \ + template <__func##__type_var##__concept _Tp1> \ + struct __dummy_struct_##__type_var##__concept { }; \ + static __dummy_struct_##__type_var##__concept< \ + __concept##_concept_specification< \ + __type_var>::__concept##_requirement_violation> \ + __dummy_ptr_##__type_var##__concept + + +#define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) \ + typedef void (* __func_##__type_x##__type_y##same_type)( __type_x, \ + __type_y ); \ + template < __func_##__type_x##__type_y##same_type _Tp1> \ + struct __dummy_struct_##__type_x##__type_y##_same_type { }; \ + static __dummy_struct_##__type_x##__type_y##_same_type< \ + _STL_SAME_TYPE_ERROR<__type_x, __type_y>::__type_X_not_same_as_type_Y> \ + __dummy_ptr_##__type_x##__type_y##_same_type + + +#define __STL_CLASS_GENERATOR_CHECK(__func, __ret) \ + typedef __ret (* __f_##__func##__ret##_generator)( __func& ); \ + template <__f_##__func##__ret##_generator _Tp1> \ + struct __dummy_struct_##__func##__ret##_generator { }; \ + static __dummy_struct_##__func##__ret##_generator< \ + _STL_GENERATOR_ERROR< \ + __func, __ret>::__generator_requirement_violation> \ + __dummy_ptr_##__func##__ret##_generator + + +#define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ + typedef __ret (* __f_##__func##__ret##__arg##_unary_check)( __func&, \ + const __arg& ); \ + template <__f_##__func##__ret##__arg##_unary_check _Tp1> \ + struct __dummy_struct_##__func##__ret##__arg##_unary_check { }; \ + static __dummy_struct_##__func##__ret##__arg##_unary_check< \ + _STL_UNARY_FUNCTION_ERROR< \ + __func, __ret, __arg>::__unary_function_requirement_violation> \ + __dummy_ptr_##__func##__ret##__arg##_unary_check + + +#define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ + typedef __ret (* __f_##__func##__ret##__first##__second##_binary_check)( __func&, const __first&,\ + const __second& ); \ + template <__f_##__func##__ret##__first##__second##_binary_check _Tp1> \ + struct __dummy_struct_##__func##__ret##__first##__second##_binary_check { }; \ + static __dummy_struct_##__func##__ret##__first##__second##_binary_check< \ + _STL_BINARY_FUNCTION_ERROR<__func, __ret, __first, __second>:: \ + __binary_function_requirement_violation> \ + __dummy_ptr_##__func##__ret##__first##__second##_binary_check + + +#define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ + typedef __ret (* __f_##__func##__ret##__first##__second##_binary_op)(const __first&, \ + const __second& ); \ + template <__f_##__func##__ret##__first##__second##_binary_op _Tp1> \ + struct __dummy_struct_##__func##__ret##__first##__second##_binary_op { }; \ + static __dummy_struct_##__func##__ret##__first##__second##_binary_op< \ + _STL_BINARY##__opname##_ERROR<__ret, __first, __second>:: \ + __binary_operator_requirement_violation> \ + __dummy_ptr_##__func##__ret##__first##__second##_binary_op + +#endif + +/* helper class for finding non-const version of a type. Need to have + something to assign to etc. when testing constant iterators. */ + +template +struct _Mutable_trait { + typedef _Tp _Type; +}; +template +struct _Mutable_trait { + typedef _Tp _Type; +}; + + +/* helper function for avoiding compiler warnings about unused variables */ +template +void __sink_unused_warning(_Type) { } + +template +struct _STL_CONVERT_ERROR { + static void + __type_X_is_not_convertible_to_type_Y(_TypeX __x, _TypeY) { + _TypeY __y = __x; + __sink_unused_warning(__y); + } +}; + + +template struct __check_equal { }; + +template +struct _STL_SAME_TYPE_ERROR { + static void + __type_X_not_same_as_type_Y(_TypeX , _TypeY ) { + __check_equal<_TypeX> t1 = __check_equal<_TypeY>(); + } +}; + + +// Some Functon Object Checks + +template +struct _STL_GENERATOR_ERROR { + static _Ret __generator_requirement_violation(_Func& __f) { + return __f(); + } +}; + +template +struct _STL_GENERATOR_ERROR<_Func, void> { + static void __generator_requirement_violation(_Func& __f) { + __f(); + } +}; + + +template +struct _STL_UNARY_FUNCTION_ERROR { + static _Ret + __unary_function_requirement_violation(_Func& __f, + const _Arg& __arg) { + return __f(__arg); + } +}; + +template +struct _STL_UNARY_FUNCTION_ERROR<_Func, void, _Arg> { + static void + __unary_function_requirement_violation(_Func& __f, + const _Arg& __arg) { + __f(__arg); + } +}; + +template +struct _STL_BINARY_FUNCTION_ERROR { + static _Ret + __binary_function_requirement_violation(_Func& __f, + const _First& __first, + const _Second& __second) { + return __f(__first, __second); + } +}; + +template +struct _STL_BINARY_FUNCTION_ERROR<_Func, void, _First, _Second> { + static void + __binary_function_requirement_violation(_Func& __f, + const _First& __first, + const _Second& __second) { + __f(__first, __second); + } +}; + + +#define __STL_DEFINE_BINARY_OP_CHECK(_OP, _NAME) \ +template \ +struct _STL_BINARY##_NAME##_ERROR { \ + static _Ret \ + __const_binary_operator_requirement_violation(const _First& __first, \ + const _Second& __second) { \ + return __first _OP __second; \ + } \ + static _Ret \ + __binary_operator_requirement_violation(_First& __first, \ + _Second& __second) { \ + return __first _OP __second; \ + } \ +} + +__STL_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL); +__STL_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL); +__STL_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN); +__STL_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL); +__STL_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN); +__STL_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL); +__STL_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS); +__STL_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES); +__STL_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE); +__STL_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT); +__STL_DEFINE_BINARY_OP_CHECK(%, _OP_MOD); +// ... + +// TODO, add unary operators (prefix and postfix) + +/* + The presence of this class is just to trick EDG into displaying + these error messages before any other errors. Without the + classes, the errors in the functions get reported after + other class errors deep inside the library. The name + choice just makes for an eye catching error message :) + */ +struct _STL_ERROR { + + template + static _Type + __default_constructor_requirement_violation(_Type) { + return _Type(); + } + template + static _Type + __assignment_operator_requirement_violation(_Type __a) { + __a = __a; + return __a; + } + template + static _Type + __copy_constructor_requirement_violation(_Type __a) { + _Type __c(__a); + return __c; + } + template + static _Type + __const_parameter_required_for_copy_constructor(_Type /* __a */, + const _Type& __b) { + _Type __c(__b); + return __c; + } + template + static _Type + __const_parameter_required_for_assignment_operator(_Type __a, + const _Type& __b) { + __a = __b; + return __a; + } + template + static _Type + __less_than_comparable_requirement_violation(_Type __a, _Type __b) { + if (__a < __b || __a > __b || __a <= __b || __a >= __b) return __a; + return __b; + } + template + static _Type + __equality_comparable_requirement_violation(_Type __a, _Type __b) { + if (__a == __b || __a != __b) return __a; + return __b; + } + template + static void + __dereference_operator_requirement_violation(_Iterator __i) { + __sink_unused_warning(*__i); + } + template + static void + __dereference_operator_and_assignment_requirement_violation(_Iterator __i) { + *__i = *__i; + } + template + static void + __preincrement_operator_requirement_violation(_Iterator __i) { + ++__i; + } + template + static void + __postincrement_operator_requirement_violation(_Iterator __i) { + __i++; + } + template + static void + __predecrement_operator_requirement_violation(_Iterator __i) { + --__i; + } + template + static void + __postdecrement_operator_requirement_violation(_Iterator __i) { + __i--; + } + template + static void + __postincrement_operator_and_assignment_requirement_violation(_Iterator __i, + _Type __t) { + *__i++ = __t; + } + template + static _Iterator + __iterator_addition_assignment_requirement_violation(_Iterator __i, + _Distance __n) { + __i += __n; + return __i; + } + template + static _Iterator + __iterator_addition_requirement_violation(_Iterator __i, _Distance __n) { + __i = __i + __n; + __i = __n + __i; + return __i; + } + template + static _Iterator + __iterator_subtraction_assignment_requirement_violation(_Iterator __i, + _Distance __n) { + __i -= __n; + return __i; + } + template + static _Iterator + __iterator_subtraction_requirement_violation(_Iterator __i, _Distance __n) { + __i = __i - __n; + return __i; + } + template + static _Distance + __difference_operator_requirement_violation(_Iterator __i, _Iterator __j, + _Distance __n) { + __n = __i - __j; + return __n; + } + template + static _Type + __element_access_operator_requirement_violation(_Exp __x, _Type*, + _Distance __n) { + return __x[__n]; + } + template + static void + __element_assignment_operator_requirement_violation(_Exp __x, + _Type* __t, + _Distance __n) { + __x[__n] = *__t; + } + +}; /* _STL_ERROR */ + +/* Associated Type Requirements */ + +__STL_BEGIN_NAMESPACE +template struct iterator_traits; +__STL_END_NAMESPACE + +template +struct __value_type_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::value_type value_type; +}; + +template +struct __difference_type_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::difference_type + difference_type; +}; + +template +struct __reference_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::reference reference; +}; + +template +struct __pointer_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::pointer pointer; +}; + +template +struct __iterator_category_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::iterator_category + iterator_category; +}; + +/* Assignable Requirements */ + + +template +struct _Assignable_concept_specification { + static void _Assignable_requirement_violation(_Type __a) { + _STL_ERROR::__assignment_operator_requirement_violation(__a); + _STL_ERROR::__copy_constructor_requirement_violation(__a); + _STL_ERROR::__const_parameter_required_for_copy_constructor(__a,__a); + _STL_ERROR::__const_parameter_required_for_assignment_operator(__a,__a); + } +}; + +/* DefaultConstructible Requirements */ + + +template +struct _DefaultConstructible_concept_specification { + static void _DefaultConstructible_requirement_violation(_Type __a) { + _STL_ERROR::__default_constructor_requirement_violation(__a); + } +}; + +/* EqualityComparable Requirements */ + +template +struct _EqualityComparable_concept_specification { + static void _EqualityComparable_requirement_violation(_Type __a) { + _STL_ERROR::__equality_comparable_requirement_violation(__a, __a); + } +}; + +/* LessThanComparable Requirements */ +template +struct _LessThanComparable_concept_specification { + static void _LessThanComparable_requirement_violation(_Type __a) { + _STL_ERROR::__less_than_comparable_requirement_violation(__a, __a); + } +}; + +/* TrivialIterator Requirements */ + +template +struct _TrivialIterator_concept_specification { +static void +_TrivialIterator_requirement_violation(_TrivialIterator __i) { + typedef typename + __value_type_type_definition_requirement_violation<_TrivialIterator>:: + value_type __T; + // Refinement of Assignable + _Assignable_concept_specification<_TrivialIterator>:: + _Assignable_requirement_violation(__i); + // Refinement of DefaultConstructible + _DefaultConstructible_concept_specification<_TrivialIterator>:: + _DefaultConstructible_requirement_violation(__i); + // Refinement of EqualityComparable + _EqualityComparable_concept_specification<_TrivialIterator>:: + _EqualityComparable_requirement_violation(__i); + // Valid Expressions + _STL_ERROR::__dereference_operator_requirement_violation(__i); +} +}; + +template +struct _Mutable_TrivialIterator_concept_specification { +static void +_Mutable_TrivialIterator_requirement_violation(_TrivialIterator __i) { + _TrivialIterator_concept_specification<_TrivialIterator>:: + _TrivialIterator_requirement_violation(__i); + // Valid Expressions + _STL_ERROR::__dereference_operator_and_assignment_requirement_violation(__i); +} +}; + +/* InputIterator Requirements */ + +template +struct _InputIterator_concept_specification { +static void +_InputIterator_requirement_violation(_InputIterator __i) { + // Refinement of TrivialIterator + _TrivialIterator_concept_specification<_InputIterator>:: + _TrivialIterator_requirement_violation(__i); + // Associated Types + __difference_type_type_definition_requirement_violation<_InputIterator>(); + __reference_type_definition_requirement_violation<_InputIterator>(); + __pointer_type_definition_requirement_violation<_InputIterator>(); + __iterator_category_type_definition_requirement_violation<_InputIterator>(); + // Valid Expressions + _STL_ERROR::__preincrement_operator_requirement_violation(__i); + _STL_ERROR::__postincrement_operator_requirement_violation(__i); +} +}; + +/* OutputIterator Requirements */ + +template +struct _OutputIterator_concept_specification { +static void +_OutputIterator_requirement_violation(_OutputIterator __i) { + // Refinement of Assignable + _Assignable_concept_specification<_OutputIterator>:: + _Assignable_requirement_violation(__i); + // Associated Types + __iterator_category_type_definition_requirement_violation<_OutputIterator>(); + // Valid Expressions + _STL_ERROR::__dereference_operator_requirement_violation(__i); + _STL_ERROR::__preincrement_operator_requirement_violation(__i); + _STL_ERROR::__postincrement_operator_requirement_violation(__i); + _STL_ERROR:: + __postincrement_operator_and_assignment_requirement_violation(__i, *__i); +} +}; + +/* ForwardIterator Requirements */ + +template +struct _ForwardIterator_concept_specification { +static void +_ForwardIterator_requirement_violation(_ForwardIterator __i) { + // Refinement of InputIterator + _InputIterator_concept_specification<_ForwardIterator>:: + _InputIterator_requirement_violation(__i); +} +}; + +template +struct _Mutable_ForwardIterator_concept_specification { +static void +_Mutable_ForwardIterator_requirement_violation(_ForwardIterator __i) { + _ForwardIterator_concept_specification<_ForwardIterator>:: + _ForwardIterator_requirement_violation(__i); + // Refinement of OutputIterator + _OutputIterator_concept_specification<_ForwardIterator>:: + _OutputIterator_requirement_violation(__i); +} +}; + +/* BidirectionalIterator Requirements */ + +template +struct _BidirectionalIterator_concept_specification { +static void +_BidirectionalIterator_requirement_violation(_BidirectionalIterator __i) { + // Refinement of ForwardIterator + _ForwardIterator_concept_specification<_BidirectionalIterator>:: + _ForwardIterator_requirement_violation(__i); + // Valid Expressions + _STL_ERROR::__predecrement_operator_requirement_violation(__i); + _STL_ERROR::__postdecrement_operator_requirement_violation(__i); +} +}; + +template +struct _Mutable_BidirectionalIterator_concept_specification { +static void +_Mutable_BidirectionalIterator_requirement_violation( + _BidirectionalIterator __i) +{ + _BidirectionalIterator_concept_specification<_BidirectionalIterator>:: + _BidirectionalIterator_requirement_violation(__i); + // Refinement of mutable_ForwardIterator + _Mutable_ForwardIterator_concept_specification<_BidirectionalIterator>:: + _Mutable_ForwardIterator_requirement_violation(__i); + typedef typename + __value_type_type_definition_requirement_violation< + _BidirectionalIterator>::value_type __T; + typename _Mutable_trait<__T>::_Type* __tmp_ptr = 0; + // Valid Expressions + _STL_ERROR:: + __postincrement_operator_and_assignment_requirement_violation(__i, + *__tmp_ptr); +} +}; + +/* RandomAccessIterator Requirements */ + +template +struct _RandomAccessIterator_concept_specification { +static void +_RandomAccessIterator_requirement_violation(_RandAccIter __i) { + // Refinement of BidirectionalIterator + _BidirectionalIterator_concept_specification<_RandAccIter>:: + _BidirectionalIterator_requirement_violation(__i); + // Refinement of LessThanComparable + _LessThanComparable_concept_specification<_RandAccIter>:: + _LessThanComparable_requirement_violation(__i); + typedef typename + __value_type_type_definition_requirement_violation<_RandAccIter> + ::value_type + value_type; + typedef typename + __difference_type_type_definition_requirement_violation<_RandAccIter> + ::difference_type + _Dist; + typedef typename _Mutable_trait<_Dist>::_Type _MutDist; + + // Valid Expressions + _STL_ERROR::__iterator_addition_assignment_requirement_violation(__i, + _MutDist()); + _STL_ERROR::__iterator_addition_requirement_violation(__i, + _MutDist()); + _STL_ERROR:: + __iterator_subtraction_assignment_requirement_violation(__i, + _MutDist()); + _STL_ERROR::__iterator_subtraction_requirement_violation(__i, + _MutDist()); + _STL_ERROR::__difference_operator_requirement_violation(__i, __i, + _MutDist()); + typename _Mutable_trait::_Type* __dummy_ptr = 0; + _STL_ERROR::__element_access_operator_requirement_violation(__i, + __dummy_ptr, + _MutDist()); +} +}; + +template +struct _Mutable_RandomAccessIterator_concept_specification { +static void +_Mutable_RandomAccessIterator_requirement_violation(_RandAccIter __i) +{ + _RandomAccessIterator_concept_specification<_RandAccIter>:: + _RandomAccessIterator_requirement_violation(__i); + // Refinement of mutable_BidirectionalIterator + _Mutable_BidirectionalIterator_concept_specification<_RandAccIter>:: + _Mutable_BidirectionalIterator_requirement_violation(__i); + typedef typename + __value_type_type_definition_requirement_violation<_RandAccIter> + ::value_type + value_type; + typedef typename + __difference_type_type_definition_requirement_violation<_RandAccIter> + ::difference_type + _Dist; + + typename _Mutable_trait::_Type* __tmp_ptr = 0; + // Valid Expressions + _STL_ERROR::__element_assignment_operator_requirement_violation(__i, + __tmp_ptr, _Dist()); +} +}; + +#define __STL_TYPEDEF_REQUIREMENT(__REQUIREMENT) \ +template \ +struct __##__REQUIREMENT##__typedef_requirement_violation { \ + typedef typename Type::__REQUIREMENT __REQUIREMENT; \ +} + +__STL_TYPEDEF_REQUIREMENT(value_type); +__STL_TYPEDEF_REQUIREMENT(difference_type); +__STL_TYPEDEF_REQUIREMENT(size_type); +__STL_TYPEDEF_REQUIREMENT(reference); +__STL_TYPEDEF_REQUIREMENT(const_reference); +__STL_TYPEDEF_REQUIREMENT(pointer); +__STL_TYPEDEF_REQUIREMENT(const_pointer); + + +template +struct _Allocator_concept_specification { +static void +_Allocator_requirement_violation(_Alloc __a) { + // Refinement of DefaultConstructible + _DefaultConstructible_concept_specification<_Alloc>:: + _DefaultConstructible_requirement_violation(__a); + // Refinement of EqualityComparable + _EqualityComparable_concept_specification<_Alloc>:: + _EqualityComparable_requirement_violation(__a); + // Associated Types + __value_type__typedef_requirement_violation<_Alloc>(); + __difference_type__typedef_requirement_violation<_Alloc>(); + __size_type__typedef_requirement_violation<_Alloc>(); + __reference__typedef_requirement_violation<_Alloc>(); + __const_reference__typedef_requirement_violation<_Alloc>(); + __pointer__typedef_requirement_violation<_Alloc>(); + __const_pointer__typedef_requirement_violation<_Alloc>(); + typedef typename _Alloc::value_type _Tp; + //__STL_REQUIRES_SAME_TYPE(typename _Alloc::__STL_TEMPLATE rebind<_Tp>::other, + // _Alloc); +} +}; + +#endif /* __STL_USE_CONCEPT_CHECKS */ + +#endif /* __CONCEPT_CHECKS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/container_concepts.h b/darkice/tags/darkice-0_2/stl/container_concepts.h new file mode 100644 index 0000000..10db8de --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/container_concepts.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __STL_CONTAINER_CONCEPTS_H +#define __STL_CONTAINER_CONCEPTS_H + + +#include + +#ifdef __STL_USE_CONCEPT_CHECKS + + +// This file covers the following concepts: +// _Container +// _ForwardContainer +// _ReversibleContainer +// _const_ReversibleContainer +// _RandomAccessContainer +// + +struct _ERROR_IN_STL_CONTAINER { + + /* Container expresssions */ + + template + static void + __begin_iterator_accessor_requirement_violation(_Container __c) { + __c.begin(); + } + template + static void + __const_begin_iterator_accessor_requirement_violation(const _Container& __c) { + __c.begin(); + } + template + static void + __end_iterator_accessor_requirement_violation(_Container __c) { + __c.end(); + } + template + static void + __const_end_iterator_accessor_requirement_violation(const _Container& __c) { + __c.end(); + } + + template + static void + __rbegin_iterator_accessor_requirement_violation(_Container __c) { + __c.rbegin(); + } + template + static void + __const_rbegin_iterator_accessor_requirement_violation(const _Container& __c) { + __c.rbegin(); + } + template + static void + __rend_iterator_accessor_requirement_violation(_Container __c) { + __c.rend(); + } + template + static void + __const_rend_iterator_accessor_requirement_violation(const _Container& __c) { + __c.rend(); + } + template + static void + __size_function_must_be_const(const _Container& __c) { + __c.size(); + } + template + static void + __size_function_requirement_violation(_Container& __c) { + __c.size(); + __size_function_must_be_const(__c); + } + template + static void + __max_size_function_must_be_const(const _Container& __c) { + __c.max_size(); + } + template + static void + __max_size_function_requirement_violation(_Container& __c) { + __c.max_size(); + __max_size_function_must_be_const(__c); + } + template + static void + __empty_function_must_be_const(const _Container& __c) { + __c.empty(); + } + template + static void + __empty_function_requirement_violation(_Container& __c) { + __c.empty(); + __empty_function_must_be_const(__c); + } + template + static void + __swap_function_requirement_violation(_Container& __c) { + __c.swap(__c); + } + +}; + + +__STL_TYPEDEF_REQUIREMENT(iterator); +__STL_TYPEDEF_REQUIREMENT(const_iterator); + +/* Containers */ + +template +struct _Container_concept_specification { +static void +_Container_requirement_violation(_Container __c) { + // Refinement of Assignable + _Assignable_concept_specification<_Container>::_Assignable_requirement_violation(__c); + // Associated Types + __value_type__typedef_requirement_violation<_Container>(); + __difference_type__typedef_requirement_violation<_Container>(); + __size_type__typedef_requirement_violation<_Container>(); + __reference__typedef_requirement_violation<_Container>(); + __const_reference__typedef_requirement_violation<_Container>(); + __pointer__typedef_requirement_violation<_Container>(); + __const_pointer__typedef_requirement_violation<_Container>(); + __iterator__typedef_requirement_violation<_Container>(); + __const_iterator__typedef_requirement_violation<_Container>(); + // Valid Expressions + _ERROR_IN_STL_CONTAINER::__const_begin_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__const_end_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__begin_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__end_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__size_function_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__max_size_function_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__empty_function_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__swap_function_requirement_violation(__c); + // Requirements on Iterators + typedef typename _Container::iterator iter; + typedef typename _Container::const_iterator const_iter; + _InputIterator_concept_specification::_InputIterator_requirement_violation(const_iter()); + _InputIterator_concept_specification::_InputIterator_requirement_violation(iter()); +} +}; + +template +struct _ForwardContainer_concept_specification { +static void +_ForwardContainer_requirement_violation(_ForwardContainer __c) { + // Refinement of Container + _Container_concept_specification<_ForwardContainer>::_Container_requirement_violation(__c); + // Requirements on Iterators + typedef typename _ForwardContainer::iterator iter; + typedef typename _ForwardContainer::const_iterator const_iter; + _ForwardIterator_concept_specification::_ForwardIterator_requirement_violation(const_iter()); + _Mutable_ForwardIterator_concept_specification::_Mutable_ForwardIterator_requirement_violation(iter()); +} +}; + + +__STL_TYPEDEF_REQUIREMENT(reverse_iterator); +__STL_TYPEDEF_REQUIREMENT(const_reverse_iterator); + +template +struct _ReversibleContainer_concept_specification { +static void +_ReversibleContainer_requirement_violation(_ReversibleContainer __c) { + // Refinement of ForwardContainer + _ForwardContainer_concept_specification<_ReversibleContainer>::_ForwardContainer_requirement_violation(__c); + // Associated types + __reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); + __const_reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); + // Valid Expressions + _ERROR_IN_STL_CONTAINER::__const_rbegin_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__const_rend_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__rbegin_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__rend_iterator_accessor_requirement_violation(__c); + // Requirements on Iterators + typedef typename _ReversibleContainer::iterator iter; + typedef typename _ReversibleContainer::const_iterator const_iter; + _BidirectionalIterator_concept_specification::_BidirectionalIterator_requirement_violation(const_iter()); + _Mutable_BidirectionalIterator_concept_specification::_Mutable_BidirectionalIterator_requirement_violation(iter()); +} +}; + +template +struct _const_ReversibleContainer_concept_specification { +static void +_const_ReversibleContainer_requirement_violation(_ReversibleContainer __c) { + // Refinement of Container (JGS, not ForwardContainer) + _Container_concept_specification<_ReversibleContainer>::_Container_requirement_violation(__c); + // Associated types + __reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); + __const_reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); + // Valid Expressions + _ERROR_IN_STL_CONTAINER::__const_rbegin_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__const_rend_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__rbegin_iterator_accessor_requirement_violation(__c); + _ERROR_IN_STL_CONTAINER::__rend_iterator_accessor_requirement_violation(__c); + // Requirements on Iterators + typedef typename _ReversibleContainer::iterator iter; + typedef typename _ReversibleContainer::const_iterator const_iter; + + // This line won't compile on gcc 2.91 due to a compiler bug. +#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 91) + __BidirectionalIterator_concept_specification::_BidirectionalIterator_requirement_violation(const_iter()); +#endif +} +}; + + +template +struct _RandomAccessContainer_concept_specification { +static void +_RandomAccessContainer_requirement_violation(_RandomAccessContainer __c) { + // Refinement of ReversibleContainer + _ReversibleContainer_concept_specification<_RandomAccessContainer>::_ReversibleContainer_requirement_violation(__c); + // Valid Expressions + typedef typename _RandomAccessContainer::value_type __T; + typedef typename _RandomAccessContainer::difference_type _Dist; + typedef typename _Mutable_trait<__T>::_Type Type; + typedef Type* _TypePtr; + typedef typename _Mutable_trait<_Dist>::_Type Dist; + _STL_ERROR::__element_access_operator_requirement_violation(__c, + _TypePtr(), + Dist()); + // Requirements on Iterators + typedef typename _RandomAccessContainer::iterator iter; + typedef typename _RandomAccessContainer::const_iterator const_iter; + _RandomAccessIterator_concept_specification::_RandomAccessIterator_requirement_violation(const_iter()); + _Mutable_RandomAccessIterator_concept_specification::_Mutable_RandomAccessIterator_requirement_violation(iter()); +} +}; + +#endif /* if __STL_USE_CONCEPT_CHECKS */ + +#endif /* __STL_CONTAINER_CONCEPTS_H */ diff --git a/darkice/tags/darkice-0_2/stl/defalloc.h b/darkice/tags/darkice-0_2/stl/defalloc.h new file mode 100644 index 0000000..0bfcc2c --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/defalloc.h @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +// Inclusion of this file is DEPRECATED. This is the original HP +// default allocator. It is provided only for backward compatibility. +// This file WILL BE REMOVED in a future release. +// +// DO NOT USE THIS FILE unless you have an old container implementation +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header . + +#ifndef DEFALLOC_H +#define DEFALLOC_H + +#include +#include +#include +#include +#include +#include + + +template +inline T* allocate(ptrdiff_t size, T*) { + set_new_handler(0); + T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); + if (tmp == 0) { + cerr << "out of memory" << endl; + exit(1); + } + return tmp; +} + + +template +inline void deallocate(T* buffer) { + ::operator delete(buffer); +} + +template +class allocator { +public: + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + pointer allocate(size_type n) { + return ::allocate((difference_type)n, (pointer)0); + } + void deallocate(pointer p) { ::deallocate(p); } + pointer address(reference x) { return (pointer)&x; } + const_pointer const_address(const_reference x) { + return (const_pointer)&x; + } + size_type init_page_size() { + return max(size_type(1), size_type(4096/sizeof(T))); + } + size_type max_size() const { + return max(size_type(1), size_type(UINT_MAX/sizeof(T))); + } +}; + +class allocator { +public: + typedef void* pointer; +}; + + + +#endif diff --git a/darkice/tags/darkice-0_2/stl/deque b/darkice/tags/darkice-0_2/stl/deque new file mode 100644 index 0000000..b823fa4 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/deque @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_DEQUE +#define __SGI_STL_DEQUE + +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_DEQUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/deque.h b/darkice/tags/darkice-0_2/stl/deque.h new file mode 100644 index 0000000..2ffeba2 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/deque.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_DEQUE_H +#define __SGI_STL_DEQUE_H + +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::deque; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/function.h b/darkice/tags/darkice-0_2/stl/function.h new file mode 100644 index 0000000..6474dd9 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/function.h @@ -0,0 +1,118 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_FUNCTION_H +#define __SGI_STL_FUNCTION_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#include +#ifndef __SGI_STL_INTERNAL_FUNCTION_H +#include +#endif + +#ifdef __STL_USE_NAMESPACE_FOR_RELOPS + +// Names from stl_relops.h +using __STD_RELOPS::operator!=; +using __STD_RELOPS::operator>; +using __STD_RELOPS::operator<=; +using __STD_RELOPS::operator>=; + +#endif /* __STL_USE_NAMESPACE_FOR_RELOPS */ + +#ifdef __STL_USE_NAMESPACES + +// Names from stl_function.h +using __STD::unary_function; +using __STD::binary_function; +using __STD::plus; +using __STD::minus; +using __STD::multiplies; +using __STD::divides; +using __STD::identity_element; +using __STD::modulus; +using __STD::negate; +using __STD::equal_to; +using __STD::not_equal_to; +using __STD::greater; +using __STD::less; +using __STD::greater_equal; +using __STD::less_equal; +using __STD::logical_and; +using __STD::logical_or; +using __STD::logical_not; +using __STD::unary_negate; +using __STD::binary_negate; +using __STD::not1; +using __STD::not2; +using __STD::binder1st; +using __STD::binder2nd; +using __STD::bind1st; +using __STD::bind2nd; +using __STD::unary_compose; +using __STD::binary_compose; +using __STD::compose1; +using __STD::compose2; +using __STD::pointer_to_unary_function; +using __STD::pointer_to_binary_function; +using __STD::ptr_fun; +using __STD::identity; +using __STD::select1st; +using __STD::select2nd; +using __STD::project1st; +using __STD::project2nd; +using __STD::constant_void_fun; +using __STD::constant_unary_fun; +using __STD::constant_binary_fun; +using __STD::constant0; +using __STD::constant1; +using __STD::constant2; +using __STD::subtractive_rng; +using __STD::mem_fun_t; +using __STD::const_mem_fun_t; +using __STD::mem_fun_ref_t; +using __STD::const_mem_fun_ref_t; +using __STD::mem_fun1_t; +using __STD::const_mem_fun1_t; +using __STD::mem_fun1_ref_t; +using __STD::const_mem_fun1_ref_t; +using __STD::mem_fun; +using __STD::mem_fun_ref; +using __STD::mem_fun1; +using __STD::mem_fun1_ref; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/functional b/darkice/tags/darkice-0_2/stl/functional new file mode 100644 index 0000000..d046dbb --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/functional @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_FUNCTIONAL +#define __SGI_STL_FUNCTIONAL + +#include +#include +#include + +#endif /* __SGI_STL_FUNCTIONAL */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/hash_map b/darkice/tags/darkice-0_2/stl/hash_map new file mode 100644 index 0000000..f7421e0 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/hash_map @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_HASH_MAP +#define __SGI_STL_HASH_MAP + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include + +#endif /* __SGI_STL_HASH_MAP */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/hash_map.h b/darkice/tags/darkice-0_2/stl/hash_map.h new file mode 100644 index 0000000..f347162 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/hash_map.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_HASH_MAP_H +#define __SGI_STL_HASH_MAP_H + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +using __STD::hash_map; +using __STD::hash_multimap; +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* __SGI_STL_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/hash_set b/darkice/tags/darkice-0_2/stl/hash_set new file mode 100644 index 0000000..2244f47 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/hash_set @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_HASH_SET +#define __SGI_STL_HASH_SET + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include + +#endif /* __SGI_STL_HASH_SET */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/hash_set.h b/darkice/tags/darkice-0_2/stl/hash_set.h new file mode 100644 index 0000000..d3e93c0 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/hash_set.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_HASH_SET_H +#define __SGI_STL_HASH_SET_H + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +using __STD::hash_set; +using __STD::hash_multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_HASH_SET_H */ diff --git a/darkice/tags/darkice-0_2/stl/hashtable.h b/darkice/tags/darkice-0_2/stl/hashtable.h new file mode 100644 index 0000000..15dbfc9 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/hashtable.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_HASHTABLE_H +#define __SGI_STL_HASHTABLE_H + +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/heap.h b/darkice/tags/darkice-0_2/stl/heap.h new file mode 100644 index 0000000..2ec93c0 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/heap.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_HEAP_H +#define __SGI_STL_HEAP_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::push_heap; +using __STD::pop_heap; +using __STD::make_heap; +using __STD::sort_heap; + +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* __SGI_STL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/iterator b/darkice/tags/darkice-0_2/stl/iterator new file mode 100644 index 0000000..fe2b8e8 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/iterator @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ITERATOR +#define __SGI_STL_ITERATOR + +#include +#include +#include + +#ifdef __STL_USE_NEW_IOSTREAMS +#include +#else /* __STL_USE_NEW_IOSTREAMS */ +#include +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#include +#include + +#endif /* __SGI_STL_ITERATOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/iterator.h b/darkice/tags/darkice-0_2/stl/iterator.h new file mode 100644 index 0000000..197278b --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/iterator.h @@ -0,0 +1,113 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ITERATOR_H +#define __SGI_STL_ITERATOR_H + +#ifndef __SGI_STL_FUNCTION_H +#include +#endif +#include + +#ifdef __STL_USE_NEW_IOSTREAMS +#include +#else /* __STL_USE_NEW_IOSTREAMS */ +#include +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#ifndef __SGI_STL_INTERNAL_ITERATOR_BASE_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#include +#endif +#ifndef __TYPE_TRAITS_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +// Names from stl_iterator.h + +using __STD::input_iterator_tag; +using __STD::output_iterator_tag; +using __STD::forward_iterator_tag; +using __STD::bidirectional_iterator_tag; +using __STD::random_access_iterator_tag; + +#if 0 +using __STD::iterator; +#endif +using __STD::input_iterator; +using __STD::output_iterator; +using __STD::forward_iterator; +using __STD::bidirectional_iterator; +using __STD::random_access_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +using __STD::iterator_traits; +#endif + +using __STD::iterator_category; +using __STD::distance_type; +using __STD::value_type; + +using __STD::distance; +using __STD::advance; + +using __STD::insert_iterator; +using __STD::front_insert_iterator; +using __STD::back_insert_iterator; +using __STD::inserter; +using __STD::front_inserter; +using __STD::back_inserter; + +using __STD::reverse_iterator; +using __STD::reverse_bidirectional_iterator; + +using __STD::istream_iterator; +using __STD::ostream_iterator; + +// Names from stl_construct.h +using __STD::construct; +using __STD::destroy; + +// Names from stl_raw_storage_iter.h +using __STD::raw_storage_iterator; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/limits b/darkice/tags/darkice-0_2/stl/limits new file mode 100644 index 0000000..f1a9a09 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/limits @@ -0,0 +1,537 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is not portable code. Parts of numeric_limits<> are + * inherently machine-dependent. At present this file is suitable + * for the MIPS and ia32 architectures. + */ + +#ifndef __SGI_CPP_LIMITS +#define __SGI_CPP_LIMITS + +#include +#include +#include + +__STL_BEGIN_NAMESPACE + +enum float_round_style { + round_indeterminate = -1, + round_toward_zero = 0, + round_to_nearest = 1, + round_toward_infinity = 2, + round_toward_neg_infinity = 3 +}; + +enum float_denorm_style { + denorm_indeterminate = -1, + denorm_absent = 0, + denorm_present = 1 +}; + +// The C++ standard (section 18.2.1) requires that some of the members of +// numeric_limits be static const data members that are given constant- +// initializers within the class declaration. On compilers where the +// __STL_STATIC_CONST_INIT_BUG macro is defined, it is impossible to write +// a standard-conforming numeric_limits class. +// +// There are two possible workarounds: either initialize the data +// members outside the class, or change them from data members to +// enums. Neither workaround is satisfactory: the former makes it +// impossible to use the data members in constant-expressions, and the +// latter means they have the wrong type and that it is impossible to +// take their addresses. We choose the former workaround. + +#ifdef __STL_STATIC_CONST_INIT_BUG +# define __STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ + enum { __mem_name = __mem_value } +#else /* __STL_STATIC_CONST_INIT_BUG */ +# define __STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ + static const __mem_type __mem_name = __mem_value +#endif /* __STL_STATIC_CONST_INIT_BUG */ + +// Base class for all specializations of numeric_limits. + +template +class _Numeric_limits_base { +public: + __STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false); + + static __number min() __STL_NOTHROW { return __number(); } + static __number max() __STL_NOTHROW { return __number(); } + + __STL_DECLARE_LIMITS_MEMBER(int, digits, 0); + __STL_DECLARE_LIMITS_MEMBER(int, digits10, 0); + + __STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false); + __STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false); + __STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false); + + __STL_DECLARE_LIMITS_MEMBER(int, radix, 0); + + static __number epsilon() __STL_NOTHROW { return __number(); } + static __number round_error() __STL_NOTHROW { return __number(); } + + __STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0); + __STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0); + __STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0); + __STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0); + + __STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false); + __STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false); + __STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false); + __STL_DECLARE_LIMITS_MEMBER(float_denorm_style, + has_denorm, + denorm_absent); + __STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); + + static __number infinity() __STL_NOTHROW { return __number(); } + static __number quiet_NaN() __STL_NOTHROW { return __number(); } + static __number signaling_NaN() __STL_NOTHROW { return __number(); } + static __number denorm_min() __STL_NOTHROW { return __number(); } + + __STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false); + __STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false); + __STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false); + + __STL_DECLARE_LIMITS_MEMBER(bool, traps, false); + __STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); + __STL_DECLARE_LIMITS_MEMBER(float_round_style, + round_style, + round_toward_zero); +}; + +#ifdef __STL_STATIC_CONST_INIT_BUG +# define __STL_DEFINE_NUMERIC_BASE_MEMBER(__type, __mem) +#else /* __STL_STATIC_CONST_INIT_BUG */ +# define __STL_DEFINE_NUMERIC_BASE_MEMBER(__type, __mem) \ + template \ + const __type _Numeric_limits_base<__number>:: __mem +#endif /* __STL_STATIC_CONST_INIT_BUG */ + +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_specialized); +__STL_DEFINE_NUMERIC_BASE_MEMBER(int, digits); +__STL_DEFINE_NUMERIC_BASE_MEMBER(int, digits10); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_signed); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_integer); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_exact); +__STL_DEFINE_NUMERIC_BASE_MEMBER(int, radix); +__STL_DEFINE_NUMERIC_BASE_MEMBER(int, min_exponent); +__STL_DEFINE_NUMERIC_BASE_MEMBER(int, max_exponent); +__STL_DEFINE_NUMERIC_BASE_MEMBER(int, min_exponent10); +__STL_DEFINE_NUMERIC_BASE_MEMBER(int, max_exponent10); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_infinity); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_quiet_NaN); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_signaling_NaN); +__STL_DEFINE_NUMERIC_BASE_MEMBER(float_denorm_style, has_denorm); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_denorm_loss); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_iec559); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_bounded); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_modulo); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, traps); +__STL_DEFINE_NUMERIC_BASE_MEMBER(bool, tinyness_before); +__STL_DEFINE_NUMERIC_BASE_MEMBER(float_round_style, round_style); + + +// Base class for integers. + +template +class _Integer_limits : public _Numeric_limits_base<_Int> +{ +public: + __STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); + + static _Int min() __STL_NOTHROW { return __imin; } + static _Int max() __STL_NOTHROW { return __imax; } + + __STL_DECLARE_LIMITS_MEMBER(int, + digits, + (__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT) + - (__imin == 0 ? 0 : 1) + : __idigits); + __STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000); + // log 2 = 0.301029995664... + + __STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0); + __STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true); + __STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true); + __STL_DECLARE_LIMITS_MEMBER(int, radix, 2); + + __STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); + __STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, __ismod); +}; + +#ifdef __STL_STATIC_CONST_INIT_BUG +# define __STL_DEFINE_INTEGER_LIMITS_MEMBER(__type, __mem) +#else /* __STL_STATIC_CONST_INIT_BUG */ +# define __STL_DEFINE_INTEGER_LIMITS_MEMBER(__type, __mem) \ + template \ + const __type _Integer_limits<_Int, __imin, __imax, __idig, __ismod>::__mem +#endif /* __STL_STATIC_CONST_INIT_BUG */ + +__STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_specialized); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(int, digits); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(int, digits10); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_signed); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_integer); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_exact); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(int, radix); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_bounded); +__STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_modulo); + + +// Base class for floating-point numbers. +template +class _Floating_limits : public _Numeric_limits_base<__number> +{ +public: + __STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); + + __STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits); + __STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10); + + __STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true); + + __STL_DECLARE_LIMITS_MEMBER(int, radix, 2); + + __STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp); + __STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp); + __STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10); + __STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10); + + __STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true); + __STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true); + __STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true); + __STL_DECLARE_LIMITS_MEMBER(float_denorm_style, + has_denorm, + denorm_indeterminate); + __STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); + + __STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559); + __STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); + __STL_DECLARE_LIMITS_MEMBER(bool, traps, true); + __STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); + + __STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle); +}; + +#ifdef __STL_STATIC_CONST_INIT_BUG +# define __STL_DEFINE_FLOAT_LIMITS_MEMBER(__type, __mem) +#else /* __STL_STATIC_CONST_INIT_BUG */ +# define __STL_DEFINE_FLOAT_LIMITS_MEMBER(__type, __mem) \ + template \ + const __type _Floating_limits<__Num, __Dig, __Dig10, \ + __MnX, __MxX, __MnX10, __MxX10, \ + __IsIEEE, __Sty>:: __mem +#endif /* __STL_STATIC_CONST_INIT_BUG */ + +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_specialized); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(int, digits); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(int, digits10); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_signed); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(int, radix); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(int, min_exponent); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(int, max_exponent); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(int, min_exponent10); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(int, max_exponent10); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_infinity); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_quiet_NaN); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_signaling_NaN); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(float_denorm_style, has_denorm); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_denorm_loss); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_iec559); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_bounded); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, traps); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, tinyness_before); +__STL_DEFINE_FLOAT_LIMITS_MEMBER(float_round_style, round_style); + + +#undef __STL_DECLARE_NUMERIC_LIMITS_MEMBER +#undef __STL_DEFINE_NUMERIC_BASE_MEMBER +#undef __STL_DEFINE_INTEGER_LIMITS_MEMBER +#undef __STL_DEFINE_FLOAT_LIMITS_MEMBER + +// Class numeric_limits + +// The unspecialized class. + +template +class numeric_limits : public _Numeric_limits_base<_Tp> {}; + +// Specializations for all built-in integral types. + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +#endif + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +#ifdef __STL_LONG_LONG + +// Some compilers have long long, but don't define the +// LONGLONG_MIN and LONGLONG_MAX macros in limits.h. This +// assumes that long long is 64 bits. +#if !defined(LONGLONG_MIN) && !defined(LONGLONG_MAX) \ + && !defined(ULONGLONG_MAX) + +#define ULONGLONG_MAX 0xffffffffffffffffLLU +#define LONGLONG_MAX 0x7fffffffffffffffLL +#define LONGLONG_MIN (-LONGLONG_MAX - 1LL) + +#endif + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +__STL_TEMPLATE_NULL +class numeric_limits + : public _Integer_limits +{}; + +#endif /* __STL_LONG_LONG */ + +// Specializations for all built-in floating-point type. + +__STL_TEMPLATE_NULL class numeric_limits + : public _Floating_limits +{ +public: + static float min() __STL_NOTHROW { return FLT_MIN; } + static float denorm_min() __STL_NOTHROW { return FLT_MIN; } + static float max() __STL_NOTHROW { return FLT_MAX; } + static float epsilon() __STL_NOTHROW { return FLT_EPSILON; } + static float round_error() __STL_NOTHROW { return 0.5f; } // Units: ulps. + static float infinity() __STL_NOTHROW; + static float quiet_NaN() __STL_NOTHROW; + static float signaling_NaN() __STL_NOTHROW; +}; + +__STL_TEMPLATE_NULL class numeric_limits + : public _Floating_limits +{ +public: + static double min() __STL_NOTHROW { return DBL_MIN; } + static double denorm_min() __STL_NOTHROW { return DBL_MIN; } + static double max() __STL_NOTHROW { return DBL_MAX; } + static double epsilon() __STL_NOTHROW { return DBL_EPSILON; } + static double round_error() __STL_NOTHROW { return 0.5; } // Units: ulps. + static double infinity() __STL_NOTHROW; + static double quiet_NaN() __STL_NOTHROW; + static double signaling_NaN() __STL_NOTHROW; +}; + +__STL_TEMPLATE_NULL class numeric_limits + : public _Floating_limits +{ +public: + static long double min() __STL_NOTHROW { return LDBL_MIN; } + static long double denorm_min() __STL_NOTHROW { return LDBL_MIN; } + static long double max() __STL_NOTHROW { return LDBL_MAX; } + static long double epsilon() __STL_NOTHROW { return LDBL_EPSILON; } + static long double round_error() __STL_NOTHROW { return 4; } // Units: ulps. + static long double infinity() __STL_NOTHROW; + static long double quiet_NaN() __STL_NOTHROW; + static long double signaling_NaN() __STL_NOTHROW; +}; + +// We write special values (Inf and NaN) as bit patterns and +// cast the the appropriate floating-point types. + +#if defined(_MIPSEB) +// Big-endian MIPS. float is 32 bits, double 64, long double 128. + +#define _Define_float(__f, __h, __l) \ + inline float numeric_limits::__f() __STL_NOTHROW { \ + static const unsigned short __x[2] = { __h, __l }; \ + return *reinterpret_cast(__x); } +#define _Define_double(__f, __h, __l) \ + inline double numeric_limits::__f() __STL_NOTHROW { \ + static const unsigned short __x[4] = { __h, __l }; \ + return *reinterpret_cast(__x); } +#define _Define_ldouble(__f, __h, __l) \ + inline long double numeric_limits::__f() __STL_NOTHROW { \ + static const unsigned short __x[8] = { __h, __l }; \ + return *reinterpret_cast(__x); } + +_Define_float(infinity, 0x7f80, 0) +_Define_float(quiet_NaN, 0x7f81, 0) +_Define_float(signaling_NaN, 0x7fc1, 0) + +_Define_double(infinity, 0x7ff0, 0) +_Define_double(quiet_NaN, 0x7ff1, 0) +_Define_double(signaling_NaN, 0x7ff9, 0) + +_Define_ldouble(infinity, 0x7ff0, 0) +_Define_ldouble(quiet_NaN, 0x7ff1, 0) +_Define_ldouble(signaling_NaN, 0x7ff9, 0) + +#elif defined(__i386) || defined(_M_IX86) +// Little-endian ia32. float is 32 bits, double 64, long double 80. + +#define _Define_float(__f, __h, __l) \ + inline float numeric_limits::__f() __STL_NOTHROW { \ + static const unsigned short __x[2] = { __l, __h }; \ + return *reinterpret_cast(__x); } +#define _Define_double(__f, __h, __l) \ + inline double numeric_limits::__f() __STL_NOTHROW { \ + static const unsigned short __x[4] = { 0, 0, __l, __h }; \ + return *reinterpret_cast(__x); } +#define _Define_ldouble(__f, __h, __l) \ + inline long double numeric_limits::__f() __STL_NOTHROW { \ + static const unsigned short __x[5] = { 0, 0, 0, __l, __h }; \ + return *reinterpret_cast(__x); } + +_Define_float(infinity, 0x7f80, 0) +_Define_float(quiet_NaN, 0x7fa0, 0) +_Define_float(signaling_NaN, 0x7fc0, 0) + +_Define_double(infinity, 0x7ff0, 0) +_Define_double(quiet_NaN, 0x7ff4, 0) +_Define_double(signaling_NaN, 0x7ff8, 0) + +_Define_ldouble(infinity, 0x7fff, 0x8000) +_Define_ldouble(quiet_NaN, 0x7fff, 0xa000) +_Define_ldouble(signaling_NaN, 0x7fff, 0xc000) + +#else + +/* This is an architecture we don't know how to handle. Return some + obviously wrong values. */ + +#define _Define_float(__f) \ + inline float numeric_limits::__f() __STL_NOTHROW { \ + return 0; } +#define _Define_double(__f) \ + inline double numeric_limits::__f() __STL_NOTHROW { \ + return 0; } +#define _Define_ldouble(__f) \ + inline long double numeric_limits::__f() __STL_NOTHROW { \ + return 0; } + +_Define_float(infinity) +_Define_float(quiet_NaN) +_Define_float(signaling_NaN) + +_Define_double(infinity) +_Define_double(quiet_NaN) +_Define_double(signaling_NaN) + +_Define_ldouble(infinity) +_Define_ldouble(quiet_NaN) +_Define_ldouble(signaling_NaN) + +#endif + +#undef _Define_float +#undef _Define_double +#undef _Define_ldouble + +__STL_END_NAMESPACE + +#endif /* __SGI_CPP_LIMITS */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/list b/darkice/tags/darkice-0_2/stl/list new file mode 100644 index 0000000..5294f39 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/list @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_LIST +#define __SGI_STL_LIST + +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_LIST */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/list.h b/darkice/tags/darkice-0_2/stl/list.h new file mode 100644 index 0000000..4e6ee0b --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/list.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_LIST_H +#define __SGI_STL_LIST_H + +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::list; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/map b/darkice/tags/darkice-0_2/stl/map new file mode 100644 index 0000000..4cfb765 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/map @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MAP +#define __SGI_STL_MAP + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include + +#endif /* __SGI_STL_MAP */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/map.h b/darkice/tags/darkice-0_2/stl/map.h new file mode 100644 index 0000000..902f66e --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/map.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MAP_H +#define __SGI_STL_MAP_H + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::rb_tree; +using __STD::map; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/memory b/darkice/tags/darkice-0_2/stl/memory new file mode 100644 index 0000000..a1b096c --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/memory @@ -0,0 +1,134 @@ +/* + * Copyright (c) 1997-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_MEMORY +#define __SGI_STL_MEMORY + +#include +#include +#include +#include +#include +#include + + +__STL_BEGIN_NAMESPACE + +#if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \ + defined(__STL_MEMBER_TEMPLATES) + +template struct auto_ptr_ref { + _Tp1* _M_ptr; + auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} +}; + +#endif + +template class auto_ptr { +private: + _Tp* _M_ptr; + +public: + typedef _Tp element_type; + + explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} + auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} + +#ifdef __STL_MEMBER_TEMPLATES + template auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW + : _M_ptr(__a.release()) {} +#endif /* __STL_MEMBER_TEMPLATES */ + + auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { + if (&__a != this) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; + } + +#ifdef __STL_MEMBER_TEMPLATES + template + auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { + if (__a.get() != this->get()) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; + } +#endif /* __STL_MEMBER_TEMPLATES */ + + // Note: The C++ standard says there is supposed to be an empty throw + // specification here, but omitting it is standard conforming. Its + // presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2) + // this is prohibited. + ~auto_ptr() { delete _M_ptr; } + + _Tp& operator*() const __STL_NOTHROW { + return *_M_ptr; + } + _Tp* operator->() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* get() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* release() __STL_NOTHROW { + _Tp* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; + } + void reset(_Tp* __p = 0) __STL_NOTHROW { + if (__p != _M_ptr) { + delete _M_ptr; + _M_ptr = __p; + } + } + + // According to the C++ standard, these conversions are required. Most + // present-day compilers, however, do not enforce that requirement---and, + // in fact, most present-day compilers do not support the language + // features that these conversions rely on. + +#if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \ + defined(__STL_MEMBER_TEMPLATES) + +public: + auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW + : _M_ptr(__ref._M_ptr) {} + + auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW { + if (__ref._M_ptr != this->get()) { + delete _M_ptr; + _M_ptr = __ref._M_ptr; + } + return *this; + } + + template operator auto_ptr_ref<_Tp1>() __STL_NOTHROW + { return auto_ptr_ref<_Tp1>(this->release()); } + template operator auto_ptr<_Tp1>() __STL_NOTHROW + { return auto_ptr<_Tp1>(this->release()); } + +#endif /* auto ptr conversions && member templates */ +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_MEMORY */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/multimap.h b/darkice/tags/darkice-0_2/stl/multimap.h new file mode 100644 index 0000000..44b26be --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/multimap.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MULTIMAP_H +#define __SGI_STL_MULTIMAP_H + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::rb_tree; +using __STD::multimap; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/multiset.h b/darkice/tags/darkice-0_2/stl/multiset.h new file mode 100644 index 0000000..91f0379 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/multiset.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MULTISET_H +#define __SGI_STL_MULTISET_H + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::rb_tree; +using __STD::multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/numeric b/darkice/tags/darkice-0_2/stl/numeric new file mode 100644 index 0000000..98e3237 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/numeric @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_NUMERIC +#define __SGI_STL_NUMERIC + +#include +#include +#include + +#ifdef __STL_USE_NEW_IOSTREAMS +#include +#else /* __STL_USE_NEW_IOSTREAMS */ +#include +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#include +#include +#include +#include + +#endif /* __SGI_STL_NUMERIC */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/pair.h b/darkice/tags/darkice-0_2/stl/pair.h new file mode 100644 index 0000000..00f5cad --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/pair.h @@ -0,0 +1,51 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_PAIR_H +#define __SGI_STL_PAIR_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::pair; +using __STD::make_pair; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/pthread_alloc b/darkice/tags/darkice-0_2/stl/pthread_alloc new file mode 100644 index 0000000..33073da --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/pthread_alloc @@ -0,0 +1,495 @@ +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_PTHREAD_ALLOC +#define __SGI_STL_PTHREAD_ALLOC + +// Pthread-specific node allocator. +// This is similar to the default allocator, except that free-list +// information is kept separately for each thread, avoiding locking. +// This should be reasonably fast even in the presence of threads. +// The down side is that storage may not be well-utilized. +// It is not an error to allocate memory in thread A and deallocate +// it in thread B. But this effectively transfers ownership of the memory, +// so that it can only be reallocated by thread B. Thus this can effectively +// result in a storage leak if it's done on a regular basis. +// It can also result in frequent sharing of +// cache lines among processors, with potentially serious performance +// consequences. + +#include +#include +#include +#ifndef __RESTRICT +# define __RESTRICT +#endif + +#ifndef __STL_NO_BAD_ALLOC +# include +#endif + +__STL_BEGIN_NAMESPACE + +#define __STL_DATA_ALIGNMENT 8 + +union _Pthread_alloc_obj { + union _Pthread_alloc_obj * __free_list_link; + char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */ +}; + +// Pthread allocators don't appear to the client to have meaningful +// instances. We do in fact need to associate some state with each +// thread. That state is represented by +// _Pthread_alloc_per_thread_state<_Max_size>. + +template +struct _Pthread_alloc_per_thread_state { + typedef _Pthread_alloc_obj __obj; + enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT }; + _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; + _Pthread_alloc_per_thread_state<_Max_size> * __next; + // Free list link for list of available per thread structures. + // When one of these becomes available for reuse due to thread + // termination, any objects in its free list remain associated + // with it. The whole structure may then be used by a newly + // created thread. + _Pthread_alloc_per_thread_state() : __next(0) + { + memset((void *)__free_list, 0, (size_t) _S_NFREELISTS * sizeof(__obj *)); + } + // Returns an object of size __n, and possibly adds to size n free list. + void *_M_refill(size_t __n); +}; + +// Pthread-specific allocator. +// The argument specifies the largest object size allocated from per-thread +// free lists. Larger objects are allocated using malloc_alloc. +// Max_size must be a power of 2. +template +class _Pthread_alloc_template { + +public: // but only for internal use: + + typedef _Pthread_alloc_obj __obj; + + // Allocates a chunk for nobjs of size size. nobjs may be reduced + // if it is inconvenient to allocate the requested number. + static char *_S_chunk_alloc(size_t __size, int &__nobjs); + + enum {_S_ALIGN = __STL_DATA_ALIGNMENT}; + + static size_t _S_round_up(size_t __bytes) { + return (((__bytes) + (int) _S_ALIGN-1) & ~((int) _S_ALIGN - 1)); + } + static size_t _S_freelist_index(size_t __bytes) { + return (((__bytes) + (int) _S_ALIGN-1)/(int)_S_ALIGN - 1); + } + +private: + // Chunk allocation state. And other shared state. + // Protected by _S_chunk_allocator_lock. + static pthread_mutex_t _S_chunk_allocator_lock; + static char *_S_start_free; + static char *_S_end_free; + static size_t _S_heap_size; + static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states; + static pthread_key_t _S_key; + static bool _S_key_initialized; + // Pthread key under which per thread state is stored. + // Allocator instances that are currently unclaimed by any thread. + static void _S_destructor(void *instance); + // Function to be called on thread exit to reclaim per thread + // state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state(); + // Return a recycled or new per thread state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state(); + // ensure that the current thread has an associated + // per thread state. + class _M_lock; + friend class _M_lock; + class _M_lock { + public: + _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); } + ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); } + }; + +public: + + /* n must be > 0 */ + static void * allocate(size_t __n) + { + __obj * volatile * __my_free_list; + __obj * __RESTRICT __result; + _Pthread_alloc_per_thread_state<_Max_size>* __a; + + if (__n > _Max_size) { + return(malloc_alloc::allocate(__n)); + } + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); + } + __my_free_list = __a -> __free_list + _S_freelist_index(__n); + __result = *__my_free_list; + if (__result == 0) { + void *__r = __a -> _M_refill(_S_round_up(__n)); + return __r; + } + *__my_free_list = __result -> __free_list_link; + return (__result); + }; + + /* p may not be 0 */ + static void deallocate(void *__p, size_t __n) + { + __obj *__q = (__obj *)__p; + __obj * volatile * __my_free_list; + _Pthread_alloc_per_thread_state<_Max_size>* __a; + + if (__n > _Max_size) { + malloc_alloc::deallocate(__p, __n); + return; + } + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); + } + __my_free_list = __a->__free_list + _S_freelist_index(__n); + __q -> __free_list_link = *__my_free_list; + *__my_free_list = __q; + } + + static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz); + +} ; + +typedef _Pthread_alloc_template<> pthread_alloc; + + +template +void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance) +{ + _M_lock __lock_instance; // Need to acquire lock here. + _Pthread_alloc_per_thread_state<_Max_size>* __s = + (_Pthread_alloc_per_thread_state<_Max_size> *)__instance; + __s -> __next = _S_free_per_thread_states; + _S_free_per_thread_states = __s; +} + +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state() +{ + /* lock already held here. */ + if (0 != _S_free_per_thread_states) { + _Pthread_alloc_per_thread_state<_Max_size> *__result = + _S_free_per_thread_states; + _S_free_per_thread_states = _S_free_per_thread_states -> __next; + return __result; + } else { + return new _Pthread_alloc_per_thread_state<_Max_size>; + } +} + +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state() +{ + /*REFERENCED*/ + _M_lock __lock_instance; // Need to acquire lock here. + int __ret_code; + _Pthread_alloc_per_thread_state<_Max_size> * __result; + if (!_S_key_initialized) { + if (pthread_key_create(&_S_key, _S_destructor)) { + __THROW_BAD_ALLOC; // defined in stl_alloc.h + } + _S_key_initialized = true; + } + __result = _S_new_per_thread_state(); + __ret_code = pthread_setspecific(_S_key, __result); + if (__ret_code) { + if (__ret_code == ENOMEM) { + __THROW_BAD_ALLOC; + } else { + // EINVAL + abort(); + } + } + return __result; +} + +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +template +char *_Pthread_alloc_template<_Max_size> +::_S_chunk_alloc(size_t __size, int &__nobjs) +{ + { + char * __result; + size_t __total_bytes; + size_t __bytes_left; + /*REFERENCED*/ + _M_lock __lock_instance; // Acquire lock for this routine + + __total_bytes = __size * __nobjs; + __bytes_left = _S_end_free - _S_start_free; + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = __bytes_left/__size; + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else { + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); + // Try to make use of the left-over piece. + if (__bytes_left > 0) { + _Pthread_alloc_per_thread_state<_Max_size>* __a = + (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key); + __obj * volatile * __my_free_list = + __a->__free_list + _S_freelist_index(__bytes_left); + + ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list; + *__my_free_list = (__obj *)_S_start_free; + } +# ifdef _SGI_SOURCE + // Try to get memory that's aligned on something like a + // cache line boundary, so as to avoid parceling out + // parts of the same line to different threads and thus + // possibly different processors. + { + const int __cache_line_size = 128; // probable upper bound + __bytes_to_get &= ~(__cache_line_size-1); + _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); + if (0 == _S_start_free) { + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); + } + } +# else /* !SGI_SOURCE */ + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); +# endif + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; + } + } + // lock is released here + return(_S_chunk_alloc(__size, __nobjs)); +} + + +/* Returns an object of size n, and optionally adds to size n free list.*/ +/* We assume that n is properly aligned. */ +/* We hold the allocation lock. */ +template +void *_Pthread_alloc_per_thread_state<_Max_size> +::_M_refill(size_t __n) +{ + int __nobjs = 128; + char * __chunk = + _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs); + __obj * volatile * __my_free_list; + __obj * __result; + __obj * __current_obj, * __next_obj; + int __i; + + if (1 == __nobjs) { + return(__chunk); + } + __my_free_list = __free_list + + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n); + + /* Build free list in chunk */ + __result = (__obj *)__chunk; + *__my_free_list = __next_obj = (__obj *)(__chunk + __n); + for (__i = 1; ; __i++) { + __current_obj = __next_obj; + __next_obj = (__obj *)((char *)__next_obj + __n); + if (__nobjs - 1 == __i) { + __current_obj -> __free_list_link = 0; + break; + } else { + __current_obj -> __free_list_link = __next_obj; + } + } + return(__result); +} + +template +void *_Pthread_alloc_template<_Max_size> +::reallocate(void *__p, size_t __old_sz, size_t __new_sz) +{ + void * __result; + size_t __copy_sz; + + if (__old_sz > _Max_size + && __new_sz > _Max_size) { + return(realloc(__p, __new_sz)); + } + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + __result = allocate(__new_sz); + __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; + memcpy(__result, __p, __copy_sz); + deallocate(__p, __old_sz); + return(__result); +} + +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0; + +template +pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key; + +template +bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false; + +template +pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock += PTHREAD_MUTEX_INITIALIZER; + +template +char *_Pthread_alloc_template<_Max_size> +::_S_start_free = 0; + +template +char *_Pthread_alloc_template<_Max_size> +::_S_end_free = 0; + +template +size_t _Pthread_alloc_template<_Max_size> +::_S_heap_size = 0; + +#ifdef __STL_USE_STD_ALLOCATORS + +template +class pthread_allocator { + typedef pthread_alloc _S_Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef pthread_allocator<_NewType> other; + }; + + pthread_allocator() __STL_NOTHROW {} + pthread_allocator(const pthread_allocator& a) __STL_NOTHROW {} + template + pthread_allocator(const pthread_allocator<_OtherType>&) + __STL_NOTHROW {} + ~pthread_allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer _p) { _p->~_Tp(); } +}; + +template<> +class pthread_allocator { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef pthread_allocator<_NewType> other; + }; +}; + +template +inline bool operator==(const _Pthread_alloc_template<_Max_size>&, + const _Pthread_alloc_template<_Max_size>&) +{ + return true; +} + +template +inline bool operator==(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>& a2) +{ + return true; +} + +template +inline bool operator!=(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>&) +{ + return false; +} + +template +struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > + allocator_type; +}; + +template +struct _Alloc_traits<_Tp, __allocator<_Atype, _Pthread_alloc_template<_Max> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type; +}; + +template +struct _Alloc_traits<_Tp, pthread_allocator<_Atype> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type; + typedef pthread_allocator<_Tp> allocator_type; +}; + + +#endif /* __STL_USE_STD_ALLOCATORS */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_PTHREAD_ALLOC */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/pthread_alloc.h b/darkice/tags/darkice-0_2/stl/pthread_alloc.h new file mode 100644 index 0000000..774ef04 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/pthread_alloc.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_PTHREAD_ALLOC_H +#define __SGI_STL_PTHREAD_ALLOC_H + +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::_Pthread_alloc_template; +using __STD::pthread_alloc; + +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* __SGI_STL_PTHREAD_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/queue b/darkice/tags/darkice-0_2/stl/queue new file mode 100644 index 0000000..f9417fb --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/queue @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_QUEUE +#define __SGI_STL_QUEUE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_QUEUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/rope b/darkice/tags/darkice-0_2/stl/rope new file mode 100644 index 0000000..f861500 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/rope @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ROPE +#define __SGI_STL_ROPE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_ROPE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/rope.h b/darkice/tags/darkice-0_2/stl/rope.h new file mode 100644 index 0000000..d767fa3 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/rope.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ROPE_H +#define __SGI_STL_ROPE_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::char_producer; +using __STD::sequence_buffer; +using __STD::rope; +using __STD::crope; +using __STD::wrope; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/ropeimpl.h b/darkice/tags/darkice-0_2/stl/ropeimpl.h new file mode 100644 index 0000000..e847ecd --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/ropeimpl.h @@ -0,0 +1,1587 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +# include + +#ifdef __STL_USE_NEW_IOSTREAMS +# include +#else /* __STL_USE_NEW_IOSTREAMS */ +# include +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#ifdef __STL_USE_EXCEPTIONS +# include +#endif + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf +// if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. +// Results in a valid buf_ptr if the iterator can be legitimately +// dereferenced. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( + _Rope_iterator_base<_CharT,_Alloc>& __x) +{ + const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; + size_t __leaf_pos = __x._M_leaf_pos; + size_t __pos = __x._M_current_pos; + + switch(__leaf->_M_tag) { + case _RopeRep::_S_leaf: + __x._M_buf_start = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data; + __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); + __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; + break; + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + { + size_t __len = _S_iterator_buf_len; + size_t __buf_start_pos = __leaf_pos; + size_t __leaf_end = __leaf_pos + __leaf->_M_size; + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)__leaf)->_M_fn; + + if (__buf_start_pos + __len <= __pos) { + __buf_start_pos = __pos - __len/4; + if (__buf_start_pos + __len > __leaf_end) { + __buf_start_pos = __leaf_end - __len; + } + } + if (__buf_start_pos + __len > __leaf_end) { + __len = __leaf_end - __buf_start_pos; + } + (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf); + __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos); + __x._M_buf_start = __x._M_tmp_buf; + __x._M_buf_end = __x._M_tmp_buf + __len; + } + break; + default: + __stl_assert(0); + } +} + +// Set path and buffer inside a rope iterator. We assume that +// pos and root are already set. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache +(_Rope_iterator_base<_CharT,_Alloc>& __x) +{ + const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1]; + const _RopeRep* __curr_rope; + int __curr_depth = -1; /* index into path */ + size_t __curr_start_pos = 0; + size_t __pos = __x._M_current_pos; + unsigned char __dirns = 0; // Bit vector marking right turns in the path + + __stl_assert(__pos <= __x._M_root->_M_size); + if (__pos >= __x._M_root->_M_size) { + __x._M_buf_ptr = 0; + return; + } + __curr_rope = __x._M_root; + if (0 != __curr_rope->_M_c_string) { + /* Treat the root as a leaf. */ + __x._M_buf_start = __curr_rope->_M_c_string; + __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size; + __x._M_buf_ptr = __curr_rope->_M_c_string + __pos; + __x._M_path_end[0] = __curr_rope; + __x._M_leaf_index = 0; + __x._M_leaf_pos = 0; + return; + } + for(;;) { + ++__curr_depth; + __stl_assert(__curr_depth <= _RopeRep::_S_max_rope_depth); + __path[__curr_depth] = __curr_rope; + switch(__curr_rope->_M_tag) { + case _RopeRep::_S_leaf: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + __x._M_leaf_pos = __curr_start_pos; + goto done; + case _RopeRep::_S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c = + (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + __dirns <<= 1; + if (__pos >= __curr_start_pos + __left_len) { + __dirns |= 1; + __curr_rope = __c->_M_right; + __curr_start_pos += __left_len; + } else { + __curr_rope = __left; + } + } + break; + } + } + done: + // Copy last section of path into _M_path_end. + { + int __i = -1; + int __j = __curr_depth + 1 - _S_path_cache_len; + + if (__j < 0) __j = 0; + while (__j <= __curr_depth) { + __x._M_path_end[++__i] = __path[__j++]; + } + __x._M_leaf_index = __i; + } + __x._M_path_directions = __dirns; + _S_setbuf(__x); +} + +// Specialized version of the above. Assumes that +// the path cache is valid for the previous position. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr +(_Rope_iterator_base<_CharT,_Alloc>& __x) +{ + int __current_index = __x._M_leaf_index; + const _RopeRep* __current_node = __x._M_path_end[__current_index]; + size_t __len = __current_node->_M_size; + size_t __node_start_pos = __x._M_leaf_pos; + unsigned char __dirns = __x._M_path_directions; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c; + + __stl_assert(__x._M_current_pos <= __x._M_root->_M_size); + if (__x._M_current_pos - __node_start_pos < __len) { + /* More stuff in this leaf, we just didn't cache it. */ + _S_setbuf(__x); + return; + } + __stl_assert(__node_start_pos + __len == __x._M_current_pos); + // node_start_pos is starting position of last_node. + while (--__current_index >= 0) { + if (!(__dirns & 1) /* Path turned left */) + break; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; + // Otherwise we were in the right child. Thus we should pop + // the concatenation node. + __node_start_pos -= __c->_M_left->_M_size; + __dirns >>= 1; + } + if (__current_index < 0) { + // We underflowed the cache. Punt. + _S_setcache(__x); + return; + } + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; + // current_node is a concatenation node. We are positioned on the first + // character in its right child. + // node_start_pos is starting position of current_node. + __node_start_pos += __c->_M_left->_M_size; + __current_node = __c->_M_right; + __x._M_path_end[++__current_index] = __current_node; + __dirns |= 1; + while (_RopeRep::_S_concat == __current_node->_M_tag) { + ++__current_index; + if (_S_path_cache_len == __current_index) { + int __i; + for (__i = 0; __i < _S_path_cache_len-1; __i++) { + __x._M_path_end[__i] = __x._M_path_end[__i+1]; + } + --__current_index; + } + __current_node = + ((_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node)->_M_left; + __x._M_path_end[__current_index] = __current_node; + __dirns <<= 1; + // node_start_pos is unchanged. + } + __x._M_leaf_index = __current_index; + __x._M_leaf_pos = __node_start_pos; + __x._M_path_directions = __dirns; + _S_setbuf(__x); +} + +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) { + _M_current_pos += __n; + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_end - _M_buf_ptr; + if (__chars_left > __n) { + _M_buf_ptr += __n; + } else if (__chars_left == __n) { + _M_buf_ptr += __n; + _S_setcache_for_incr(*this); + } else { + _M_buf_ptr = 0; + } + } +} + +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) { + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_ptr - _M_buf_start; + if (__chars_left >= __n) { + _M_buf_ptr -= __n; + } else { + _M_buf_ptr = 0; + } + } + _M_current_pos -= __n; +} + +template +void _Rope_iterator<_CharT,_Alloc>::_M_check() { + if (_M_root_rope->_M_tree_ptr != _M_root) { + // _Rope was modified. Get things fixed up. + _RopeRep::_S_unref(_M_root); + _M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(_M_root); + _M_buf_ptr = 0; + } +} + +template +inline +_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( + const _Rope_iterator<_CharT,_Alloc>& __x) +: _Rope_iterator_base<_CharT,_Alloc>(__x) +{ } + +template +inline _Rope_iterator<_CharT,_Alloc>::_Rope_iterator( + rope<_CharT,_Alloc>& __r, size_t __pos) +: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), + _M_root_rope(&__r) +{ + _RopeRep::_S_ref(_M_root); +} + +template +inline size_t +rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) +{ + const _CharT* __p = __s; + + while (!_S_is0(*__p)) { ++__p; } + return (__p - __s); +} + + +#ifndef __GC + +template +inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() +{ + _CharT* __cstr = _M_c_string; + if (0 != __cstr) { + size_t __size = _M_size + 1; + destroy(__cstr, __cstr + __size); + _Data_deallocate(__cstr, __size); + } +} + + +template +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n, + allocator_type __a) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n) +#endif +{ + if (!_S_is_basic_char_type((_CharT*)0)) { + destroy(__s, __s + __n); + } +// This has to be a static member, so this gets a bit messy +# ifdef __STL_USE_STD_ALLOCATORS + __a.deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# else + _Data_deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# endif +} + + +// There are several reasons for not doing this with virtual destructors +// and a class specific delete operator: +// - A class specific delete operator can't easily get access to +// allocator instances if we need them. +// - Any virtual function would need a 4 or byte vtable pointer; +// this only requires a one byte tag per object. +template +void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() +{ + switch(_M_tag) { + case _S_leaf: + { + _Rope_RopeLeaf<_CharT,_Alloc>* __l + = (_Rope_RopeLeaf<_CharT,_Alloc>*)this; + __l->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf(); + _L_deallocate(__l, 1); + break; + } + case _S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c + = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this; + __c->_Rope_RopeConcatenation<_CharT,_Alloc>:: + ~_Rope_RopeConcatenation(); + _C_deallocate(__c, 1); + break; + } + case _S_function: + { + _Rope_RopeFunction<_CharT,_Alloc>* __f + = (_Rope_RopeFunction<_CharT,_Alloc>*)this; + __f->_Rope_RopeFunction<_CharT,_Alloc>::~_Rope_RopeFunction(); + _F_deallocate(__f, 1); + break; + } + case _S_substringfn: + { + _Rope_RopeSubstring<_CharT,_Alloc>* __ss = + (_Rope_RopeSubstring<_CharT,_Alloc>*)this; + __ss->_Rope_RopeSubstring<_CharT,_Alloc>:: + ~_Rope_RopeSubstring(); + _S_deallocate(__ss, 1); + break; + } + } +} +#else + +template +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t, allocator_type) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t) +#endif +{} + +#endif + + +// Concatenate a C string onto a leaf rope by copying the rope data. +// Used for short ropes. +template +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) +{ + size_t __old_len = __r->_M_size; + _CharT* __new_data = (_CharT*) + _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _RopeLeaf* __result; + + uninitialized_copy_n(__r->_M_data, __old_len, __new_data); + uninitialized_copy_n(__iter, __len, __new_data + __old_len); + _S_cond_store_eos(__new_data[__old_len + __len]); + __STL_TRY { + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, + __r->get_allocator()); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, + __r->get_allocator())); + return __result; +} + +#ifndef __GC +// As above, but it's OK to clobber original if refcount is 1 +template +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) +{ + __stl_assert(__r->_M_ref_count >= 1); + if (__r->_M_ref_count > 1) + return _S_leaf_concat_char_iter(__r, __iter, __len); + size_t __old_len = __r->_M_size; + if (_S_allocated_capacity(__old_len) >= __old_len + __len) { + // The space has been partially initialized for the standard + // character types. But that doesn't matter for those types. + uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len); + if (_S_is_basic_char_type((_CharT*)0)) { + _S_cond_store_eos(__r->_M_data[__old_len + __len]); + __stl_assert(__r->_M_c_string == __r->_M_data); + } else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + __r->_M_size = __old_len + __len; + __stl_assert(__r->_M_ref_count == 1); + __r->_M_ref_count = 2; + return __r; + } else { + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); + __stl_assert(__result->_M_ref_count == 1); + return __result; + } +} +#endif + +// Assumes left and right are not 0. +// Does not increment (nor decrement on exception) child reference counts. +// Result has ref count 1. +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) +{ + _RopeConcatenation* __result = + _S_new_RopeConcatenation(__left, __right, __left->get_allocator()); + size_t __depth = __result->_M_depth; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left->get_allocator() == __right->get_allocator()); +# endif + if (__depth > 20 && (__result->_M_size < 1000 || + __depth > _RopeRep::_S_max_rope_depth)) { + _RopeRep* __balanced; + + __STL_TRY { + __balanced = _S_balance(__result); +# ifndef __GC + if (__result != __balanced) { + __stl_assert(1 == __result->_M_ref_count + && 1 == __balanced->_M_ref_count); + } +# endif + __result->_M_unref_nonnil(); + } + __STL_UNWIND((_C_deallocate(__result,1))); + // In case of exception, we need to deallocate + // otherwise dangling result node. But caller + // still owns its children. Thus unref is + // inappropriate. + return __balanced; + } else { + return __result; + } +} + +template +rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter + (_RopeRep* __r, const _CharT*__s, size_t __slen) +{ + _RopeRep* __result; + if (0 == __slen) { + _S_ref(__r); + return __r; + } + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + if (_RopeRep::_S_leaf == __r->_M_tag && + __r->_M_size + __slen <= _S_copy_max) { + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); +# ifndef __GC + __stl_assert(1 == __result->_M_ref_count); +# endif + return __result; + } + if (_RopeRep::_S_concat == __r->_M_tag + && _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { + _RopeLeaf* __right = + (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); + if (__right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; + _RopeRep* __nright = + _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); + __left->_M_ref_nonnil(); + __STL_TRY { + __result = _S_tree_concat(__left, __nright); + } + __STL_UNWIND(_S_unref(__left); _S_unref(__nright)); +# ifndef __GC + __stl_assert(1 == __result->_M_ref_count); +# endif + return __result; + } + } + _RopeRep* __nright = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __STL_TRY { + __r->_M_ref_nonnil(); + __result = _S_tree_concat(__r, __nright); + } + __STL_UNWIND(_S_unref(__r); _S_unref(__nright)); +# ifndef __GC + __stl_assert(1 == __result->_M_ref_count); +# endif + return __result; +} + +#ifndef __GC +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_destr_concat_char_iter( + _RopeRep* __r, const _CharT* __s, size_t __slen) +{ + _RopeRep* __result; + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + size_t __count = __r->_M_ref_count; + size_t __orig_size = __r->_M_size; + __stl_assert(__count >= 1); + if (__count > 1) return _S_concat_char_iter(__r, __s, __slen); + if (0 == __slen) { + __r->_M_ref_count = 2; // One more than before + return __r; + } + if (__orig_size + __slen <= _S_copy_max && + _RopeRep::_S_leaf == __r->_M_tag) { + __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; + } + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); + if (_RopeRep::_S_leaf == __right->_M_tag + && __right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __new_right = + _S_destr_leaf_concat_char_iter(__right, __s, __slen); + if (__right == __new_right) { + __stl_assert(__new_right->_M_ref_count == 2); + __new_right->_M_ref_count = 1; + } else { + __stl_assert(__new_right->_M_ref_count >= 1); + __right->_M_unref_nonnil(); + } + __stl_assert(__r->_M_ref_count == 1); + __r->_M_ref_count = 2; // One more than before. + ((_RopeConcatenation*)__r)->_M_right = __new_right; + __r->_M_size = __orig_size + __slen; + if (0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + return __r; + } + } + _RopeRep* __right = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __r->_M_ref_nonnil(); + __STL_TRY { + __result = _S_tree_concat(__r, __right); + } + __STL_UNWIND(_S_unref(__r); _S_unref(__right)) + __stl_assert(1 == __result->_M_ref_count); + return __result; +} +#endif /* !__GC */ + +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) +{ + if (0 == __left) { + _S_ref(__right); + return __right; + } + if (0 == __right) { + __left->_M_ref_nonnil(); + return __left; + } + if (_RopeRep::_S_leaf == __right->_M_tag) { + if (_RopeRep::_S_leaf == __left->_M_tag) { + if (__right->_M_size + __left->_M_size <= _S_copy_max) { + return _S_leaf_concat_char_iter((_RopeLeaf*)__left, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + } + } else if (_RopeRep::_S_concat == __left->_M_tag + && _RopeRep::_S_leaf == + ((_RopeConcatenation*)__left)->_M_right->_M_tag) { + _RopeLeaf* __leftright = + (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + if (__leftright->_M_size + __right->_M_size <= _S_copy_max) { + _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left; + _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + __leftleft->_M_ref_nonnil(); + __STL_TRY { + return(_S_tree_concat(__leftleft, __rest)); + } + __STL_UNWIND(_S_unref(__leftleft); _S_unref(__rest)) + } + } + } + __left->_M_ref_nonnil(); + __right->_M_ref_nonnil(); + __STL_TRY { + return(_S_tree_concat(__left, __right)); + } + __STL_UNWIND(_S_unref(__left); _S_unref(__right)); +} + +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, + size_t __start, size_t __endp1) +{ + if (0 == __base) return 0; + size_t __len = __base->_M_size; + size_t __adj_endp1; + const size_t __lazy_threshold = 128; + + if (__endp1 >= __len) { + if (0 == __start) { + __base->_M_ref_nonnil(); + return __base; + } else { + __adj_endp1 = __len; + } + } else { + __adj_endp1 = __endp1; + } + switch(__base->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__base; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + size_t __left_len = __left->_M_size; + _RopeRep* __result; + + if (__adj_endp1 <= __left_len) { + return _S_substring(__left, __start, __endp1); + } else if (__start >= __left_len) { + return _S_substring(__right, __start - __left_len, + __adj_endp1 - __left_len); + } + _Self_destruct_ptr __left_result( + _S_substring(__left, __start, __left_len)); + _Self_destruct_ptr __right_result( + _S_substring(__right, 0, __endp1 - __left_len)); + __result = _S_concat(__left_result, __right_result); +# ifndef __GC + __stl_assert(1 == __result->_M_ref_count); +# endif + return __result; + } + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__base; + _RopeLeaf* __result; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) goto lazy; +# ifdef __GC + const _CharT* __section = __l->_M_data + __start; + __result = _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + __result->_M_c_string = 0; // Not eos terminated. +# else + // We should sometimes create substring node instead. + __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR( + __l->_M_data + __start, __result_len, + __base->get_allocator()); +# endif + return __result; + } + case _RopeRep::_S_substringfn: + // Avoid introducing multiple layers of substring nodes. + { + _RopeSubstring* __old = (_RopeSubstring*)__base; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) { + _RopeSubstring* __result = + _S_new_RopeSubstring(__old->_M_base, + __start + __old->_M_start, + __adj_endp1 - __start, + __base->get_allocator()); + return __result; + + } // *** else fall through: *** + } + case _RopeRep::_S_function: + { + _RopeFunction* __f = (_RopeFunction*)__base; + _CharT* __section; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + + if (__result_len > __lazy_threshold) goto lazy; + __section = (_CharT*) + _Data_allocate(_S_rounded_up_size(__result_len)); + __STL_TRY { + (*(__f->_M_fn))(__start, __result_len, __section); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING( + __section, __result_len, __base->get_allocator())); + _S_cond_store_eos(__section[__result_len]); + return _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + } + } + /*NOTREACHED*/ + __stl_assert(false); + lazy: + { + // Create substring node. + return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, + __base->get_allocator()); + } +} + +template +class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT* _M_buf_ptr; + public: + + _Rope_flatten_char_consumer(_CharT* __buffer) { + _M_buf_ptr = __buffer; + }; + ~_Rope_flatten_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + uninitialized_copy_n(__leaf, __n, _M_buf_ptr); + _M_buf_ptr += __n; + return true; + } +}; + +template +class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT _M_pattern; + public: + size_t _M_count; // Number of nonmatching characters + _Rope_find_char_char_consumer(_CharT __p) + : _M_pattern(__p), _M_count(0) {} + ~_Rope_find_char_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + size_t __i; + for (__i = 0; __i < __n; __i++) { + if (__leaf[__i] == _M_pattern) { + _M_count += __i; return false; + } + } + _M_count += __n; return true; + } +}; + +#ifdef __STL_USE_NEW_IOSTREAMS + template + // Here _CharT is both the stream and rope character type. +#else + template + // Here _CharT is the rope character type. Unlike in the + // above case, we somewhat handle the case in which it doesn't + // match the stream character type, i.e. char. +#endif +class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { + private: +# ifdef __STL_USE_NEW_IOSTREAMS + typedef basic_ostream<_CharT,_Traits> _Insert_ostream; +# else + typedef ostream _Insert_ostream; +# endif + _Insert_ostream& _M_o; + public: + _Rope_insert_char_consumer(_Insert_ostream& __writer) + : _M_o(__writer) {}; + ~_Rope_insert_char_consumer() { }; + // Caller is presumed to own the ostream + bool operator() (const _CharT* __leaf, size_t __n); + // Returns true to continue traversal. +}; + +#ifdef __STL_USE_NEW_IOSTREAMS + template + bool _Rope_insert_char_consumer<_CharT, _Traits>::operator() + (const _CharT* __leaf, size_t __n) + { + size_t __i; + // We assume that formatting is set up correctly for each element. + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); + return true; + } + +#else + template + bool _Rope_insert_char_consumer<_CharT>::operator() + (const _CharT* __leaf, size_t __n) + { + size_t __i; + // We assume that formatting is set up correctly for each element. + for (__i = 0; __i < __n; __i++) _M_o << __leaf[__i]; + return true; + } + + + __STL_TEMPLATE_NULL + inline bool _Rope_insert_char_consumer::operator() + (const char* __leaf, size_t __n) + { + size_t __i; + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); + return true; + } +#endif + +template +bool rope<_CharT, _Alloc>::_S_apply_to_pieces( + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end) +{ + if (0 == __r) return true; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __conc = (_RopeConcatenation*)__r; + _RopeRep* __left = __conc->_M_left; + size_t __left_len = __left->_M_size; + if (__begin < __left_len) { + size_t __left_end = min(__left_len, __end); + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) + return false; + } + if (__end > __left_len) { + _RopeRep* __right = __conc->_M_right; + size_t __right_start = max(__left_len, __begin); + if (!_S_apply_to_pieces(__c, __right, + __right_start - __left_len, + __end - __left_len)) { + return false; + } + } + } + return true; + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __c(__l->_M_data + __begin, __end - __begin); + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + size_t __len = __end - __begin; + bool __result; + _CharT* __buffer = + (_CharT*)alloc::allocate(__len * sizeof(_CharT)); + __STL_TRY { + (*(__f->_M_fn))(__begin, __len, __buffer); + __result = __c(__buffer, __len); + alloc::deallocate(__buffer, __len * sizeof(_CharT)); + } + __STL_UNWIND((alloc::deallocate(__buffer, + __len * sizeof(_CharT)))) + return __result; + } + default: + __stl_assert(false); + /*NOTREACHED*/ + return false; + } +} + +#ifdef __STL_USE_NEW_IOSTREAMS + template + inline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n) +#else + inline void _Rope_fill(ostream& __o, size_t __n) +#endif +{ + char __f = __o.fill(); + size_t __i; + + for (__i = 0; __i < __n; __i++) __o.put(__f); +} + + +template inline bool _Rope_is_simple(_CharT*) { return false; } +inline bool _Rope_is_simple(char*) { return true; } +inline bool _Rope_is_simple(wchar_t*) { return true; } + +#ifdef __STL_USE_NEW_IOSTREAMS + template + basic_ostream<_CharT, _Traits>& operator<< + (basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r) +#else + template + ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r) +#endif +{ + size_t __w = __o.width(); + bool __left = bool(__o.flags() & ios::left); + size_t __pad_len; + size_t __rope_len = __r.size(); +# ifdef __STL_USE_NEW_IOSTREAMS + _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); +# else + _Rope_insert_char_consumer<_CharT> __c(__o); +# endif + bool __is_simple = _Rope_is_simple((_CharT*)0); + + if (__rope_len < __w) { + __pad_len = __w - __rope_len; + } else { + __pad_len = 0; + } + if (!__is_simple) __o.width(__w/__rope_len); + __STL_TRY { + if (__is_simple && !__left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); + } + __r.apply_to_pieces(0, __r.size(), __c); + if (__is_simple && __left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); + } + if (!__is_simple) + __o.width(__w); + } + __STL_UNWIND(if (!__is_simple) __o.width(__w)) + return __o; +} + +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer) +{ + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); +} + +template +size_t +rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const +{ + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, _M_tree_ptr, __start, size()); + size_type __result_pos = __start + __c._M_count; +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; +} + +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) +{ + if (0 == __r) return __buffer; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + _CharT* __rest = _S_flatten(__left, __buffer); + return _S_flatten(__right, __rest); + } + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return copy_n(__l->_M_data, __l->_M_size, __buffer).second; + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + // We dont yet do anything with substring nodes. + // This needs to be fixed before ropefiles will work well. + { + _RopeFunction* __f = (_RopeFunction*)__r; + (*(__f->_M_fn))(0, __f->_M_size, __buffer); + return __buffer + __f->_M_size; + } + default: + __stl_assert(false); + /*NOTREACHED*/ + return 0; + } +} + + +// This needs work for _CharT != char +template +void +rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) +{ + for (int __i = 0; __i < __indent; __i++) putchar(' '); + if (0 == __r) { + printf("NULL\n"); return; + } + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + +# ifdef __GC + printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", + __r, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); +# else + printf("Concatenation %p (rc = %ld, depth = %d, " + "len = %ld, %s balanced)\n", + __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size, + __r->_M_is_balanced? "" : "not"); +# endif + _S_dump(__left, __indent + 2); + _S_dump(__right, __indent + 2); + return; + } else { + char* __kind; + + switch (__r->_M_tag) { + case _RopeRep::_S_leaf: + __kind = "Leaf"; + break; + case _RopeRep::_S_function: + __kind = "Function"; + break; + case _RopeRep::_S_substringfn: + __kind = "Function representing substring"; + break; + default: + __kind = "(corrupted kind field!)"; + } +# ifdef __GC + printf("%s %p (depth = %d, len = %ld) ", + __kind, __r, __r->_M_depth, __r->_M_size); +# else + printf("%s %p (rc = %ld, depth = %d, len = %ld) ", + __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size); +# endif + if (_S_is_one_byte_char_type((_CharT*)0)) { + const int __max_len = 40; + _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len)); + _CharT __buffer[__max_len + 1]; + bool __too_big = __r->_M_size > __prefix->_M_size; + + _S_flatten(__prefix, __buffer); + __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); + printf("%s%s\n", + (char*)__buffer, __too_big? "...\n" : "\n"); + } else { + printf("\n"); + } + } +} + +template +const unsigned long +rope<_CharT,_Alloc>::_S_min_len[ + _Rope_RopeRep<_CharT,_Alloc>::_S_max_rope_depth + 1] = { +/* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, +/* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, +/* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, +/* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368, +/* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811, +/* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309, +/* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352, +/* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, +/* 39 */165580141, /* 40 */267914296, /* 41 */433494437, +/* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, +/* 45 */2971215073u }; +// These are Fibonacci numbers < 2**32. + +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) +{ + _RopeRep* __forest[_RopeRep::_S_max_rope_depth + 1]; + _RopeRep* __result = 0; + int __i; + // Invariant: + // The concatenation of forest in descending order is equal to __r. + // __forest[__i]._M_size >= _S_min_len[__i] + // __forest[__i]._M_depth = __i + // References from forest are included in refcount. + + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + __forest[__i] = 0; + __STL_TRY { + _S_add_to_forest(__r, __forest); + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__result); +# endif + __result = _S_concat(__forest[__i], __result); + __forest[__i]->_M_unref_nonnil(); +# if !defined(__GC) && defined(__STL_USE_EXCEPTIONS) + __forest[__i] = 0; +# endif + } + } + __STL_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; __i++) + _S_unref(__forest[__i])) + if (__result->_M_depth > _RopeRep::_S_max_rope_depth) { +# ifdef __STL_USE_EXCEPTIONS + __STL_THROW(length_error("rope too long")); +# else + abort(); +# endif + } + return(__result); +} + + +template +void +rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + if (__r->_M_is_balanced) { + _S_add_leaf_to_forest(__r, __forest); + return; + } + __stl_assert(__r->_M_tag == _RopeRep::_S_concat); + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + + _S_add_to_forest(__c->_M_left, __forest); + _S_add_to_forest(__c->_M_right, __forest); + } +} + + +template +void +rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty + size_t __s = __r->_M_size; + + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + } + { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __insertee = _S_concat_and_set_balanced(__too_tiny, __r); + } + // Too_tiny dead, and no longer included in refcount. + // Insertee is live and included. + __stl_assert(_S_is_almost_balanced(__insertee)); + __stl_assert(__insertee->_M_depth <= __r->_M_depth + 1); + for (;; ++__i) { + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__insertee); +# endif + __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + __stl_assert(_S_is_almost_balanced(__insertee)); + } + __stl_assert(_S_min_len[__i] <= __insertee->_M_size); + __stl_assert(__forest[__i] == 0); + if (__i == _RopeRep::_S_max_rope_depth || + __insertee->_M_size < _S_min_len[__i+1]) { + __forest[__i] = __insertee; + // refcount is OK since __insertee is now dead. + return; + } + } +} + +template +_CharT +rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) +{ + __GC_CONST _CharT* __cstr = __r->_M_c_string; + + __stl_assert(__i < __r->_M_size); + if (0 != __cstr) return __cstr[__i]; + for(;;) { + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; + } else { + __r = __left; + } + } + break; + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __l->_M_data[__i]; + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + _CharT __result; + + (*(__f->_M_fn))(__i, 1, &__result); + return __result; + } + } + } +} + +# ifndef __GC +// Return a uniquely referenced character slot for the given +// position, or 0 if that's not possible. +template +_CharT* +rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) +{ + _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth]; + size_t __csptr = 0; + + for(;;) { + if (__r->_M_ref_count > 1) return 0; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c; + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; + } else { + __r = __left; + } + } + break; + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) + __clrstack[__csptr++] = __l; + while (__csptr > 0) { + -- __csptr; + _RopeRep* __d = __clrstack[__csptr]; + __d->_M_free_c_string(); + __d->_M_c_string = 0; + } + return __l->_M_data + __i; + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + return 0; + } + } +} +# endif /* __GC */ + +// The following could be implemented trivially using +// lexicographical_compare_3way. +// We do a little more work to avoid dealing with rope iterators for +// flat strings. +template +int +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, + const _RopeRep* __right) +{ + size_t __left_len; + size_t __right_len; + + if (0 == __right) return 0 != __left; + if (0 == __left) return -1; + __left_len = __left->_M_size; + __right_len = __right->_M_size; + if (_RopeRep::_S_leaf == __left->_M_tag) { + _RopeLeaf* __l = (_RopeLeaf*) __left; + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way( + __l->_M_data, __l->_M_data + __left_len, + __r->_M_data, __r->_M_data + __right_len); + } else { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way( + __l->_M_data, __l->_M_data + __left_len, + __rstart, __rend); + } + } else { + const_iterator __lstart(__left, 0); + const_iterator __lend(__left, __left_len); + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way( + __lstart, __lend, + __r->_M_data, __r->_M_data + __right_len); + } else { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way( + __lstart, __lend, + __rstart, __rend); + } + } +} + +// Assignment to reference proxies. +template +_Rope_char_ref_proxy<_CharT, _Alloc>& +_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) { + _RopeRep* __old = _M_root->_M_tree_ptr; +# ifndef __GC + // First check for the case in which everything is uniquely + // referenced. In that case we can do this destructively. + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) { + *__ptr = __c; + return *this; + } +# endif + _Self_destruct_ptr __left( + _My_rope::_S_substring(__old, 0, _M_pos)); + _Self_destruct_ptr __right( + _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size)); + _Self_destruct_ptr __result_left( + _My_rope::_S_destr_concat_char_iter(__left, &__c, 1)); + +# ifndef __GC + __stl_assert(__left == __result_left || 1 == __result_left->_M_ref_count); +# endif + _RopeRep* __result = + _My_rope::_S_concat(__result_left, __right); +# ifndef __GC + __stl_assert(1 <= __result->_M_ref_count); + _RopeRep::_S_unref(__old); +# endif + _M_root->_M_tree_ptr = __result; + return *this; +} + +template +inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const +{ + if (_M_current_valid) { + return _M_current; + } else { + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); + } +} +template +_Rope_char_ptr_proxy<_CharT, _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { + return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); +} + +template +rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, + const allocator_type& __a) +: _Base(__a) +{ + rope<_CharT,_Alloc> __result; + const size_t __exponentiate_threshold = 32; + size_t __exponent; + size_t __rest; + _CharT* __rest_buffer; + _RopeRep* __remainder; + rope<_CharT,_Alloc> __remainder_rope; + + if (0 == __n) + return; + + __exponent = __n / __exponentiate_threshold; + __rest = __n % __exponentiate_threshold; + if (0 == __rest) { + __remainder = 0; + } else { + __rest_buffer = _Data_allocate(_S_rounded_up_size(__rest)); + uninitialized_fill_n(__rest_buffer, __rest, __c); + _S_cond_store_eos(__rest_buffer[__rest]); + __STL_TRY { + __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a)) + } + __remainder_rope._M_tree_ptr = __remainder; + if (__exponent != 0) { + _CharT* __base_buffer = + _Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + _RopeLeaf* __base_leaf; + rope __base_rope; + uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); + _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); + __STL_TRY { + __base_leaf = _S_new_RopeLeaf(__base_buffer, + __exponentiate_threshold, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__base_buffer, + __exponentiate_threshold, __a)) + __base_rope._M_tree_ptr = __base_leaf; + if (1 == __exponent) { + __result = __base_rope; +# ifndef __GC + __stl_assert(2 == __result._M_tree_ptr->_M_ref_count); + // One each for base_rope and __result +# endif + } else { + __result = power(__base_rope, __exponent, + _Rope_Concat_fn<_CharT,_Alloc>()); + } + if (0 != __remainder) { + __result += __remainder_rope; + } + } else { + __result = __remainder_rope; + } + _M_tree_ptr = __result._M_tree_ptr; + _M_tree_ptr->_M_ref_nonnil(); +} + +template + _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; + +template +const _CharT* rope<_CharT,_Alloc>::c_str() const { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, + // but probably fast. + return _S_empty_c_str; + } + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (0 != __old_c_string) return(__old_c_string); + size_t __s = size(); + _CharT* __result = _Data_allocate(__s + 1); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); +# ifdef __GC + _M_tree_ptr->_M_c_string = __result; +# else + if ((__old_c_string = (__GC_CONST _CharT*) + _Atomic_swap((unsigned long *)(&(_M_tree_ptr->_M_c_string)), + (unsigned long)__result)) != 0) { + // It must have been added in the interim. Hence it had to have been + // separately allocated. Deallocate the old copy, since we just + // replaced it. + destroy(__old_c_string, __old_c_string + __s + 1); + _Data_deallocate(__old_c_string, __s + 1); + } +# endif + return(__result); +} + +template +const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); + return _S_empty_c_str; + } + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 0 != __old_c_string) { + return(__old_c_string); + } + size_t __s = size(); + _CharT* __result = _Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + _M_tree_ptr->_M_unref_nonnil(); + _M_tree_ptr = _S_new_RopeLeaf(__result, __s, get_allocator()); + return(__result); +} + +// Algorithm specializations. More should be added. + +template // was templated on CharT and Alloc +void // VC++ workaround +_Rope_rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) +{ + typedef typename _Rope_iterator::value_type _CharT; + typedef typename _Rope_iterator::_allocator_type _Alloc; + + __stl_assert(__first.container() == __middle.container() + && __middle.container() == __last.container()); + rope<_CharT,_Alloc>& __r(__first.container()); + rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index()); + rope<_CharT,_Alloc> __suffix = + __r.substr(__last.index(), __r.size() - __last.index()); + rope<_CharT,_Alloc> __part1 = + __r.substr(__middle.index(), __last.index() - __middle.index()); + rope<_CharT,_Alloc> __part2 = + __r.substr(__first.index(), __middle.index() - __first.index()); + __r = __prefix; + __r += __part1; + __r += __part2; + __r += __suffix; +} + +#if !defined(__GNUC__) +// Appears to confuse g++ +inline void rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); +} +#endif + +# if 0 +// Probably not useful for several reasons: +// - for SGIs 7.1 compiler and probably some others, +// this forces lots of rope instantiations, creating a +// code bloat and compile time problem. (Fixed in 7.2.) +// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive +// for unicode strings. Unsigned short may be a better character +// type. +inline void rotate( + _Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); +} +# endif + + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/sequence_concepts.h b/darkice/tags/darkice-0_2/stl/sequence_concepts.h new file mode 100644 index 0000000..bf8f373 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/sequence_concepts.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef STL_SEQUENCE_CONCEPTS_H +#define STL_SEQUENCE_CONCEPTS_H + +#include + +#ifdef __STL_USE_CONCEPT_CHECKS + +// This file covers the following concepts: +// _Sequence +// _FrontInsertionSequence +// _BackInsertionSequence + +struct _ERROR_IN_STL_SEQ { + + template + static void + __fill_constructor_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + typename _XX::difference_type __n = typename _XX::difference_type(); + _XX __x(__n, __t); + __sink_unused_warning(__x); + } + template + static void + __fill_default_constructor_requirement_violation(_XX& __s) { + _STL_ERROR::__default_constructor_requirement_violation(*__s.begin()); + typename _XX::difference_type __n = typename _XX::difference_type(); + _XX __x(__n); + __sink_unused_warning(__x); + } + template + static void + __range_constructor_requirement_violation(_XX& __s) { + _XX __x(__s.begin(), __s.end()); + __sink_unused_warning(__x); + } + template + static void + __insert_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + typename _XX::iterator __p = typename _XX::iterator(); + __p = __s.insert(__p, __t); + } + template + static void + __fill_insert_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + typename _XX::iterator __p = typename _XX::iterator(); + typename _XX::difference_type __n = typename _XX::difference_type(); + __s.insert(__p, __n, __t); + } + template + static void + __range_insert_function_requirement_violation(_XX& __s) { + typename _XX::iterator __p = typename _XX::iterator(); + typename _XX::iterator __i = typename _XX::iterator(); + typename _XX::iterator __j = typename _XX::iterator(); + __s.insert(__p, __i, __j); + } + template + static void + __insert_element_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + std::pair __r; + __r = __s.insert(__t); + __sink_unused_warning(__r); + } + template + static void + __unconditional_insert_element_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + typename _XX::iterator __p; + __p = __s.insert(__t); + __sink_unused_warning(__p); + } + template + static void + __erase_function_requirement_violation(_XX& __s) { + typename _XX::iterator __p = typename _XX::iterator(); + __p = __s.erase(__p); + } + template + static void + __range_erase_function_requirement_violation(_XX& __s) { + typename _XX::iterator __p = typename _XX::iterator(); + typename _XX::iterator __q = typename _XX::iterator(); + __p = __s.erase(__p, __q); + } + template + static void + __const_front_function_requirement_violation(const _XX& __s) { + typename _XX::const_reference __t = __s.front(); + __sink_unused_warning(__t); + } + template + static void + __front_function_requirement_violation(_XX& __s) { + typename _XX::reference __t = __s.front(); + __const_front_function_requirement_violation(__s); + __sink_unused_warning(__t); + } + template + static void + __const_back_function_requirement_violation(const _XX& __s) { + typename _XX::const_reference __t = __s.back(); + __sink_unused_warning(__t); + } + template + static void + __back_function_requirement_violation(_XX& __s) { + typename _XX::reference __t = __s.back(); + __const_back_function_requirement_violation(__s); + __sink_unused_warning(__t); + } + template + static void + __push_front_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + __s.push_front(__t); + } + template + static void + __pop_front_function_requirement_violation(_XX& __s) { + __s.pop_front(); + } + template + static void + __push_back_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + __s.push_back(__t); + } + template + static void + __pop_back_function_requirement_violation(_XX& __s) { + __s.pop_back(); + } + +}; + +/* Sequence Containers */ + +template +struct _Sequence_concept_specification { +static void +_Sequence_requirement_violation(_Sequence __s) { + // Refinement of ForwardContainer + _ForwardContainer_concept_specification<_Sequence>::_ForwardContainer_requirement_violation(__s); + // Refinement of DefaultConstructible + _DefaultConstructible_concept_specification<_Sequence>::_DefaultConstructible_requirement_violation(__s); + // Valid Expressions + _ERROR_IN_STL_SEQ::__fill_constructor_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__fill_default_constructor_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__range_constructor_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__insert_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__fill_insert_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__range_insert_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__erase_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__range_erase_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__front_function_requirement_violation(__s); +} +}; + +template +struct _FrontInsertionSequence_concept_specification { +static void +_FrontInsertionSequence_requirement_violation(_FrontInsertionSequence __s) { + // Refinement of Sequence + _Sequence_concept_specification<_FrontInsertionSequence>::_Sequence_requirement_violation(__s); + // Valid Expressions + _ERROR_IN_STL_SEQ::__push_front_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__pop_front_function_requirement_violation(__s); +} +}; + +template +struct _BackInsertionSequence_concept_specification { +static void +_BackInsertionSequence_requirement_violation(_BackInsertionSequence __s) { + // Refinement of Sequence + _Sequence_concept_specification<_BackInsertionSequence>::_Sequence_requirement_violation(__s); + // Valid Expressions + _ERROR_IN_STL_SEQ::__back_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__push_back_function_requirement_violation(__s); + _ERROR_IN_STL_SEQ::__pop_back_function_requirement_violation(__s); +} +}; + +#endif /* if __STL_USE_CONCEPT_CHECKS */ + + +#endif /* STL_SEQUENCE_CONCEPTS_H */ diff --git a/darkice/tags/darkice-0_2/stl/set b/darkice/tags/darkice-0_2/stl/set new file mode 100644 index 0000000..c836c45 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/set @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_SET +#define __SGI_STL_SET + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include + +#endif /* __SGI_STL_SET */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/set.h b/darkice/tags/darkice-0_2/stl/set.h new file mode 100644 index 0000000..779f395 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/set.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_SET_H +#define __SGI_STL_SET_H + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::rb_tree; +using __STD::set; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/slist b/darkice/tags/darkice-0_2/stl/slist new file mode 100644 index 0000000..c3ec742 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/slist @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_SLIST +#define __SGI_STL_SLIST + +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_SLIST */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/slist.h b/darkice/tags/darkice-0_2/stl/slist.h new file mode 100644 index 0000000..d2377b0 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/slist.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_SLIST_H +#define __SGI_STL_SLIST_H + +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::slist; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stack b/darkice/tags/darkice-0_2/stl/stack new file mode 100644 index 0000000..36461d9 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stack @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_STACK +#define __SGI_STL_STACK + +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_STACK */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stack.h b/darkice/tags/darkice-0_2/stl/stack.h new file mode 100644 index 0000000..89beca8 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stack.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_STACK_H +#define __SGI_STL_STACK_H + +#include +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::stack; +using __STD::queue; +using __STD::priority_queue; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stdexcept b/darkice/tags/darkice-0_2/stl/stdexcept new file mode 100644 index 0000000..ca99369 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stdexcept @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STDEXCEPT +#define __SGI_STDEXCEPT + +#include + +#if defined(__STL_USE_EXCEPTIONS) || \ + !(defined(_MIPS_SIM) && defined(_ABIO32) && _MIPS_SIM == _ABIO32) + +#include + +__STL_BEGIN_NAMESPACE + +class __Named_exception : public __STL_EXCEPTION_BASE { +public: + __Named_exception(const string& __str) { + strncpy(_M_name, __get_c_string(__str), _S_bufsize); + _M_name[_S_bufsize - 1] = '\0'; + } + virtual const char* what() const __STL_NOTHROW { return _M_name; } + +private: + enum { _S_bufsize = 256 }; + char _M_name[_S_bufsize]; +}; + +class logic_error : public __Named_exception { +public: + logic_error(const string& __s) : __Named_exception(__s) {} +}; + +class runtime_error : public __Named_exception { +public: + runtime_error(const string& __s) : __Named_exception(__s) {} +}; + +class domain_error : public logic_error { +public: + domain_error(const string& __arg) : logic_error(__arg) {} +}; + +class invalid_argument : public logic_error { +public: + invalid_argument(const string& __arg) : logic_error(__arg) {} +}; + +class length_error : public logic_error { +public: + length_error(const string& __arg) : logic_error(__arg) {} +}; + +class out_of_range : public logic_error { +public: + out_of_range(const string& __arg) : logic_error(__arg) {} +}; + +class range_error : public runtime_error { +public: + range_error(const string& __arg) : runtime_error(__arg) {} +}; + +class overflow_error : public runtime_error { +public: + overflow_error(const string& __arg) : runtime_error(__arg) {} +}; + +class underflow_error : public runtime_error { +public: + underflow_error(const string& __arg) : runtime_error(__arg) {} +}; + +__STL_END_NAMESPACE + +#ifndef __SGI_STL_STRING +#include +#endif + +#endif /* Not o32, and no exceptions */ + +#endif /* __SGI_STDEXCEPT */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_algo.h b/darkice/tags/darkice-0_2/stl/stl_algo.h new file mode 100644 index 0000000..37dbf4a --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_algo.h @@ -0,0 +1,3297 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_ALGO_H +#define __SGI_STL_INTERNAL_ALGO_H + +#include + +// See concept_checks.h for the concept-checking macros +// __STL_REQUIRES, __STL_CONVERTIBLE, etc. + + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +// __median (an extension, not present in the C++ standard). + +template +inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { + __STL_REQUIRES(_Tp, _LessThanComparable); + if (__a < __b) + if (__b < __c) + return __b; + else if (__a < __c) + return __c; + else + return __a; + else if (__a < __c) + return __a; + else if (__b < __c) + return __c; + else + return __b; +} + +template +inline const _Tp& +__median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); + if (__comp(__a, __b)) + if (__comp(__b, __c)) + return __b; + else if (__comp(__a, __c)) + return __c; + else + return __a; + else if (__comp(__a, __c)) + return __a; + else if (__comp(__b, __c)) + return __c; + else + return __b; +} + +// for_each. Apply a function to every element of a range. +template +_Function for_each(_InputIter __first, _InputIter __last, _Function __f) { + __STL_REQUIRES(_InputIter, _InputIterator); + for ( ; __first != __last; ++__first) + __f(*__first); + return __f; +} + +// find and find_if. + +template +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val, + input_iterator_tag) +{ + while (__first != __last && !(*__first == __val)) + ++__first; + return __first; +} + +template +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred, + input_iterator_tag) +{ + while (__first != __last && !__pred(*__first)) + ++__first; + return __first; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +_RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last, + const _Tp& __val, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (*__first == __val) return __first; + ++__first; + case 2: + if (*__first == __val) return __first; + ++__first; + case 1: + if (*__first == __val) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +template +_RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last, + _Predicate __pred, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (__pred(*__first)) return __first; + ++__first; + case 2: + if (__pred(*__first)) return __first; + ++__first; + case 1: + if (__pred(*__first)) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val) +{ + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_InputIter>::value_type, _Tp); + return find(__first, __last, __val, __ITERATOR_CATEGORY(__first)); +} + +template +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_InputIter>::value_type); + return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); +} + +// adjacent_find. + +template +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, + _EqualityComparable); + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (*__first == *__next) + return __first; + __first = __next; + } + return __last; +} + +template +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, + typename iterator_traits<_ForwardIter>::value_type, + typename iterator_traits<_ForwardIter>::value_type); + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; + } + return __last; +} + +// count and count_if. There are two version of each, one whose return type +// type is void and one (present only if we have partial specialization) +// whose return type is iterator_traits<_InputIter>::difference_type. The +// C++ standard only has the latter version, but the former, which was present +// in the HP STL, is retained for backward compatibility. + +template +void count(_InputIter __first, _InputIter __last, const _Tp& __value, + _Size& __n) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, + _EqualityComparable); + __STL_REQUIRES(_Tp, _EqualityComparable); + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; +} + +template +void count_if(_InputIter __first, _InputIter __last, _Predicate __pred, + _Size& __n) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_InputIter>::value_type); + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +typename iterator_traits<_InputIter>::difference_type +count(_InputIter __first, _InputIter __last, const _Tp& __value) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, + _EqualityComparable); + __STL_REQUIRES(_Tp, _EqualityComparable); + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + return __n; +} + +template +typename iterator_traits<_InputIter>::difference_type +count_if(_InputIter __first, _InputIter __last, _Predicate __pred) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_InputIter>::value_type); + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + return __n; +} + + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// search. + +template +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2) +{ + __STL_REQUIRES(_ForwardIter1, _ForwardIterator); + __STL_REQUIRES(_ForwardIter2, _ForwardIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_ForwardIter1>::value_type, + typename iterator_traits<_ForwardIter2>::value_type); + + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return find(__first1, __last1, *__first2); + + // General case. + + _ForwardIter2 __p1, __p; + + __p1 = __first2; ++__p1; + + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + __first1 = find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (*__current == *__p) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + + ++__first1; + } + return __first1; +} + +template +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + _BinaryPred __predicate) +{ + __STL_REQUIRES(_ForwardIter1, _ForwardIterator); + __STL_REQUIRES(_ForwardIter2, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, + typename iterator_traits<_ForwardIter1>::value_type, + typename iterator_traits<_ForwardIter2>::value_type); + + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) { + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + return __first1; + } + + // General case. + + _ForwardIter2 __p1, __p; + + __p1 = __first2; ++__p1; + + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + while (__first1 != __last1) { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; + } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) return __last1; + + while (__predicate(*__current, *__p)) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + + ++__first1; + } + return __first1; +} + +// search_n. Search for __count consecutive copies of __val. + +template +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, + _EqualityComparable); + __STL_REQUIRES(_Tp, _EqualityComparable); + + if (__count <= 0) + return __first; + else { + __first = find(__first, __last, __val); + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && *__i == __val) { + ++__i; + --__n; + } + if (__n == 0) + return __first; + else + __first = find(__i, __last, __val); + } + return __last; + } +} + +template +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val, + _BinaryPred __binary_pred) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, + typename iterator_traits<_ForwardIter>::value_type, _Tp); + if (__count <= 0) + return __first; + else { + while (__first != __last) { + if (__binary_pred(*__first, __val)) + break; + ++__first; + } + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { + ++__i; + --__n; + } + if (__n == 0) + return __first; + else { + while (__i != __last) { + if (__binary_pred(*__i, __val)) + break; + ++__i; + } + __first = __i; + } + } + return __last; + } +} + +// swap_ranges + +template +_ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2) { + __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator); + __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator); + __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type, + typename iterator_traits<_ForwardIter2>::value_type); + __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type, + typename iterator_traits<_ForwardIter1>::value_type); + for ( ; __first1 != __last1; ++__first1, ++__first2) + iter_swap(__first1, __first2); + return __first2; +} + +// transform + +template +_OutputIter transform(_InputIter __first, _InputIter __last, + _OutputIter __result, _UnaryOperation __opr) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + + for ( ; __first != __last; ++__first, ++__result) + *__result = __opr(*__first); + return __result; +} + +template +_OutputIter transform(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _OutputIter __result, + _BinaryOperation __binary_op) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; +} + +// replace, replace_if, replace_copy, replace_copy_if + +template +void replace(_ForwardIter __first, _ForwardIter __last, + const _Tp& __old_value, const _Tp& __new_value) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_ForwardIter>::value_type, _Tp); + __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); + for ( ; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; +} + +template +void replace_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, const _Tp& __new_value) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_ForwardIter>::value_type); + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; +} + +template +_OutputIter replace_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + const _Tp& __old_value, const _Tp& __new_value) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_InputIter>::value_type, _Tp); + for ( ; __first != __last; ++__first, ++__result) + *__result = *__first == __old_value ? __new_value : *__first; + return __result; +} + +template +_OutputIter replace_copy_if(_InputIter __first, _InputIter __last, + _OutputIter __result, + _Predicate __pred, const _Tp& __new_value) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_InputIter>::value_type); + for ( ; __first != __last; ++__first, ++__result) + *__result = __pred(*__first) ? __new_value : *__first; + return __result; +} + +// generate and generate_n + +template +void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_GENERATOR_CHECK(_Generator, + typename iterator_traits<_ForwardIter>::value_type); + for ( ; __first != __last; ++__first) + *__first = __gen(); +} + +template +_OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) { + __STL_REQUIRES(_OutputIter, _OutputIterator); + for ( ; __n > 0; --__n, ++__first) + *__first = __gen(); + return __first; +} + +// remove, remove_if, remove_copy, remove_copy_if + +template +_OutputIter remove_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, const _Tp& __value) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_InputIter>::value_type, _Tp); + for ( ; __first != __last; ++__first) + if (!(*__first == __value)) { + *__result = *__first; + ++__result; + } + return __result; +} + +template +_OutputIter remove_copy_if(_InputIter __first, _InputIter __last, + _OutputIter __result, _Predicate __pred) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_InputIter>::value_type); + for ( ; __first != __last; ++__first) + if (!__pred(*__first)) { + *__result = *__first; + ++__result; + } + return __result; +} + +template +_ForwardIter remove(_ForwardIter __first, _ForwardIter __last, + const _Tp& __value) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_ForwardIter>::value_type, _Tp); + __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); + __first = find(__first, __last, __value); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy(++__i, __last, __first, __value); +} + +template +_ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_ForwardIter>::value_type); + __first = find_if(__first, __last, __pred); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy_if(++__i, __last, __first, __pred); +} + +// unique and unique_copy + +template +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, _Tp*) { + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (!(__value == *__first)) { + __value = *__first; + *++__result = __value; + } + return ++__result; +} + +template +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first)); +} + +template +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, forward_iterator_tag) { + *__result = *__first; + while (++__first != __last) + if (!(*__result == *__first)) + *++__result = *__first; + return ++__result; +} + +template +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, + _EqualityComparable); + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, + __ITERATOR_CATEGORY(__result)); +} + +template +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, _Tp*) { + __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, _Tp, _Tp); + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (!__binary_pred(__value, *__first)) { + __value = *__first; + *++__result = __value; + } + return ++__result; +} + +template +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __binary_pred, + __VALUE_TYPE(__first)); +} + +template +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, + _BinaryPredicate __binary_pred, + forward_iterator_tag) { + __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, + typename iterator_traits<_ForwardIter>::value_type, + typename iterator_traits<_InputIter>::value_type); + *__result = *__first; + while (++__first != __last) + if (!__binary_pred(*__result, *__first)) *++__result = *__first; + return ++__result; +} + +template +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, __binary_pred, + __ITERATOR_CATEGORY(__result)); +} + +template +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, + _EqualityComparable); + __first = adjacent_find(__first, __last); + return unique_copy(__first, __last, __first); +} + +template +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, + typename iterator_traits<_ForwardIter>::value_type, + typename iterator_traits<_ForwardIter>::value_type); + __first = adjacent_find(__first, __last, __binary_pred); + return unique_copy(__first, __last, __first, __binary_pred); +} + +// reverse and reverse_copy, and their auxiliary functions + +template +void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, + bidirectional_iterator_tag) { + while (true) + if (__first == __last || __first == --__last) + return; + else + iter_swap(__first++, __last); +} + +template +void __reverse(_RandomAccessIter __first, _RandomAccessIter __last, + random_access_iterator_tag) { + while (__first < __last) + iter_swap(__first++, --__last); +} + +template +inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) { + __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); + __reverse(__first, __last, __ITERATOR_CATEGORY(__first)); +} + +template +_OutputIter reverse_copy(_BidirectionalIter __first, + _BidirectionalIter __last, + _OutputIter __result) { + __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + while (__first != __last) { + --__last; + *__result = *__last; + ++__result; + } + return __result; +} + +// rotate and rotate_copy, and their auxiliary functions + +template +_EuclideanRingElement __gcd(_EuclideanRingElement __m, + _EuclideanRingElement __n) +{ + while (__n != 0) { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; + } + return __m; +} + +template +_ForwardIter __rotate(_ForwardIter __first, + _ForwardIter __middle, + _ForwardIter __last, + _Distance*, + forward_iterator_tag) { + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + _ForwardIter __first2 = __middle; + do { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + } while (__first2 != __last); + + _ForwardIter __new_middle = __first; + + __first2 = __middle; + + while (__first2 != __last) { + swap (*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } + + return __new_middle; +} + + +template +_BidirectionalIter __rotate(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance*, + bidirectional_iterator_tag) { + __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + __reverse(__first, __middle, bidirectional_iterator_tag()); + __reverse(__middle, __last, bidirectional_iterator_tag()); + + while (__first != __middle && __middle != __last) + swap (*__first++, *--__last); + + if (__first == __middle) { + __reverse(__middle, __last, bidirectional_iterator_tag()); + return __last; + } + else { + __reverse(__first, __middle, bidirectional_iterator_tag()); + return __first; + } +} + +template +_RandomAccessIter __rotate(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, + _Distance *, _Tp *) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + _Distance __n = __last - __first; + _Distance __k = __middle - __first; + _Distance __l = __n - __k; + _RandomAccessIter __result = __first + (__last - __middle); + + if (__k == 0) + return __last; + + else if (__k == __l) { + swap_ranges(__first, __middle, __middle); + return __result; + } + + _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) { + _Tp __tmp = *__first; + _RandomAccessIter __p = __first; + + if (__k < __l) { + for (_Distance __j = 0; __j < __l/__d; __j++) { + if (__p > __first + __l) { + *__p = *(__p - __l); + __p -= __l; + } + + *__p = *(__p + __k); + __p += __k; + } + } + + else { + for (_Distance __j = 0; __j < __k/__d - 1; __j ++) { + if (__p < __last - __k) { + *__p = *(__p + __k); + __p += __k; + } + + *__p = * (__p - __l); + __p -= __l; + } + } + + *__p = __tmp; + ++__first; + } + + return __result; +} + +template +inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __last) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + return __rotate(__first, __middle, __last, + __DISTANCE_TYPE(__first), + __ITERATOR_CATEGORY(__first)); +} + +template +_OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __last, _OutputIter __result) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + return copy(__first, __middle, copy(__middle, __last, __result)); +} + +// Return a random number in the range [0, __n). This function encapsulates +// whether we're using rand (part of the standard C library) or lrand48 +// (not standard, but a much better choice whenever it's available). + +template +inline _Distance __random_number(_Distance __n) { +#ifdef __STL_NO_DRAND48 + return rand() % __n; +#else + return lrand48() % __n; +#endif +} + +// random_shuffle + +template +inline void random_shuffle(_RandomAccessIter __first, + _RandomAccessIter __last) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __random_number((__i - __first) + 1)); +} + +template +void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, + _RandomNumberGenerator& __rand) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __rand((__i - __first) + 1)); +} + +// random_sample and random_sample_n (extensions, not part of the standard). + +template +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n) +{ + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if (__random_number(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; +} + +template +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n, + _RandomNumberGenerator& __rand) +{ + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance); + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if (__rand(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; +} + +template +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + const _Distance __n) +{ + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = __random_number(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; +} + +template +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + _RandomNumberGenerator& __rand, + const _Distance __n) +{ + __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance); + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = __rand(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; +} + +template +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last) +{ + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + return __random_sample(__first, __last, + __out_first, __out_last - __out_first); +} + + +template +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last, + _RandomNumberGenerator& __rand) +{ + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + return __random_sample(__first, __last, + __out_first, __rand, + __out_last - __out_first); +} + +// partition, stable_partition, and their auxiliary functions + +template +_ForwardIter __partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, + forward_iterator_tag) { + if (__first == __last) return __first; + + while (__pred(*__first)) + if (++__first == __last) return __first; + + _ForwardIter __next = __first; + + while (++__next != __last) + if (__pred(*__next)) { + swap(*__first, *__next); + ++__first; + } + + return __first; +} + +template +_BidirectionalIter __partition(_BidirectionalIter __first, + _BidirectionalIter __last, + _Predicate __pred, + bidirectional_iterator_tag) { + while (true) { + while (true) + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; + else + break; + --__last; + while (true) + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; + else + break; + iter_swap(__first, __last); + ++__first; + } +} + +template +inline _ForwardIter partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_ForwardIter>::value_type); + return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); +} + + +template +_ForwardIter __inplace_stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len) { + if (__len == 1) + return __pred(*__first) ? __last : __first; + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__inplace_stable_partition(__first, __middle, __pred, + __len / 2), + __middle, + __inplace_stable_partition(__middle, __last, __pred, + __len - __len / 2)); +} + +template +_ForwardIter __stable_partition_adaptive(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) +{ + if (__len <= __buffer_size) { + _ForwardIter __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) { + *__result1 = *__first; + ++__result1; + } + else { + *__result2 = *__first; + ++__result2; + } + copy(__buffer, __result2, __result1); + return __result1; + } + else { + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__stable_partition_adaptive( + __first, __middle, __pred, + __len / 2, __buffer, __buffer_size), + __middle, + __stable_partition_adaptive( + __middle, __last, __pred, + __len - __len / 2, __buffer, __buffer_size)); + } +} + +template +inline _ForwardIter +__stable_partition_aux(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, _Tp*, _Distance*) +{ + _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); + if (__buf.size() > 0) + return __stable_partition_adaptive(__first, __last, __pred, + _Distance(__buf.requested_size()), + __buf.begin(), __buf.size()); + else + return __inplace_stable_partition(__first, __last, __pred, + _Distance(__buf.requested_size())); +} + +template +inline _ForwardIter stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, + typename iterator_traits<_ForwardIter>::value_type); + if (__first == __last) + return __first; + else + return __stable_partition_aux(__first, __last, __pred, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); +} + +template +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot) +{ + while (true) { + while (*__first < __pivot) + ++__first; + --__last; + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; + } +} + +template +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot, _Compare __comp) +{ + while (true) { + while (__comp(*__first, __pivot)) + ++__first; + --__last; + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; + } +} + +const int __stl_threshold = 16; + +// sort() and its auxiliary functions. + +template +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { + _RandomAccessIter __next = __last; + --__next; + while (__val < *__next) { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; +} + +template +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, + _Compare __comp) { + _RandomAccessIter __next = __last; + --__next; + while (__comp(__val, *__next)) { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; +} + +template +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + _Tp __val = *__last; + if (__val < *__first) { + copy_backward(__first, __last, __last + 1); + *__first = __val; + } + else + __unguarded_linear_insert(__last, __val); +} + +template +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + _Tp __val = *__last; + if (__comp(__val, *__first)) { + copy_backward(__first, __last, __last + 1); + *__first = __val; + } + else + __unguarded_linear_insert(__last, __val, __comp); +} + +template +void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first)); +} + +template +void __insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp); +} + +template +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i)); +} + +template +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first)); +} + +template +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp*, _Compare __comp) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i), __comp); +} + +template +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Compare __comp) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first), + __comp); +} + +template +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold); + __unguarded_insertion_sort(__first + __stl_threshold, __last); + } + else + __insertion_sort(__first, __last); +} + +template +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold, __comp); + __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); + } + else + __insertion_sort(__first, __last, __comp); +} + +template +inline _Size __lg(_Size __n) { + _Size __k; + for (__k = 0; __n != 1; __n >>= 1) ++__k; + return __k; +} + +template +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last); + return; + } + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit); + __last = __cut; + } +} + +template +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit, _Compare __comp) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last, __comp); + return; + } + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), __comp)), + __comp); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); + __last = __cut; + } +} + +template +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, + _LessThanComparable); + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2); + __final_insertion_sort(__first, __last); + } +} + +template +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last, + _Compare __comp) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_RandomAccessIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2, + __comp); + __final_insertion_sort(__first, __last, __comp); + } +} + +// stable_sort() and its auxiliary functions. + +template +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first < 15) { + __insertion_sort(__first, __last); + return; + } + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle); + __inplace_stable_sort(__middle, __last); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); +} + +template +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first < 15) { + __insertion_sort(__first, __last, __comp); + return; + } + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle, __comp); + __inplace_stable_sort(__middle, __last, __comp); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); +} + +template +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size) { + _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; + } + + __step_size = min(_Distance(__last - __first), __step_size); + merge(__first, __first + __step_size, __first + __step_size, __last, + __result); +} + +template +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size, + _Compare __comp) { + _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; + } + __step_size = min(_Distance(__last - __first), __step_size); + + merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); +} + +const int __stl_chunk_size = 7; + +template +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Distance __chunk_size) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + __insertion_sort(__first, __last); +} + +template +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Distance __chunk_size, _Compare __comp) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; + } + __insertion_sort(__first, __last, __comp); +} + +template +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, + _Pointer __buffer, _Distance*) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; + } +} + +template +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance*, _Compare __comp) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size, __comp); + + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); + __step_size *= 2; + } +} + +template +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size); + } + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size); +} + +template +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size, _Compare __comp) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, + __comp); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, + __comp); + } + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, + __comp); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, + __comp); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size, + __comp); +} + +template +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size())); +} + +template +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last, __comp); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size()), + __comp); +} + +template +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, + _LessThanComparable); + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); +} + +template +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_RandomAccessIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first), + __comp); +} + +// partial_sort, partial_sort_copy, and auxiliary functions. + +template +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*) { + make_heap(__first, __middle); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (*__i < *__first) + __pop_heap(__first, __middle, __i, _Tp(*__i), + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle); +} + +template +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, + _LessThanComparable); + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first)); +} + +template +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + make_heap(__first, __middle, __comp); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle, __comp); +} + +template +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, _Compare __comp) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_RandomAccessIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp); +} + +template +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last); + while (__first != __last) { + if (*__first < *__result_first) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first)); + ++__first; + } + sort_heap(__result_first, __result_real_last); + return __result_real_last; +} + +template +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, + _LessThanComparable); + __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, + _LessThanComparable); + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +template +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Compare __comp, _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) { + if (__comp(*__first, *__result_first)) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first), + __comp); + ++__first; + } + sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; +} + +template +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, _Compare __comp) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_RandomAccessIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __comp, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +// nth_element() and its auxiliary functions. + +template +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + __insertion_sort(__first, __last); +} + +template +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, + _LessThanComparable); + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first)); +} + +template +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), + __comp)), + __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + __insertion_sort(__first, __last, __comp); +} + +template +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Compare __comp) { + __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_RandomAccessIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp); +} + + +// Binary search (lower_bound, upper_bound, equal_range, binary_search). + +template +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; +} + +template +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_REQUIRES(_Tp, _LessThanComparable); + return __lower_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} + +template +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; +} + +template +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); + return __lower_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} + +template +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__val < *__middle) + __len = __half; + else { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; +} + +template +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_REQUIRES(_Tp, _LessThanComparable); + return __upper_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} + +template +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; + else { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; +} + +template +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); + return __upper_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} + +template +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; + else { + __left = lower_bound(__first, __middle, __val); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val); + return pair<_ForwardIter, _ForwardIter>(__left, __right); + } + } + return pair<_ForwardIter, _ForwardIter>(__first, __first); +} + +template +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_REQUIRES(_Tp, _LessThanComparable); + return __equal_range(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} + +template +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; + else { + __left = lower_bound(__first, __middle, __val, __comp); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIter, _ForwardIter>(__left, __right); + } + } + return pair<_ForwardIter, _ForwardIter>(__first, __first); +} + +template +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); + return __equal_range(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} + +template +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_REQUIRES(_Tp, _LessThanComparable); + _ForwardIter __i = lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__i); +} + +template +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, + _Compare __comp) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_SAME_TYPE(_Tp, + typename iterator_traits<_ForwardIter>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); + _ForwardIter __i = lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); +} + +// merge, with and without an explicitly supplied comparison function. + +template +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + while (__first1 != __last1 && __first2 != __last2) { + if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter1>::value_type); + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +// inplace_merge and its auxiliary functions. + +template +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (*__middle < *__first) + iter_swap(__first, __middle); + return; + } + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22); +} + +template +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Compare __comp) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (__comp(*__middle, *__first)) + iter_swap(__first, __middle); + return; + } + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, + __comp); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __comp); +} + +template +_BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, + _BidirectionalIter1 __middle, + _BidirectionalIter1 __last, + _Distance __len1, _Distance __len2, + _BidirectionalIter2 __buffer, + _Distance __buffer_size) { + _BidirectionalIter2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) { + __buffer_end = copy(__middle, __last, __buffer); + copy_backward(__first, __middle, __last); + return copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) { + __buffer_end = copy(__first, __middle, __buffer); + copy(__middle, __last, __first); + return copy_backward(__buffer, __buffer_end, __last); + } + else + return rotate(__first, __middle, __last); +} + +template +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) { + if (*__last2 < *__last1) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; + } + else { + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; + } + } +} + +template +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result, + _Compare __comp) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) { + if (__comp(*__last2, *__last1)) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; + } + else { + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; + } + } +} + +template +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first); + } + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last); + } + else { + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } +} + +template +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last, + __comp); + } + else { + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size, __comp); + } +} + +template +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2); + else + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size())); +} + +template +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); + else + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size()), + __comp); +} + +template +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last) { + __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); + __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, + _LessThanComparable); + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} + +template +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Compare __comp) { + __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_BidirectionalIter>::value_type, + typename iterator_traits<_BidirectionalIter>::value_type); + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), + __comp); +} + +// Set algorithms: includes, set_union, set_intersection, set_difference, +// set_symmetric_difference. All of these algorithms have the precondition +// that their input ranges are sorted and the postcondition that their output +// ranges are sorted. + +template +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + return false; + else if(*__first1 < *__first2) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; +} + +template +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + return false; + else if(__comp(*__first1, *__first2)) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; +} + +template +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + } + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + } + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + ++__first1; + else if (*__first2 < *__first1) + ++__first2; + else { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + ++__first1; + else if (__comp(*__first2, *__first1)) + ++__first2; + else { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + ++__first2; + else { + ++__first1; + ++__first2; + } + return copy(__first1, __last1, __result); +} + +template +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + ++__first2; + else { + ++__first1; + ++__first2; + } + return copy(__first1, __last1, __result); +} + +template +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + ++__result; + } + else { + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, + _Compare __comp) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + __STL_REQUIRES_SAME_TYPE( + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_InputIter1>::value_type, + typename iterator_traits<_InputIter2>::value_type); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + ++__result; + } + else { + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +// min_element and max_element, with and without an explicitly supplied +// comparison function. + +template +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, + _LessThanComparable); + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__result < *__first) + __result = __first; + return __result; +} + +template +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_ForwardIter>::value_type, + typename iterator_traits<_ForwardIter>::value_type); + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__result, *__first)) __result = __first; + return __result; +} + +template +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, + _LessThanComparable); + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__first < *__result) + __result = __first; + return __result; +} + +template +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_ForwardIter>::value_type, + typename iterator_traits<_ForwardIter>::value_type); + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__first, *__result)) + __result = __first; + return __result; +} + +// next_permutation and prev_permutation, with and without an explicitly +// supplied comparison function. + +template +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); + __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, + _LessThanComparable); + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (*__i < *__ii) { + _BidirectionalIter __j = __last; + while (!(*__i < *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +template +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_BidirectionalIter>::value_type, + typename iterator_traits<_BidirectionalIter>::value_type); + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__i, *__ii)) { + _BidirectionalIter __j = __last; + while (!__comp(*__i, *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +template +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); + __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, + _LessThanComparable); + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (*__ii < *__i) { + _BidirectionalIter __j = __last; + while (!(*--__j < *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +template +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); + __STL_BINARY_FUNCTION_CHECK(_Compare, bool, + typename iterator_traits<_BidirectionalIter>::value_type, + typename iterator_traits<_BidirectionalIter>::value_type); + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__ii, *__i)) { + _BidirectionalIter __j = __last; + while (!__comp(*--__j, *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +// find_first_of, with and without an explicitly supplied comparison function. + +template +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2) +{ + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_InputIter>::value_type, + typename iterator_traits<_ForwardIter>::value_type); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (*__first1 == *__iter) + return __first1; + return __last1; +} + +template +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + _BinaryPredicate __comp) +{ + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, + typename iterator_traits<_InputIter>::value_type, + typename iterator_traits<_ForwardIter>::value_type); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (__comp(*__first1, *__iter)) + return __first1; + return __last1; +} + + +// find_end, with and without an explicitly supplied comparison function. +// Search [first2, last2) as a subsequence in [first1, last1), and return +// the *last* possible match. Note that find_end for bidirectional iterators +// is much faster than for forward iterators. + +// find_end for forward iterators. +template +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag) +{ + if (__first2 == __last2) + return __last1; + else { + _ForwardIter1 __result = __last1; + while (1) { + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; + else { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } +} + +template +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag, + _BinaryPredicate __comp) +{ + if (__first2 == __last2) + return __last1; + else { + _ForwardIter1 __result = __last1; + while (1) { + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; + else { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } +} + +// find_end for bidirectional iterators. Requires partial specialization. +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag) +{ + __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); + __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; + + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2); + + if (__rresult == __rlast1) + return __last1; + else { + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; + } +} + +template +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag, + _BinaryPredicate __comp) +{ + __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); + __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; + + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2, + __comp); + + if (__rresult == __rlast1) + return __last1; + else { + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; + } +} +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Dispatching functions for find_end. + +template +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2) +{ + __STL_REQUIRES(_ForwardIter1, _ForwardIterator); + __STL_REQUIRES(_ForwardIter2, _ForwardIterator); + __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, + typename iterator_traits<_ForwardIter1>::value_type, + typename iterator_traits<_ForwardIter2>::value_type); + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2)); +} + +template +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + _BinaryPredicate __comp) +{ + __STL_REQUIRES(_ForwardIter1, _ForwardIterator); + __STL_REQUIRES(_ForwardIter2, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, + typename iterator_traits<_ForwardIter1>::value_type, + typename iterator_traits<_ForwardIter2>::value_type); + + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2), + __comp); +} + +// is_heap, a predicate testing whether or not a range is +// a heap. This function is an extension, not part of the C++ +// standard. + +template +bool __is_heap(_RandomAccessIter __first, _Distance __n) +{ + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__first[__parent] < __first[__child]) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; +} + +template +bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp, + _Distance __n) +{ + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__comp(__first[__parent], __first[__child])) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; +} + +template +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last) +{ + __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, + _LessThanComparable); + return __is_heap(__first, __last - __first); +} + + +template +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last, + _StrictWeakOrdering __comp) +{ + __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator); + __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool, + typename iterator_traits<_RandomAccessIter>::value_type, + typename iterator_traits<_RandomAccessIter>::value_type); + return __is_heap(__first, __comp, __last - __first); +} + +// is_sorted, a predicated testing whether a range is sorted in +// nondescending order. This is an extension, not part of the C++ +// standard. + +template +bool is_sorted(_ForwardIter __first, _ForwardIter __last) +{ + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, + _LessThanComparable); + if (__first == __last) + return true; + + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; +} + +template +bool is_sorted(_ForwardIter __first, _ForwardIter __last, + _StrictWeakOrdering __comp) +{ + __STL_REQUIRES(_ForwardIter, _ForwardIterator); + __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool, + typename iterator_traits<_ForwardIter>::value_type, + typename iterator_traits<_ForwardIter>::value_type); + if (__first == __last) + return true; + + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__comp(*__next, *__first)) + return false; + } + + return true; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ALGO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_algobase.h b/darkice/tags/darkice-0_2/stl/stl_algobase.h new file mode 100644 index 0000000..35ed7ec --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_algobase.h @@ -0,0 +1,696 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + + +#ifndef __SGI_STL_INTERNAL_ALGOBASE_H +#define __SGI_STL_INTERNAL_ALGOBASE_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include +#endif +#ifndef __TYPE_TRAITS_H +#include +#endif + +#include +#include +#include +#include +#include + +#ifdef __STL_USE_NEW_IOSTREAMS +#include +#else /* __STL_USE_NEW_IOSTREAMS */ +#include +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#include +#include +#endif + +// We pick up concept_checks.h from stl_iterator_base.h. + +__STL_BEGIN_NAMESPACE + +// swap and iter_swap + +template +inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) { + _Tp __tmp = *__a; + *__a = *__b; + *__b = __tmp; +} + +template +inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) { + __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator); + __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator); + __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type, + typename iterator_traits<_ForwardIter2>::value_type); + __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type, + typename iterator_traits<_ForwardIter1>::value_type); + __iter_swap(__a, __b, __VALUE_TYPE(__a)); +} + +template +inline void swap(_Tp& __a, _Tp& __b) { + __STL_REQUIRES(_Tp, _Assignable); + _Tp __tmp = __a; + __a = __b; + __b = __tmp; +} + +//-------------------------------------------------- +// min and max + +#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */ + +#undef min +#undef max + +template +inline const _Tp& min(const _Tp& __a, const _Tp& __b) { + __STL_REQUIRES(_Tp, _LessThanComparable); + return __b < __a ? __b : __a; +} + +template +inline const _Tp& max(const _Tp& __a, const _Tp& __b) { + __STL_REQUIRES(_Tp, _LessThanComparable); + return __a < __b ? __b : __a; +} + +#endif /* __BORLANDC__ */ + +template +inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? __b : __a; +} + +template +inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__a, __b) ? __b : __a; +} + +//-------------------------------------------------- +// copy + +// All of these auxiliary functions serve two purposes. (1) Replace +// calls to copy with memmove whenever possible. (Memmove, not memcpy, +// because the input and output ranges are permitted to overlap.) +// (2) If we're using random access iterators, then write the loop as +// a for loop with an explicit count. + +template +inline _OutputIter __copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + input_iterator_tag, _Distance*) +{ + for ( ; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; +} + +template +inline _OutputIter +__copy(_RandomAccessIter __first, _RandomAccessIter __last, + _OutputIter __result, random_access_iterator_tag, _Distance*) +{ + for (_Distance __n = __last - __first; __n > 0; --__n) { + *__result = *__first; + ++__first; + ++__result; + } + return __result; +} + +template +inline _Tp* +__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) { + memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + return __result + (__last - __first); +} + +#if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) + +template +inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last, + _OutputIter __result, __false_type) { + return __copy(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); +} + +template +inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last, + _OutputIter __result, __true_type) { + return __copy(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); +} + +#ifndef __USLC__ + +template +inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, + __true_type) { + return __copy_trivial(__first, __last, __result); +} + +#endif /* __USLC__ */ + +template +inline _Tp* __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result, + __true_type) { + return __copy_trivial(__first, __last, __result); +} + + +template +inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last, + _OutputIter __result, _Tp*) { + typedef typename __type_traits<_Tp>::has_trivial_assignment_operator + _Trivial; + return __copy_aux2(__first, __last, __result, _Trivial()); +} + +template +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first)); +} + +// Hack for compilers that don't have partial ordering of function templates +// but do have partial specialization of class templates. +#elif defined(__STL_CLASS_PARTIAL_SPECIALIZATION) + +template +struct __copy_dispatch { + static _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + typedef typename iterator_traits<_InputIter>::difference_type _Distance; + return __copy(__first, __last, __result, _Category(), (_Distance*) 0); + } +}; + +template +struct __copy_dispatch<_Tp*, _Tp*, __true_type> +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); + } +}; + +template +struct __copy_dispatch +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); + } +}; + +template +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + typedef typename iterator_traits<_InputIter>::value_type _Tp; + typedef typename __type_traits<_Tp>::has_trivial_assignment_operator + _Trivial; + return __copy_dispatch<_InputIter, _OutputIter, _Trivial> + ::copy(__first, __last, __result); +} + +// Fallback for compilers with neither partial ordering nor partial +// specialization. Define the faster version for the basic builtin +// types. +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) +{ + return __copy(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); +} + +#define __SGI_STL_DECLARE_COPY_TRIVIAL(_Tp) \ + inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { \ + memmove(__result, __first, sizeof(_Tp) * (__last - __first)); \ + return __result + (__last - __first); \ + } + +__SGI_STL_DECLARE_COPY_TRIVIAL(char) +__SGI_STL_DECLARE_COPY_TRIVIAL(signed char) +__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned char) +__SGI_STL_DECLARE_COPY_TRIVIAL(short) +__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned short) +__SGI_STL_DECLARE_COPY_TRIVIAL(int) +__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned int) +__SGI_STL_DECLARE_COPY_TRIVIAL(long) +__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long) +#ifdef __STL_HAS_WCHAR_T +__SGI_STL_DECLARE_COPY_TRIVIAL(wchar_t) +#endif +#ifdef _STL_LONG_LONG +__SGI_STL_DECLARE_COPY_TRIVIAL(long long) +__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long long) +#endif +__SGI_STL_DECLARE_COPY_TRIVIAL(float) +__SGI_STL_DECLARE_COPY_TRIVIAL(double) +__SGI_STL_DECLARE_COPY_TRIVIAL(long double) + +#undef __SGI_STL_DECLARE_COPY_TRIVIAL +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +//-------------------------------------------------- +// copy_backward + +template +inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result, + bidirectional_iterator_tag, + _Distance*) +{ + while (__first != __last) + *--__result = *--__last; + return __result; +} + +template +inline _BidirectionalIter __copy_backward(_RandomAccessIter __first, + _RandomAccessIter __last, + _BidirectionalIter __result, + random_access_iterator_tag, + _Distance*) +{ + for (_Distance __n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +// This dispatch class is a workaround for compilers that do not +// have partial ordering of function templates. All we're doing is +// creating a specialization so that we can turn a call to copy_backward +// into a memmove whenever possible. + +template +struct __copy_backward_dispatch +{ + typedef typename iterator_traits<_BidirectionalIter1>::iterator_category + _Cat; + typedef typename iterator_traits<_BidirectionalIter1>::difference_type + _Distance; + + static _BidirectionalIter2 copy(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result) { + return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0); + } +}; + +template +struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + const ptrdiff_t _Num = __last - __first; + memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; + } +}; + +template +struct __copy_backward_dispatch +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + ::copy(__first, __last, __result); + } +}; + +template +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + __STL_REQUIRES(_BI1, _BidirectionalIterator); + __STL_REQUIRES(_BI2, _Mutable_BidirectionalIterator); + __STL_CONVERTIBLE(typename iterator_traits<_BI1>::value_type, + typename iterator_traits<_BI2>::value_type); + typedef typename __type_traits::value_type> + ::has_trivial_assignment_operator + _Trivial; + return __copy_backward_dispatch<_BI1, _BI2, _Trivial> + ::copy(__first, __last, __result); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + return __copy_backward(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +//-------------------------------------------------- +// copy_n (not part of the C++ standard) + +template +pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, + _OutputIter __result, + input_iterator_tag) { + for ( ; __count > 0; --__count) { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InputIter, _OutputIter>(__first, __result); +} + +template +inline pair<_RAIter, _OutputIter> +__copy_n(_RAIter __first, _Size __count, + _OutputIter __result, + random_access_iterator_tag) { + _RAIter __last = __first + __count; + return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result)); +} + +template +inline pair<_InputIter, _OutputIter> +__copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template +inline pair<_InputIter, _OutputIter> +copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + return __copy_n(__first, __count, __result); +} + +//-------------------------------------------------- +// fill and fill_n + + +template +void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + for ( ; __first != __last; ++__first) + *__first = __value; +} + +template +_OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) { + __STL_REQUIRES(_OutputIter, _OutputIterator); + for ( ; __n > 0; --__n, ++__first) + *__first = __value; + return __first; +} + +// Specialization: for one-byte types we can use memset. + +inline void fill(unsigned char* __first, unsigned char* __last, + const unsigned char& __c) { + unsigned char __tmp = __c; + memset(__first, __tmp, __last - __first); +} + +inline void fill(signed char* __first, signed char* __last, + const signed char& __c) { + signed char __tmp = __c; + memset(__first, static_cast(__tmp), __last - __first); +} + +inline void fill(char* __first, char* __last, const char& __c) { + char __tmp = __c; + memset(__first, static_cast(__tmp), __last - __first); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline unsigned char* fill_n(unsigned char* __first, _Size __n, + const unsigned char& __c) { + fill(__first, __first + __n, __c); + return __first + __n; +} + +template +inline signed char* fill_n(char* __first, _Size __n, + const signed char& __c) { + fill(__first, __first + __n, __c); + return __first + __n; +} + +template +inline char* fill_n(char* __first, _Size __n, const char& __c) { + fill(__first, __first + __n, __c); + return __first + __n; +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +//-------------------------------------------------- +// equal and mismatch + +template +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _EqualityComparable); + __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, + _EqualityComparable); + while (__first1 != __last1 && *__first1 == *__first2) { + ++__first1; + ++__first2; + } + return pair<_InputIter1, _InputIter2>(__first1, __first2); +} + +template +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2, + _BinaryPredicate __binary_pred) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { + ++__first1; + ++__first2; + } + return pair<_InputIter1, _InputIter2>(__first1, __first2); +} + +template +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _EqualityComparable); + __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, + _EqualityComparable); + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (*__first1 != *__first2) + return false; + return true; +} + +template +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _BinaryPredicate __binary_pred) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!__binary_pred(*__first1, *__first2)) + return false; + return true; +} + +//-------------------------------------------------- +// lexicographical_compare and lexicographical_compare_3way. +// (the latter is not part of the C++ standard.) + +template +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, + _LessThanComparable); + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (*__first1 < *__first2) + return true; + if (*__first2 < *__first1) + return false; + } + return __first1 == __last1 && __first2 != __last2; +} + +template +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _Compare __comp) { + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (__comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; +} + +inline bool +lexicographical_compare(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) +{ + const size_t __len1 = __last1 - __first1; + const size_t __len2 = __last2 - __first2; + const int __result = memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result < 0 : __len1 < __len2; +} + +inline bool lexicographical_compare(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) +{ +#if CHAR_MAX == SCHAR_MAX + return lexicographical_compare((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else /* CHAR_MAX == SCHAR_MAX */ + return lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif /* CHAR_MAX == SCHAR_MAX */ +} + +template +int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) +{ + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + if (__first2 == __last2) { + return !(__first1 == __last1); + } + else { + return -1; + } +} + +inline int +__lexicographical_compare_3way(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) +{ + const ptrdiff_t __len1 = __last1 - __first1; + const ptrdiff_t __len2 = __last2 - __first2; + const int __result = memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result + : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); +} + +inline int +__lexicographical_compare_3way(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) +{ +#if CHAR_MAX == SCHAR_MAX + return __lexicographical_compare_3way( + (const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else + return __lexicographical_compare_3way((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif +} + +template +int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) +{ + __STL_REQUIRES(_InputIter1, _InputIterator); + __STL_REQUIRES(_InputIter2, _InputIterator); + __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, + _LessThanComparable); + __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, + _LessThanComparable); + return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_alloc.h b/darkice/tags/darkice-0_2/stl/stl_alloc.h new file mode 100644 index 0000000..e96122a --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_alloc.h @@ -0,0 +1,897 @@ +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_ALLOC_H +#define __SGI_STL_INTERNAL_ALLOC_H + +#ifdef __SUNPRO_CC +# define __PRIVATE public + // Extra access restrictions prevent us from really making some things + // private. +#else +# define __PRIVATE private +#endif + +#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG +# define __USE_MALLOC +#endif + + +// This implements some standard node allocators. These are +// NOT the same as the allocators in the C++ draft standard or in +// in the original STL. They do not encapsulate different pointer +// types; indeed we assume that there is only one pointer type. +// The allocation primitives are intended to allocate individual objects, +// not larger arenas as with the original STL allocators. + +#ifndef __THROW_BAD_ALLOC +# if defined(__STL_NO_BAD_ALLOC) || !defined(__STL_USE_EXCEPTIONS) +# include +# include +# define __THROW_BAD_ALLOC fprintf(stderr, "out of memory\n"); exit(1) +# else /* Standard conforming out-of-memory handling */ +# include +# define __THROW_BAD_ALLOC throw std::bad_alloc() +# endif +#endif + +#include +#include +#include +#include +#ifndef __RESTRICT +# define __RESTRICT +#endif + +#ifdef __STL_THREADS +# include +# define __NODE_ALLOCATOR_THREADS true +# ifdef __STL_SGI_THREADS + // We test whether threads are in use before locking. + // Perhaps this should be moved into stl_threads.h, but that + // probably makes it harder to avoid the procedure call when + // it isn't needed. + extern "C" { + extern int __us_rsthread_malloc; + } + // The above is copied from malloc.h. Including + // would be cleaner but fails with certain levels of standard + // conformance. +# define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ + { _S_node_allocator_lock._M_acquire_lock(); } +# define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ + { _S_node_allocator_lock._M_release_lock(); } +# else /* !__STL_SGI_THREADS */ +# define __NODE_ALLOCATOR_LOCK \ + { if (threads) _S_node_allocator_lock._M_acquire_lock(); } +# define __NODE_ALLOCATOR_UNLOCK \ + { if (threads) _S_node_allocator_lock._M_release_lock(); } +# endif +#else +// Thread-unsafe +# define __NODE_ALLOCATOR_LOCK +# define __NODE_ALLOCATOR_UNLOCK +# define __NODE_ALLOCATOR_THREADS false +#endif + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// Malloc-based allocator. Typically slower than default alloc below. +// Typically thread-safe and more storage efficient. +#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG +# ifdef __DECLARE_GLOBALS_HERE + void (* __malloc_alloc_oom_handler)() = 0; + // g++ 2.7.2 does not handle static template data members. +# else + extern void (* __malloc_alloc_oom_handler)(); +# endif +#endif + +template +class __malloc_alloc_template { + +private: + + static void* _S_oom_malloc(size_t); + static void* _S_oom_realloc(void*, size_t); + +#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG + static void (* __malloc_alloc_oom_handler)(); +#endif + +public: + + static void* allocate(size_t __n) + { + void* __result = malloc(__n); + if (0 == __result) __result = _S_oom_malloc(__n); + return __result; + } + + static void deallocate(void* __p, size_t /* __n */) + { + free(__p); + } + + static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) + { + void* __result = realloc(__p, __new_sz); + if (0 == __result) __result = _S_oom_realloc(__p, __new_sz); + return __result; + } + + static void (* __set_malloc_handler(void (*__f)()))() + { + void (* __old)() = __malloc_alloc_oom_handler; + __malloc_alloc_oom_handler = __f; + return(__old); + } + +}; + +// malloc_alloc out-of-memory handling + +#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG +template +void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; +#endif + +template +void* +__malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) +{ + void (* __my_malloc_handler)(); + void* __result; + + for (;;) { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } + (*__my_malloc_handler)(); + __result = malloc(__n); + if (__result) return(__result); + } +} + +template +void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) +{ + void (* __my_malloc_handler)(); + void* __result; + + for (;;) { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } + (*__my_malloc_handler)(); + __result = realloc(__p, __n); + if (__result) return(__result); + } +} + +typedef __malloc_alloc_template<0> malloc_alloc; + +template +class simple_alloc { + +public: + static _Tp* allocate(size_t __n) + { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); } + static _Tp* allocate(void) + { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } + static void deallocate(_Tp* __p, size_t __n) + { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } + static void deallocate(_Tp* __p) + { _Alloc::deallocate(__p, sizeof (_Tp)); } +}; + +// Allocator adaptor to check size arguments for debugging. +// Reports errors using assert. Checking can be disabled with +// NDEBUG, but it's far better to just use the underlying allocator +// instead when no checking is desired. +// There is some evidence that this can confuse Purify. +template +class debug_alloc { + +private: + + enum {_S_extra = 8}; // Size of space used to store size. Note + // that this must be large enough to preserve + // alignment. + +public: + + static void* allocate(size_t __n) + { + char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra); + *(size_t*)__result = __n; + return __result + (int) _S_extra; + } + + static void deallocate(void* __p, size_t __n) + { + char* __real_p = (char*)__p - (int) _S_extra; + assert(*(size_t*)__real_p == __n); + _Alloc::deallocate(__real_p, __n + (int) _S_extra); + } + + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz) + { + char* __real_p = (char*)__p - (int) _S_extra; + assert(*(size_t*)__real_p == __old_sz); + char* __result = (char*) + _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra, + __new_sz + (int) _S_extra); + *(size_t*)__result = __new_sz; + return __result + (int) _S_extra; + } + +}; + + +# ifdef __USE_MALLOC + +typedef malloc_alloc alloc; +typedef malloc_alloc single_client_alloc; + +# else + + +// Default node allocator. +// With a reasonable compiler, this should be roughly as fast as the +// original STL class-specific allocators, but with less fragmentation. +// Default_alloc_template parameters are experimental and MAY +// DISAPPEAR in the future. Clients should just use alloc for now. +// +// Important implementation properties: +// 1. If the client request an object of size > _MAX_BYTES, the resulting +// object will be obtained directly from malloc. +// 2. In all other cases, we allocate an object of size exactly +// _S_round_up(requested_size). Thus the client has enough size +// information that we can return the object to the proper free list +// without permanently losing part of the object. +// + +// The first template parameter specifies whether more than one thread +// may use this allocator. It is safe to allocate an object from +// one instance of a default_alloc and deallocate it with another +// one. This effectively transfers its ownership to the second one. +// This may have undesirable effects on reference locality. +// The second parameter is unreferenced and serves only to allow the +// creation of multiple default_alloc instances. +// Node that containers built on different allocator instances have +// different types, limiting the utility of this approach. + +#if defined(__SUNPRO_CC) || defined(__GNUC__) +// breaks if we make these template class members: + enum {_ALIGN = 8}; + enum {_MAX_BYTES = 128}; + enum {_NFREELISTS = 16}; // _MAX_BYTES/_ALIGN +#endif + +template +class __default_alloc_template { + +private: + // Really we should use static const int x = N + // instead of enum { x = N }, but few compilers accept the former. +#if ! (defined(__SUNPRO_CC) || defined(__GNUC__)) + enum {_ALIGN = 8}; + enum {_MAX_BYTES = 128}; + enum {_NFREELISTS = 16}; // _MAX_BYTES/_ALIGN +# endif + static size_t + _S_round_up(size_t __bytes) + { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); } + +__PRIVATE: + union _Obj { + union _Obj* _M_free_list_link; + char _M_client_data[1]; /* The client sees this. */ + }; +private: +# if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC) + static _Obj* __STL_VOLATILE _S_free_list[]; + // Specifying a size results in duplicate def for 4.1 +# else + static _Obj* __STL_VOLATILE _S_free_list[_NFREELISTS]; +# endif + static size_t _S_freelist_index(size_t __bytes) { + return (((__bytes) + (size_t)_ALIGN-1)/(size_t)_ALIGN - 1); + } + + // Returns an object of size __n, and optionally adds to size __n free list. + static void* _S_refill(size_t __n); + // Allocates a chunk for nobjs of size size. nobjs may be reduced + // if it is inconvenient to allocate the requested number. + static char* _S_chunk_alloc(size_t __size, int& __nobjs); + + // Chunk allocation state. + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_heap_size; + +# ifdef __STL_THREADS + static _STL_mutex_lock _S_node_allocator_lock; +# endif + + // It would be nice to use _STL_auto_lock here. But we + // don't need the NULL check. And we do need a test whether + // threads have actually been started. + class _Lock; + friend class _Lock; + class _Lock { + public: + _Lock() { __NODE_ALLOCATOR_LOCK; } + ~_Lock() { __NODE_ALLOCATOR_UNLOCK; } + }; + +public: + + /* __n must be > 0 */ + static void* allocate(size_t __n) + { + void* __ret = 0; + + if (__n > (size_t) _MAX_BYTES) { + __ret = malloc_alloc::allocate(__n); + } + else { + _Obj* __STL_VOLATILE* __my_free_list + = _S_free_list + _S_freelist_index(__n); + // Acquire the lock here with a constructor call. + // This ensures that it is released in exit or during stack + // unwinding. +# ifndef _NOTHREADS + /*REFERENCED*/ + _Lock __lock_instance; +# endif + _Obj* __RESTRICT __result = *__my_free_list; + if (__result == 0) + __ret = _S_refill(_S_round_up(__n)); + else { + *__my_free_list = __result -> _M_free_list_link; + __ret = __result; + } + } + + return __ret; + }; + + /* __p may not be 0 */ + static void deallocate(void* __p, size_t __n) + { + if (__n > (size_t) _MAX_BYTES) + malloc_alloc::deallocate(__p, __n); + else { + _Obj* __STL_VOLATILE* __my_free_list + = _S_free_list + _S_freelist_index(__n); + _Obj* __q = (_Obj*)__p; + + // acquire lock +# ifndef _NOTHREADS + /*REFERENCED*/ + _Lock __lock_instance; +# endif /* _NOTHREADS */ + __q -> _M_free_list_link = *__my_free_list; + *__my_free_list = __q; + // lock is released here + } + } + + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz); + +} ; + +typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; +typedef __default_alloc_template single_client_alloc; + +template +inline bool operator==(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return true; +} + +# ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return false; +} +# endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + + +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +/* We hold the allocation lock. */ +template +char* +__default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, + int& __nobjs) +{ + char* __result; + size_t __total_bytes = __size * __nobjs; + size_t __bytes_left = _S_end_free - _S_start_free; + + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = (int)(__bytes_left/__size); + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else { + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); + // Try to make use of the left-over piece. + if (__bytes_left > 0) { + _Obj* __STL_VOLATILE* __my_free_list = + _S_free_list + _S_freelist_index(__bytes_left); + + ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; + *__my_free_list = (_Obj*)_S_start_free; + } + _S_start_free = (char*)malloc(__bytes_to_get); + if (0 == _S_start_free) { + size_t __i; + _Obj* __STL_VOLATILE* __my_free_list; + _Obj* __p; + // Try to make do with what we have. That can't + // hurt. We do not try smaller requests, since that tends + // to result in disaster on multi-process machines. + for (__i = __size; + __i <= (size_t) _MAX_BYTES; + __i += (size_t) _ALIGN) { + __my_free_list = _S_free_list + _S_freelist_index(__i); + __p = *__my_free_list; + if (0 != __p) { + *__my_free_list = __p -> _M_free_list_link; + _S_start_free = (char*)__p; + _S_end_free = _S_start_free + __i; + return(_S_chunk_alloc(__size, __nobjs)); + // Any leftover piece will eventually make it to the + // right free list. + } + } + _S_end_free = 0; // In case of exception. + _S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get); + // This should either throw an + // exception or remedy the situation. Thus we assume it + // succeeded. + } + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; + return(_S_chunk_alloc(__size, __nobjs)); + } +} + + +/* Returns an object of size __n, and optionally adds to size __n free list.*/ +/* We assume that __n is properly aligned. */ +/* We hold the allocation lock. */ +template +void* +__default_alloc_template<__threads, __inst>::_S_refill(size_t __n) +{ + int __nobjs = 20; + char* __chunk = _S_chunk_alloc(__n, __nobjs); + _Obj* __STL_VOLATILE* __my_free_list; + _Obj* __result; + _Obj* __current_obj; + _Obj* __next_obj; + int __i; + + if (1 == __nobjs) return(__chunk); + __my_free_list = _S_free_list + _S_freelist_index(__n); + + /* Build free list in chunk */ + __result = (_Obj*)__chunk; + *__my_free_list = __next_obj = (_Obj*)(__chunk + __n); + for (__i = 1; ; __i++) { + __current_obj = __next_obj; + __next_obj = (_Obj*)((char*)__next_obj + __n); + if (__nobjs - 1 == __i) { + __current_obj -> _M_free_list_link = 0; + break; + } else { + __current_obj -> _M_free_list_link = __next_obj; + } + } + return(__result); +} + +template +void* +__default_alloc_template::reallocate(void* __p, + size_t __old_sz, + size_t __new_sz) +{ + void* __result; + size_t __copy_sz; + + if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) { + return(realloc(__p, __new_sz)); + } + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + __result = allocate(__new_sz); + __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; + memcpy(__result, __p, __copy_sz); + deallocate(__p, __old_sz); + return(__result); +} + +#ifdef __STL_THREADS + template + _STL_mutex_lock + __default_alloc_template<__threads, __inst>::_S_node_allocator_lock + __STL_MUTEX_INITIALIZER; +#endif + + +template +char* __default_alloc_template<__threads, __inst>::_S_start_free = 0; + +template +char* __default_alloc_template<__threads, __inst>::_S_end_free = 0; + +template +size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0; + +template +typename __default_alloc_template<__threads, __inst>::_Obj* __STL_VOLATILE +__default_alloc_template<__threads, __inst> ::_S_free_list[ +# if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC) + _NFREELISTS +# else + __default_alloc_template<__threads, __inst>::_NFREELISTS +# endif +] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +// The 16 zeros are necessary to make version 4.1 of the SunPro +// compiler happy. Otherwise it appears to allocate too little +// space for the array. + +#endif /* ! __USE_MALLOC */ + +// This implements allocators as specified in the C++ standard. +// +// Note that standard-conforming allocators use many language features +// that are not yet widely implemented. In particular, they rely on +// member templates, partial specialization, partial ordering of function +// templates, the typename keyword, and the use of the template keyword +// to refer to a template member of a dependent type. + +#ifdef __STL_USE_STD_ALLOCATORS + +template +class allocator { + typedef alloc _Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef allocator<_Tp1> other; + }; + + allocator() __STL_NOTHROW {} + allocator(const allocator&) __STL_NOTHROW {} + template allocator(const allocator<_Tp1>&) __STL_NOTHROW {} + ~allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template<> +class allocator { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef allocator<_Tp1> other; + }; +}; + + +template +inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) +{ + return true; +} + +template +inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) +{ + return false; +} + +// Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc) +// into a standard-conforming allocator. Note that this adaptor does +// *not* assume that all objects of the underlying alloc class are +// identical, nor does it assume that all of the underlying alloc's +// member functions are static member functions. Note, also, that +// __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>. + +template +struct __allocator { + _Alloc __underlying_alloc; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; + + __allocator() __STL_NOTHROW {} + __allocator(const __allocator& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + template + __allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + ~__allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 + ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template +class __allocator { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; +}; + +template +inline bool operator==(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc == __a2.__underlying_alloc; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc != __a2.__underlying_alloc; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Comparison operators for all of the predifined SGI-style allocators. +// This ensures that __allocator (for example) will +// work correctly. + +template +inline bool operator==(const __malloc_alloc_template&, + const __malloc_alloc_template&) +{ + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __malloc_alloc_template<__inst>&, + const __malloc_alloc_template<__inst>&) +{ + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template +inline bool operator==(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Another allocator adaptor: _Alloc_traits. This serves two +// purposes. First, make it possible to write containers that can use +// either SGI-style allocators or standard-conforming allocator. +// Second, provide a mechanism so that containers can query whether or +// not the allocator has distinct instances. If not, the container +// can avoid wasting a word of memory to store an empty object. + +// This adaptor uses partial specialization. The general case of +// _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a +// standard-conforming allocator, possibly with non-equal instances +// and non-static members. (It still behaves correctly even if _Alloc +// has static member and if all instances are equal. Refinements +// affect performance, not correctness.) + +// There are always two members: allocator_type, which is a standard- +// conforming allocator type for allocating objects of type _Tp, and +// _S_instanceless, a static const member of type bool. If +// _S_instanceless is true, this means that there is no difference +// between any two instances of type allocator_type. Furthermore, if +// _S_instanceless is true, then _Alloc_traits has one additional +// member: _Alloc_type. This type encapsulates allocation and +// deallocation of objects of type _Tp through a static interface; it +// has two member functions, whose signatures are +// static _Tp* allocate(size_t) +// static void deallocate(_Tp*, size_t) + +// The fully general version. + +template +struct _Alloc_traits +{ + static const bool _S_instanceless = false; + typedef typename _Allocator::__STL_TEMPLATE rebind<_Tp>::other + allocator_type; +}; + +template +const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; + +// The version for the default allocator. + +template +struct _Alloc_traits<_Tp, allocator<_Tp1> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, alloc> _Alloc_type; + typedef allocator<_Tp> allocator_type; +}; + +// Versions for the predefined SGI-style allocators. + +template +struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +template +struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > + allocator_type; +}; + +template +struct _Alloc_traits<_Tp, debug_alloc<_Alloc> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + +// Versions for the __allocator adaptor used with the predefined +// SGI-style allocators. + +template +struct _Alloc_traits<_Tp, + __allocator<_Tp1, __malloc_alloc_template<__inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +template +struct _Alloc_traits<_Tp, + __allocator<_Tp1, + __default_alloc_template<__thr, __inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > + allocator_type; +}; + +template +struct _Alloc_traits<_Tp, __allocator<_Tp1, debug_alloc<_Alloc> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + + +#endif /* __STL_USE_STD_ALLOCATORS */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#undef __PRIVATE + +#endif /* __SGI_STL_INTERNAL_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_bvector.h b/darkice/tags/darkice-0_2/stl/stl_bvector.h new file mode 100644 index 0000000..cba0835 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_bvector.h @@ -0,0 +1,896 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_BVECTOR_H +#define __SGI_STL_INTERNAL_BVECTOR_H + +__STL_BEGIN_NAMESPACE + +static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int)); + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +struct _Bit_reference { + unsigned int* _M_p; + unsigned int _M_mask; + _Bit_reference(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_mask(__y) {} + +public: + _Bit_reference() : _M_p(0), _M_mask(0) {} + operator bool() const { return !(!(*_M_p & _M_mask)); } + _Bit_reference& operator=(bool __x) + { + if (__x) *_M_p |= _M_mask; + else *_M_p &= ~_M_mask; + return *this; + } + _Bit_reference& operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + bool operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + bool operator<(const _Bit_reference& __x) const { + return !bool(*this) && bool(__x); + } + void flip() { *_M_p ^= _M_mask; } +}; + +inline void swap(_Bit_reference __x, _Bit_reference __y) +{ + bool __tmp = __x; + __x = __y; + __y = __tmp; +} + +struct _Bit_iterator_base : public random_access_iterator +{ + unsigned int* _M_p; + unsigned int _M_offset; + + _Bit_iterator_base(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) {} + + void _M_bump_up() { + if (_M_offset++ == __WORD_BIT - 1) { + _M_offset = 0; + ++_M_p; + } + } + void _M_bump_down() { + if (_M_offset-- == 0) { + _M_offset = __WORD_BIT - 1; + --_M_p; + } + } + + void _M_incr(ptrdiff_t __i) { + difference_type __n = __i + _M_offset; + _M_p += __n / __WORD_BIT; + __n = __n % __WORD_BIT; + if (__n < 0) { + _M_offset = (unsigned int) __n + __WORD_BIT; + --_M_p; + } else + _M_offset = (unsigned int) __n; + } + + bool operator==(const _Bit_iterator_base& __i) const { + return _M_p == __i._M_p && _M_offset == __i._M_offset; + } + bool operator<(const _Bit_iterator_base& __i) const { + return _M_p < __i._M_p || (_M_p == __i._M_p && _M_offset < __i._M_offset); + } + bool operator!=(const _Bit_iterator_base& __i) const { + return !(*this == __i); + } + bool operator>(const _Bit_iterator_base& __i) const { + return __i < *this; + } + bool operator<=(const _Bit_iterator_base& __i) const { + return !(__i < *this); + } + bool operator>=(const _Bit_iterator_base& __i) const { + return !(*this < __i); + } +}; + +inline ptrdiff_t +operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) { + return __WORD_BIT * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset; +} + + +struct _Bit_iterator : public _Bit_iterator_base +{ + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; + + _Bit_iterator() : _Bit_iterator_base(0, 0) {} + _Bit_iterator(unsigned int* __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) {} + + reference operator*() const { return reference(_M_p, 1U << _M_offset); } + iterator& operator++() { + _M_bump_up(); + return *this; + } + iterator operator++(int) { + iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + iterator& operator--() { + _M_bump_down(); + return *this; + } + iterator operator--(int) { + iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + iterator& operator+=(difference_type __i) { + _M_incr(__i); + return *this; + } + iterator& operator-=(difference_type __i) { + *this += -__i; + return *this; + } + iterator operator+(difference_type __i) const { + iterator __tmp = *this; + return __tmp += __i; + } + iterator operator-(difference_type __i) const { + iterator __tmp = *this; + return __tmp -= __i; + } + + reference operator[](difference_type __i) { return *(*this + __i); } +}; + +inline _Bit_iterator +operator+(ptrdiff_t __n, const _Bit_iterator& __x) { return __x + __n; } + + +struct _Bit_const_iterator : public _Bit_iterator_base +{ + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef _Bit_const_iterator const_iterator; + + _Bit_const_iterator() : _Bit_iterator_base(0, 0) {} + _Bit_const_iterator(unsigned int* __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) {} + _Bit_const_iterator(const _Bit_iterator& __x) + : _Bit_iterator_base(__x._M_p, __x._M_offset) {} + + const_reference operator*() const { + return _Bit_reference(_M_p, 1U << _M_offset); + } + const_iterator& operator++() { + _M_bump_up(); + return *this; + } + const_iterator operator++(int) { + const_iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + const_iterator& operator--() { + _M_bump_down(); + return *this; + } + const_iterator operator--(int) { + const_iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + const_iterator& operator+=(difference_type __i) { + _M_incr(__i); + return *this; + } + const_iterator& operator-=(difference_type __i) { + *this += -__i; + return *this; + } + const_iterator operator+(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp += __i; + } + const_iterator operator-(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp -= __i; + } + const_reference operator[](difference_type __i) { + return *(*this + __i); + } +}; + +inline _Bit_const_iterator +operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) { return __x + __n; } + + +// Bit-vector base class, which encapsulates the difference between +// old SGI-style allocators and standard-conforming allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Bvector_alloc_base { +public: + typedef typename _Alloc_traits::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Bvector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + unsigned int* _M_bit_alloc(size_t __n) + { return _M_data_allocator.allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _M_data_allocator.deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + typename _Alloc_traits::allocator_type + _M_data_allocator; + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +// Specialization for instanceless allocators. +template +class _Bvector_alloc_base<_Allocator, true> { +public: + typedef typename _Alloc_traits::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_alloc_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + typedef typename _Alloc_traits::_Alloc_type + _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +template +class _Bvector_base + : public _Bvector_alloc_base<_Alloc, + _Alloc_traits::_S_instanceless> +{ + typedef _Bvector_alloc_base<_Alloc, + _Alloc_traits::_S_instanceless> + _Base; +public: + typedef typename _Base::allocator_type allocator_type; + + _Bvector_base(const allocator_type& __a) : _Base(__a) {} + ~_Bvector_base() { _Base::_M_deallocate(); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Bvector_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + ~_Bvector_base() { _M_deallocate(); } + +protected: + typedef simple_alloc _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +// The next few lines are confusing. What we're doing is declaring a +// partial specialization of vector if we have the necessary +// compiler support. Otherwise, we define a class bit_vector which uses +// the default allocator. + +#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NO_BOOL) +# define __SGI_STL_VECBOOL_TEMPLATE +# define __BVECTOR vector +# define __VECTOR vector +# define __BVECTOR_BASE _Bvector_base<_Alloc> +# define __BVECTOR_TMPL_LIST template + __STL_END_NAMESPACE +# include + __STL_BEGIN_NAMESPACE +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION && !__STL_NO_BOOL */ +# undef __SGI_STL_VECBOOL_TEMPLATE +# define __BVECTOR bit_vector +# define __VECTOR bit_vector +# define __BVECTOR_BASE _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > +# define __BVECTOR_TMPL_LIST +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION && !__STL_NO_BOOL */ + + +__BVECTOR_TMPL_LIST +class __BVECTOR : public __BVECTOR_BASE +{ +public: + typedef bool value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Bit_reference reference; + typedef bool const_reference; + typedef _Bit_reference* pointer; + typedef const bool* const_pointer; + + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + typedef typename __BVECTOR_BASE::allocator_type allocator_type; + allocator_type get_allocator() const { + return __BVECTOR_BASE::get_allocator(); + } + +protected: +#ifdef __STL_USE_NAMESPACES + using __BVECTOR_BASE::_M_bit_alloc; + using __BVECTOR_BASE::_M_deallocate; + using __BVECTOR_BASE::_M_start; + using __BVECTOR_BASE::_M_finish; + using __BVECTOR_BASE::_M_end_of_storage; +#endif /* __STL_USE_NAMESPACES */ + +protected: + void _M_initialize(size_type __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + _M_finish = _M_start + difference_type(__n); + } + void _M_insert_aux(iterator __position, bool __x) { + if (_M_finish._M_p != _M_end_of_storage) { + copy_backward(__position, _M_finish, _M_finish + 1); + *__position = __x; + ++_M_finish; + } + else { + size_type __len = size() ? 2 * size() : __WORD_BIT; + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + +#ifdef __STL_MEMBER_TEMPLATES + template + void _M_initialize_range(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + _M_start = iterator(); + _M_finish = iterator(); + _M_end_of_storage = 0; + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + template + void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + + template + void _M_insert_range(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) { + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template + void _M_insert_range(iterator __position, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + difference_type(__n)); + copy(__first, __last, __position); + _M_finish += difference_type(__n); + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + size_type size() const { return size_type(end() - begin()); } + size_type max_size() const { return size_type(-1); } + size_type capacity() const { + return size_type(const_iterator(_M_end_of_storage, 0) - begin()); + } + bool empty() const { return begin() == end(); } + + reference operator[](size_type __n) + { return *(begin() + difference_type(__n)); } + const_reference operator[](size_type __n) const + { return *(begin() + difference_type(__n)); } + +#ifdef __STL_THROW_RANGE_ERRORS + void _M_range_check(size_type __n) const { + if (__n >= this->size()) + __stl_throw_range_error("vector"); + } + + reference at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + const_reference at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } +#endif /* __STL_THROW_RANGE_ERRORS */ + + explicit __VECTOR(const allocator_type& __a = allocator_type()) + : __BVECTOR_BASE(__a) {} + + __VECTOR(size_type __n, bool __value, + const allocator_type& __a = allocator_type()) + : __BVECTOR_BASE(__a) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __value ? ~0 : 0); + } + + explicit __VECTOR(size_type __n) + : __BVECTOR_BASE(allocator_type()) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, 0); + } + + __VECTOR(const __VECTOR& __x) : __BVECTOR_BASE(__x.get_allocator()) { + _M_initialize(__x.size()); + copy(__x.begin(), __x.end(), _M_start); + } + +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + } + + template + void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_initialize_range(__first, __last, __ITERATOR_CATEGORY(__first)); + } + + template + __VECTOR(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : __BVECTOR_BASE(__a) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + __VECTOR(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : __BVECTOR_BASE(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + __VECTOR(const bool* __first, const bool* __last, + const allocator_type& __a = allocator_type()) + : __BVECTOR_BASE(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + ~__VECTOR() { } + + __VECTOR& operator=(const __VECTOR& __x) { + if (&__x == this) return *this; + if (__x.size() > capacity()) { + _M_deallocate(); + _M_initialize(__x.size()); + } + copy(__x.begin(), __x.end(), begin()); + _M_finish = begin() + difference_type(__x.size()); + return *this; + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void _M_fill_assign(size_t __n, bool __x) { + if (__n > size()) { + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else { + erase(begin() + __n, end()); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + } + } + + void assign(size_t __n, bool __x) { _M_fill_assign(__n, __x); } + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_t) __n, (bool) __val); } + + template + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len < size()) + erase(copy(__first, __last, begin()), end()); + else { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + void reserve(size_type __n) { + if (capacity() < __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_finish = copy(begin(), end(), iterator(__q, 0)); + _M_deallocate(); + _M_start = iterator(__q, 0); + _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; + } + } + + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(end() - 1); } + const_reference back() const { return *(end() - 1); } + void push_back(bool __x) { + if (_M_finish._M_p != _M_end_of_storage) + *_M_finish++ = __x; + else + _M_insert_aux(end(), __x); + } + void swap(__BVECTOR& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); + } + iterator insert(iterator __position, bool __x = bool()) { + difference_type __n = __position - begin(); + if (_M_finish._M_p != _M_end_of_storage && __position == end()) + *_M_finish++ = __x; + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + _M_fill_insert(__pos, __n, __x); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_insert_range(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); + } + + template + void insert(iterator __position, + _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, + const_iterator __first, const_iterator __last) { + if (__first == __last) return; + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + __n); + copy(__first, __last, __position); + _M_finish += __n; + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + + void insert(iterator __position, const bool* __first, const bool* __last) { + if (__first == __last) return; + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + __n); + copy(__first, __last, __position); + _M_finish += __n; + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } +#endif /* __STL_MEMBER_TEMPLATES */ + + void _M_fill_insert(iterator __position, size_type __n, bool __x) { + if (__n == 0) return; + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + difference_type(__n)); + fill(__position, __position + difference_type(__n), __x); + _M_finish += difference_type(__n); + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + fill_n(__i, __n, __x); + _M_finish = copy(__position, end(), __i + difference_type(__n)); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + + void insert(iterator __position, size_type __n, bool __x) { + _M_fill_insert(__position, __n, __x); + } + + void pop_back() { --_M_finish; } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, end(), __position); + --_M_finish; + return __position; + } + iterator erase(iterator __first, iterator __last) { + _M_finish = copy(__last, end(), __first); + return __first; + } + void resize(size_type __new_size, bool __x = bool()) { + if (__new_size < size()) + erase(begin() + difference_type(__new_size), end()); + else + insert(end(), __new_size - size(), __x); + } + void flip() { + for (unsigned int* __p = _M_start._M_p; __p != _M_end_of_storage; ++__p) + *__p = ~*__p; + } + + void clear() { erase(begin(), end()); } +}; + +#ifdef __SGI_STL_VECBOOL_TEMPLATE + +// This typedef is non-standard. It is provided for backward compatibility. +typedef vector bit_vector; + +#else /* __SGI_STL_VECBOOL_TEMPLATE */ + +inline void swap(bit_vector& __x, bit_vector& __y) { + __x.swap(__y); +} + +inline bool +operator==(const bit_vector& __x, const bit_vector& __y) +{ + return (__x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin())); +} + +inline bool +operator!=(const bit_vector& __x, const bit_vector& __y) +{ + return !(__x == __y); +} + +inline bool +operator<(const bit_vector& __x, const bit_vector& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +inline bool operator>(const bit_vector& __x, const bit_vector& __y) +{ + return __y < __x; +} + +inline bool operator<=(const bit_vector& __x, const bit_vector& __y) +{ + return !(__y < __x); +} + +inline bool operator>=(const bit_vector& __x, const bit_vector& __y) +{ + return !(__x < __y); +} + +#endif /* __SGI_STL_VECBOOL_TEMPLATE */ + +#undef __SGI_STL_VECBOOL_TEMPLATE +#undef __BVECTOR +#undef __VECTOR +#undef __BVECTOR_BASE +#undef __BVECTOR_TMPL_LIST + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_config.h b/darkice/tags/darkice-0_2/stl/stl_config.h new file mode 100644 index 0000000..6f37131 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_config.h @@ -0,0 +1,576 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __STL_CONFIG_H +# define __STL_CONFIG_H + +// Flags: +// * __STL_NO_BOOL: defined if the compiler doesn't have bool as a builtin +// type. +// * __STL_HAS_WCHAR_T: defined if the compier has wchar_t as a builtin type. +// * __STL_NO_DRAND48: defined if the compiler doesn't have the drand48 +// function. +// * __STL_STATIC_TEMPLATE_MEMBER_BUG: defined if the compiler can't handle +// static members of template classes. +// * __STL_STATIC_CONST_INIT_BUG: defined if the compiler can't handle a +// constant-initializer in the declaration of a static const data member +// of integer type. (See section 9.4.2, paragraph 4, of the C++ standard.) +// * __STL_CLASS_PARTIAL_SPECIALIZATION: defined if the compiler supports +// partial specialization of template classes. +// * __STL_PARTIAL_SPECIALIZATION_SYNTAX: defined if the compiler +// supports partial specialization syntax for full specialization of +// class templates. (Even if it doesn't actually support partial +// specialization itself.) +// * __STL_FUNCTION_TMPL_PARTIAL_ORDER: defined if the compiler supports +// partial ordering of function templates. (a.k.a partial specialization +// of function templates.) +// * __STL_MEMBER_TEMPLATES: defined if the compiler supports template +// member functions of classes. +// * __STL_MEMBER_TEMPLATE_CLASSES: defined if the compiler supports +// nested classes that are member templates of other classes. +// * __STL_TEMPLATE_FRIENDS: defined if the compiler supports templatized +// friend declarations. +// * __STL_EXPLICIT_FUNCTION_TMPL_ARGS: defined if the compiler +// supports calling a function template by providing its template +// arguments explicitly. +// * __STL_LIMITED_DEFAULT_TEMPLATES: defined if the compiler is unable +// to handle default template parameters that depend on previous template +// parameters. +// * __STL_NON_TYPE_TMPL_PARAM_BUG: defined if the compiler has trouble with +// function template argument deduction for non-type template parameters. +// * __SGI_STL_NO_ARROW_OPERATOR: defined if the compiler is unable +// to support the -> operator for iterators. +// * __STL_DEFAULT_CONSTRUCTOR_BUG: defined if T() does not work properly +// when T is a builtin type. +// * __STL_USE_EXCEPTIONS: defined if the compiler (in the current compilation +// mode) supports exceptions. +// * __STL_USE_NAMESPACES: defined if the compiler has the necessary +// support for namespaces. +// * __STL_NO_EXCEPTION_HEADER: defined if the compiler does not have a +// standard-conforming header . +// * __STL_NO_BAD_ALLOC: defined if the compiler does not have a +// header, or if does not contain a bad_alloc class. If a bad_alloc +// class exists, it is assumed to be in namespace std. +// * __STL_SGI_THREADS: defined if this is being compiled for an SGI IRIX +// system in multithreaded mode, using native SGI threads instead of +// pthreads. +// * __STL_WIN32THREADS: defined if this is being compiled on a WIN32 +// compiler in multithreaded mode. +// * __STL_PTHREADS: defined if we should use portable pthreads +// synchronization. +// * __STL_UITHREADS: defined if we should use UI / solaris / UnixWare threads +// synchronization. UIthreads are similar to pthreads, but are based +// on an earlier version of the Posix threads standard. +// * __STL_LONG_LONG if the compiler has long long and unsigned long long +// types. (They're not in the C++ standard, but they are expected to be +// included in the forthcoming C9X standard.) +// * __STL_THREADS is defined if thread safety is needed. +// * __STL_VOLATILE is defined to be "volatile" if threads are being +// used, and the empty string otherwise. +// * __STL_USE_CONCEPT_CHECKS enables some extra compile-time error +// checking to make sure that user-defined template arguments satisfy +// all of the appropriate requirements. This may result in more +// comprehensible error messages. It incurs no runtime overhead. This +// feature requires member templates and partial specialization. +// * __STL_NO_USING_CLAUSE_IN_CLASS: The compiler does not handle "using" +// clauses inside of class definitions. +// * __STL_NO_FRIEND_TEMPLATE_CLASS: The compiler does not handle friend +// declaractions where the friend is a template class. +// * __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE: The compiler does not +// support the use of a function pointer type as the argument +// for a template. +// * __STL_MEMBER_TEMPLATE_KEYWORD: standard C++ requires the template +// keyword in a few new places (14.2.4). This flag is set for +// compilers that support (and require) this usage. + + +// User-settable macros that control compilation: +// * __STL_USE_SGI_ALLOCATORS: if defined, then the STL will use older +// SGI-style allocators, instead of standard-conforming allocators, +// even if the compiler supports all of the language features needed +// for standard-conforming allocators. +// * __STL_NO_NAMESPACES: if defined, don't put the library in namespace +// std, even if the compiler supports namespaces. +// * __STL_NO_RELOPS_NAMESPACE: if defined, don't put the relational +// operator templates (>, <=. >=, !=) in namespace std::rel_ops, even +// if the compiler supports namespaces and partial ordering of +// function templates. +// * __STL_ASSERTIONS: if defined, then enable runtime checking through the +// __stl_assert macro. +// * _PTHREADS: if defined, use Posix threads for multithreading support. +// * _UITHREADS:if defined, use SCO/Solaris/UI threads for multithreading +// support +// * _NOTHREADS: if defined, don't use any multithreading support. +// * _STL_NO_CONCEPT_CHECKS: if defined, disables the error checking that +// we get from __STL_USE_CONCEPT_CHECKS. +// * __STL_USE_NEW_IOSTREAMS: if defined, then the STL will use new, +// standard-conforming iostreams (e.g. the header). If not +// defined, the STL will use old cfront-style iostreams (e.g. the +// header). + +// Other macros defined by this file: + +// * bool, true, and false, if __STL_NO_BOOL is defined. +// * typename, as a null macro if it's not already a keyword. +// * explicit, as a null macro if it's not already a keyword. +// * namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) +// * exception-related macros (__STL_TRY, __STL_UNWIND, etc.) +// * __stl_assert, either as a test or as a null macro, depending on +// whether or not __STL_ASSERTIONS is defined. + +# if defined(_PTHREADS) && !defined(_NOTHREADS) +# define __STL_PTHREADS +# endif + +# if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS) +# define __STL_UITHREADS +# endif + +# if defined(__sgi) && !defined(__GNUC__) +# include +# if !defined(_BOOL) +# define __STL_NO_BOOL +# endif +# if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 +# define __STL_STATIC_CONST_INIT_BUG +# endif +# if defined(_WCHAR_T_IS_KEYWORD) +# define __STL_HAS_WCHAR_T +# endif +# if !defined(_TYPENAME_IS_KEYWORD) +# define __STL_NEED_TYPENAME +# endif +# ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# endif +# if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 +# define __STL_FUNCTION_TMPL_PARTIAL_ORDER +# endif +# ifdef _MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATES +# define __STL_TEMPLATE_FRIENDS +# define __STL_MEMBER_TEMPLATE_CLASSES +# endif +# if defined(_MEMBER_TEMPLATE_KEYWORD) +# define __STL_MEMBER_TEMPLATE_KEYWORD +# endif +# if defined(_STANDARD_C_PLUS_PLUS) +# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# endif +# if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 +# define __STL_MEMBER_TEMPLATE_KEYWORD +# endif +# if COMPILER_VERSION < 720 || (defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32) +# define __STL_DEFAULT_CONSTRUCTOR_BUG +# endif +# if !defined(_EXPLICIT_IS_KEYWORD) +# define __STL_NEED_EXPLICIT +# endif +# ifdef __EXCEPTIONS +# define __STL_USE_EXCEPTIONS +# endif +# if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) +# define __STL_HAS_NAMESPACES +# endif +# if (_COMPILER_VERSION < 721) || \ + !defined(__STL_HAS_NAMESPACES) || defined(__STL_NO_NAMESPACES) +# define __STL_NO_EXCEPTION_HEADER +# endif +# if _COMPILER_VERSION < 730 || !defined(_STANDARD_C_PLUS_PLUS) || \ + !defined(_NAMESPACES) +# define __STL_NO_BAD_ALLOC +# endif +# if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) +# define __STL_SGI_THREADS +# endif +# if defined(_LONGLONG) && defined(_SGIAPI) && _SGIAPI +# define __STL_LONG_LONG +# endif +# if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) +# define __STL_USE_NEW_IOSTREAMS +# endif +# if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) +# define __STL_CAN_THROW_RANGE_ERRORS +# endif +# if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) +# define __SGI_STL_USE_AUTO_PTR_CONVERSIONS +# endif +# endif + + +/* + * Jochen Schlick '1999 - added new #defines (__STL)_UITHREADS (for + * providing SCO / Solaris / UI thread support) + * - added the necessary defines for the SCO UDK 7 + * compiler (and its template friend behavior) + * - all UDK7 specific STL changes are based on the + * macro __USLC__ being defined + */ +// SCO UDK 7 compiler (UnixWare 7x, OSR 5, UnixWare 2x) +# if defined(__USLC__) +# define __STL_HAS_WCHAR_T +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_PARTIAL_SPECIALIZATION_SYNTAX +# define __STL_FUNCTION_TMPL_PARTIAL_ORDER +# define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_USE_EXCEPTIONS +# define __STL_HAS_NAMESPACES +# define __STL_USE_NAMESPACES +# define __STL_LONG_LONG +# if defined(_REENTRANT) +# define _UITHREADS /* if UnixWare < 7.0.1 */ +# define __STL_UITHREADS +// use the following defines instead of the UI threads defines when +// you want to use POSIX threads +//# define _PTHREADS /* only if UnixWare >=7.0.1 */ +//# define __STL_PTHREADS +# endif +# endif + + + +# ifdef __GNUC__ +# if __GNUC__ == 2 && __GNUC_MINOR__ <= 7 +# define __STL_STATIC_TEMPLATE_MEMBER_BUG +# endif +# if __GNUC__ < 2 +# define __STL_NEED_TYPENAME +# define __STL_NEED_EXPLICIT +# endif +# if __GNUC__ == 2 && __GNUC_MINOR__ <= 8 +# define __STL_NO_EXCEPTION_HEADER +# define __STL_NO_BAD_ALLOC +# endif +# if __GNUC__ == 2 && __GNUC_MINOR__ >= 8 +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_FUNCTION_TMPL_PARTIAL_ORDER +# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# define __STL_MEMBER_TEMPLATES +# define __STL_CAN_THROW_RANGE_ERRORS + // g++ 2.8.1 supports member template functions, but not member + // template nested classes. +# if __GNUC_MINOR__ >= 9 +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_TEMPLATE_FRIENDS +# define __SGI_STL_USE_AUTO_PTR_CONVERSIONS +# define __STL_HAS_NAMESPACES +//# define __STL_USE_NEW_IOSTREAMS +# endif +# endif +# define __STL_DEFAULT_CONSTRUCTOR_BUG +# ifdef __EXCEPTIONS +# define __STL_USE_EXCEPTIONS +# endif +# ifdef _REENTRANT +# define __STL_PTHREADS +# endif +# if (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) +# define __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE +# endif +# endif + +# if defined(__SUNPRO_CC) +# define __STL_NO_BOOL +# define __STL_NEED_TYPENAME +# define __STL_NEED_EXPLICIT +# define __STL_USE_EXCEPTIONS +# ifdef _REENTRANT +# define __STL_PTHREADS +# endif +# define __SGI_STL_NO_ARROW_OPERATOR +# define __STL_PARTIAL_SPECIALIZATION_SYNTAX +# define __STL_NO_EXCEPTION_HEADER +# define __STL_NO_BAD_ALLOC +# endif + +# if defined(__COMO__) +# define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_TEMPLATE_FRIENDS +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_USE_EXCEPTIONS +# define __STL_HAS_NAMESPACES +# endif + +// Intel compiler, which uses the EDG front end. +# if defined(__ICL) +# define __STL_LONG_LONG +# define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_TEMPLATE_FRIENDS +# define __STL_FUNCTION_TMPL_PARTIAL_ORDER +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_NO_DRAND48 +# define __STL_HAS_NAMESPACES +# define __STL_USE_EXCEPTIONS +# define __STL_MEMBER_TEMPLATE_KEYWORD +# ifdef _CPPUNWIND +# define __STL_USE_EXCEPTIONS +# endif +# ifdef _MT +# define __STL_WIN32THREADS +# endif +# endif + +// Mingw32, egcs compiler using the Microsoft C runtime +# if defined(__MINGW32__) +# define __STL_NO_DRAND48 +# ifdef _MT +# define __STL_WIN32THREADS +# endif +# endif + +// Cygwin32, egcs compiler on MS Windows +# if defined(__CYGWIN__) +# define __STL_NO_DRAND48 +# endif + + + +// Microsoft compiler. +# if defined(_MSC_VER) && !defined(__ICL) && !defined(__MWERKS__) +# define __STL_NO_DRAND48 +# define __STL_STATIC_CONST_INIT_BUG +# define __STL_NEED_TYPENAME +# define __STL_NO_USING_CLAUSE_IN_CLASS +# define __STL_NO_FRIEND_TEMPLATE_CLASS +# if _MSC_VER < 1100 /* 1000 is version 4.0, 1100 is 5.0, 1200 is 6.0. */ +# define __STL_NEED_EXPLICIT +# define __STL_NO_BOOL +# define __STL_NO_BAD_ALLOC +# endif +# if _MSC_VER > 1000 +# include +# define __STL_DONT_USE_BOOL_TYPEDEF +# endif +# define __STL_NON_TYPE_TMPL_PARAM_BUG +# define __SGI_STL_NO_ARROW_OPERATOR +# define __STL_DEFAULT_CONSTRUCTOR_BUG +# ifdef _CPPUNWIND +# define __STL_USE_EXCEPTIONS +# endif +# ifdef _MT +# define __STL_WIN32THREADS +# endif +# if _MSC_VER >= 1200 +# define __STL_PARTIAL_SPECIALIZATION_SYNTAX +# define __STL_HAS_NAMESPACES +# define __STL_CAN_THROW_RANGE_ERRORS +# define NOMINMAX +# undef min +# undef max +// disable warning 'initializers put in unrecognized initialization area' +# pragma warning ( disable : 4075 ) +// disable warning 'empty controlled statement found' +# pragma warning ( disable : 4390 ) +// disable warning 'debug symbol greater than 255 chars' +# pragma warning ( disable : 4786 ) +# endif +# if _MSC_VER < 1100 +# define __STL_NO_EXCEPTION_HEADER +# define __STL_NO_BAD_ALLOC +# endif + // Because of a Microsoft front end bug, we must not provide a + // namespace qualifier when declaring a friend function. +# define __STD_QUALIFIER +# endif + +# if defined(__BORLANDC__) +# define __STL_NO_BAD_ALLOC +# define __STL_NO_DRAND48 +# define __STL_DEFAULT_CONSTRUCTOR_BUG +# if __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */ +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_FUNCTION_TMPL_PARTIAL_ORDER +# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# define __STL_MEMBER_TEMPLATES +# define __STL_TEMPLATE_FRIENDS +# else +# define __STL_NEED_TYPENAME +# define __STL_LIMITED_DEFAULT_TEMPLATES +# define __SGI_STL_NO_ARROW_OPERATOR +# define __STL_NON_TYPE_TMPL_PARAM_BUG +# endif +# ifdef _CPPUNWIND +# define __STL_USE_EXCEPTIONS +# endif +# ifdef __MT__ +# define __STL_WIN32THREADS +# endif +# endif + +# if defined(__STL_NO_BOOL) && !defined(__STL_DONT_USE_BOOL_TYPEDEF) + typedef int bool; +# define true 1 +# define false 0 +# endif + +# ifdef __STL_NEED_TYPENAME +# define typename +# endif + +# ifdef __STL_LIMITED_DEFAULT_TEMPLATES +# define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) +# else +# define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp +# endif + +# ifdef __STL_MEMBER_TEMPLATE_KEYWORD +# define __STL_TEMPLATE template +# else +# define __STL_TEMPLATE +# endif + +# ifdef __STL_NEED_EXPLICIT +# define explicit +# endif + +# ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# define __STL_NULL_TMPL_ARGS <> +# else +# define __STL_NULL_TMPL_ARGS +# endif + +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ + || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX) +# define __STL_TEMPLATE_NULL template<> +# else +# define __STL_TEMPLATE_NULL +# endif + +// Use standard-conforming allocators if we have the necessary language +// features. __STL_USE_SGI_ALLOCATORS is a hook so that users can +// disable new-style allocators, and continue to use the same kind of +// allocators as before, without having to edit library headers. +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && \ + defined(__STL_MEMBER_TEMPLATES) && \ + defined(__STL_MEMBER_TEMPLATE_CLASSES) && \ + !defined(__STL_NO_BOOL) && \ + !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) && \ + !defined(__STL_LIMITED_DEFAULT_TEMPLATES) && \ + !defined(__STL_USE_SGI_ALLOCATORS) +# define __STL_USE_STD_ALLOCATORS +# endif + +# ifndef __STL_DEFAULT_ALLOCATOR +# ifdef __STL_USE_STD_ALLOCATORS +# define __STL_DEFAULT_ALLOCATOR(T) allocator< T > +# else +# define __STL_DEFAULT_ALLOCATOR(T) alloc +# endif +# endif + +// __STL_NO_NAMESPACES is a hook so that users can disable namespaces +// without having to edit library headers. __STL_NO_RELOPS_NAMESPACE is +// a hook so that users can disable the std::rel_ops namespace, keeping +// the relational operator template in namespace std, without having to +// edit library headers. +# if defined(__STL_HAS_NAMESPACES) && !defined(__STL_NO_NAMESPACES) +# define __STL_USE_NAMESPACES +# define __STD std +# define __STL_BEGIN_NAMESPACE namespace std { +# define __STL_END_NAMESPACE } +# if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ + !defined(__STL_NO_RELOPS_NAMESPACE) +# define __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_BEGIN_RELOPS_NAMESPACE namespace std { namespace rel_ops { +# define __STL_END_RELOPS_NAMESPACE } } +# define __STD_RELOPS std::rel_ops +# else /* Use std::rel_ops namespace */ +# define __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_BEGIN_RELOPS_NAMESPACE namespace std { +# define __STL_END_RELOPS_NAMESPACE } +# define __STD_RELOPS std +# endif /* Use std::rel_ops namespace */ +# else +# define __STD +# define __STL_BEGIN_NAMESPACE +# define __STL_END_NAMESPACE +# undef __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_BEGIN_RELOPS_NAMESPACE +# define __STL_END_RELOPS_NAMESPACE +# define __STD_RELOPS +# undef __STL_USE_NAMESPACES +# endif + +// Some versions of the EDG front end sometimes require an explicit +// namespace spec where they shouldn't. This macro facilitates that. +// If the bug becomes irrelevant, then all uses of __STD_QUALIFIER +// should be removed. The 7.3 beta SGI compiler has this bug, but the +// MR version is not expected to have it. + +# if defined(__STL_USE_NAMESPACES) && !defined(__STD_QUALIFIER) +# define __STD_QUALIFIER std:: +# else +# define __STD_QUALIFIER +# endif + +# ifdef __STL_USE_EXCEPTIONS +# define __STL_TRY try +# define __STL_CATCH_ALL catch(...) +# define __STL_THROW(x) throw x +# define __STL_RETHROW throw +# define __STL_NOTHROW throw() +# define __STL_UNWIND(action) catch(...) { action; throw; } +# else +# define __STL_TRY +# define __STL_CATCH_ALL if (false) +# define __STL_THROW(x) +# define __STL_RETHROW +# define __STL_NOTHROW +# define __STL_UNWIND(action) +# endif + +#ifdef __STL_ASSERTIONS +# include +# define __stl_assert(expr) \ + if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \ + __FILE__, __LINE__, # expr); abort(); } +#else +# define __stl_assert(expr) +#endif + +#if defined(__STL_WIN32THREADS) || defined(__STL_SGI_THREADS) \ + || defined(__STL_PTHREADS) || defined(__STL_UITHREADS) +# define __STL_THREADS +# define __STL_VOLATILE volatile +#else +# define __STL_VOLATILE +#endif + +#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ + && defined(__STL_MEMBER_TEMPLATES) \ + && !defined(_STL_NO_CONCEPT_CHECKS) +# define __STL_USE_CONCEPT_CHECKS +#endif + + +#endif /* __STL_CONFIG_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_construct.h b/darkice/tags/darkice-0_2/stl/stl_construct.h new file mode 100644 index 0000000..a17f9ee --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_construct.h @@ -0,0 +1,124 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#define __SGI_STL_INTERNAL_CONSTRUCT_H + +#include + +__STL_BEGIN_NAMESPACE + +// construct and destroy. These functions are not part of the C++ standard, +// and are provided for backward compatibility with the HP STL. We also +// provide internal names _Construct and _Destroy that can be used within +// the library, so that standard-conforming pieces don't have to rely on +// non-standard extensions. + +// Internal names + +template +inline void _Construct(_T1* __p, const _T2& __value) { + new ((void*) __p) _T1(__value); +} + +template +inline void _Construct(_T1* __p) { + new ((void*) __p) _T1(); +} + +template +inline void _Destroy(_Tp* __pointer) { + __pointer->~_Tp(); +} + +template +void +__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type) +{ + for ( ; __first != __last; ++__first) + destroy(&*__first); +} + +template +inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {} + +template +inline void +__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*) +{ + typedef typename __type_traits<_Tp>::has_trivial_destructor + _Trivial_destructor; + __destroy_aux(__first, __last, _Trivial_destructor()); +} + +template +inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) { + __destroy(__first, __last, __VALUE_TYPE(__first)); +} + +inline void _Destroy(char*, char*) {} +inline void _Destroy(int*, int*) {} +inline void _Destroy(long*, long*) {} +inline void _Destroy(float*, float*) {} +inline void _Destroy(double*, double*) {} +#ifdef __STL_HAS_WCHAR_T +inline void _Destroy(wchar_t*, wchar_t*) {} +#endif /* __STL_HAS_WCHAR_T */ + +// -------------------------------------------------- +// Old names from the HP STL. + +template +inline void construct(_T1* __p, const _T2& __value) { + _Construct(__p, __value); +} + +template +inline void construct(_T1* __p) { + _Construct(__p); +} + +template +inline void destroy(_Tp* __pointer) { + _Destroy(__pointer); +} + +template +inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { + _Destroy(__first, __last); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_CONSTRUCT_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_ctraits_fns.h b/darkice/tags/darkice-0_2/stl/stl_ctraits_fns.h new file mode 100644 index 0000000..5577f4d --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_ctraits_fns.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +// WARNING: This is an internal header file, included by other C++ +// standard library headers. You should not attempt to use this header +// file directly. + +#ifndef __SGI_STL_INTERNAL_CTRAITS_FUNCTIONS_H +#define __SGI_STL_INTERNAL_CTRAITS_FUNCTIONS_H + +// This file contains a few small adapters that allow a character +// traits class to be used as a function object. + +__STL_BEGIN_NAMESPACE + +template +struct _Eq_traits + : public binary_function +{ + bool operator()(const typename _Traits::char_type& __x, + const typename _Traits::char_type& __y) const + { return _Traits::eq(__x, __y); } +}; + +template +struct _Eq_int_traits + : public binary_function +{ + bool operator()(const typename _Traits::char_type& __x, + const typename _Traits::int_type& __y) const + { return _Traits::eq_int_type(_Traits::to_int_type(__x), __y); } +}; + +template +struct _Lt_traits + : public binary_function +{ + bool operator()(const typename _Traits::char_type& __x, + const typename _Traits::char_type& __y) const + { return _Traits::lt(__x, __y); } +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_CTRAITS_FUNCTIONS_H */ + +// Local Variables: +// mode:C++ +// End: + + + + diff --git a/darkice/tags/darkice-0_2/stl/stl_deque.h b/darkice/tags/darkice-0_2/stl/stl_deque.h new file mode 100644 index 0000000..7978f7d --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_deque.h @@ -0,0 +1,1652 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#include + +#ifndef __SGI_STL_INTERNAL_DEQUE_H +#define __SGI_STL_INTERNAL_DEQUE_H + +/* Class invariants: + * For any nonsingular iterator i: + * i.node is the address of an element in the map array. The + * contents of i.node is a pointer to the beginning of a node. + * i.first == *(i.node) + * i.last == i.first + node_size + * i.cur is a pointer in the range [i.first, i.last). NOTE: + * the implication of this is that i.cur is always a dereferenceable + * pointer, even if i is a past-the-end iterator. + * Start and Finish are always nonsingular iterators. NOTE: this means + * that an empty deque must have one node, and that a deque + * with N elements, where N is the buffer size, must have two nodes. + * For every node other than start.node and finish.node, every element + * in the node is an initialized object. If start.node == finish.node, + * then [start.cur, finish.cur) are initialized objects, and + * the elements outside that range are uninitialized storage. Otherwise, + * [start.cur, start.last) and [finish.first, finish.cur) are initialized + * objects, and [start.first, start.cur) and [finish.cur, finish.last) + * are uninitialized storage. + * [map, map + map_size) is a valid, non-empty range. + * [start.node, finish.node] is a valid range contained within + * [map, map + map_size). + * A pointer in the range [map, map + map_size) points to an allocated node + * if and only if the pointer is in the range [start.node, finish.node]. + */ + + +/* + * In previous versions of deque, there was an extra template + * parameter so users could control the node size. This extension + * turns out to violate the C++ standard (it can be detected using + * template template parameters), and it has been removed. + */ + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Note: this function is simply a kludge to work around several compilers' +// bugs in handling constant expressions. +inline size_t __deque_buf_size(size_t __size) { + return __size < 512 ? size_t(512 / __size) : size_t(1); +} + +template +struct _Deque_iterator { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } + + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + + typedef _Deque_iterator _Self; + + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) {} + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) {} + + reference operator*() const { return *_M_cur; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return _M_cur; } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + difference_type operator-(const _Self& __x) const { + return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) + + (_M_cur - _M_first) + (__x._M_last - __x._M_cur); + } + + _Self& operator++() { + ++_M_cur; + if (_M_cur == _M_last) { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + ++*this; + return __tmp; + } + + _Self& operator--() { + if (_M_cur == _M_first) { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& operator+=(difference_type __n) + { + difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else { + difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + + (__offset - __node_offset * difference_type(_S_buffer_size())); + } + return *this; + } + + _Self operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } + + _Self& operator-=(difference_type __n) { return *this += -__n; } + + _Self operator-(difference_type __n) const { + _Self __tmp = *this; + return __tmp -= __n; + } + + reference operator[](difference_type __n) const { return *(*this + __n); } + + bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; } + bool operator!=(const _Self& __x) const { return !(*this == __x); } + bool operator<(const _Self& __x) const { + return (_M_node == __x._M_node) ? + (_M_cur < __x._M_cur) : (_M_node < __x._M_node); + } + bool operator>(const _Self& __x) const { return __x < *this; } + bool operator<=(const _Self& __x) const { return !(__x < *this); } + bool operator>=(const _Self& __x) const { return !(*this < __x); } + + void _M_set_node(_Map_pointer __new_node) { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); + } +}; + +template +inline _Deque_iterator<_Tp, _Ref, _Ptr> +operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) +{ + return __x + __n; +} + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline random_access_iterator_tag +iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&) +{ + return random_access_iterator_tag(); +} + +template +inline _Tp* value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } + +template +inline ptrdiff_t* distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { + return 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Deque base class. It has two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Deque_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Deque_alloc_base(const allocator_type& __a) + : _M_node_allocator(__a), _M_map_allocator(__a), + _M_map(0), _M_map_size(0) + {} + +protected: + typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type + _Map_allocator_type; + + allocator_type _M_node_allocator; + _Map_allocator_type _M_map_allocator; + + _Tp* _M_allocate_node() { + return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp))); + } + void _M_deallocate_node(_Tp* __p) { + _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp))); + } + _Tp** _M_allocate_map(size_t __n) + { return _M_map_allocator.allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _M_map_allocator.deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +// Specialization for instanceless allocators. +template +class _Deque_alloc_base<_Tp, _Alloc, true> +{ +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {} + +protected: + typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type; + typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type; + + _Tp* _M_allocate_node() { + return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); + } + void _M_deallocate_node(_Tp* __p) { + _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); + } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +template +class _Deque_base + : public _Deque_alloc_base<_Tp,_Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _Deque_alloc_base<_Tp,_Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _Base(__a), _M_start(), _M_finish() + { _M_initialize_map(__num_elements); } + _Deque_base(const allocator_type& __a) + : _Base(__a), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + iterator _M_start; + iterator _M_finish; +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Deque_base { +public: + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_base(const allocator_type&, size_t __num_elements) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() { + _M_initialize_map(__num_elements); + } + _Deque_base(const allocator_type&) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + typedef simple_alloc<_Tp, _Alloc> _Node_alloc_type; + typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type; + + _Tp* _M_allocate_node() + { return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); } + void _M_deallocate_node(_Tp* __p) + { _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +// Non-inline member functions from _Deque_base. + +template +_Deque_base<_Tp,_Alloc>::~_Deque_base() { + if (_M_map) { + _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1); + _M_deallocate_map(_M_map, _M_map_size); + } +} + +template +void +_Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) +{ + size_t __num_nodes = + __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; + + _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2); + _M_map = _M_allocate_map(_M_map_size); + + _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + __STL_TRY { + _M_create_nodes(__nstart, __nfinish); + } + __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), + _M_map = 0, _M_map_size = 0)); + _M_start._M_set_node(__nstart); + _M_finish._M_set_node(__nfinish - 1); + _M_start._M_cur = _M_start._M_first; + _M_finish._M_cur = _M_finish._M_first + + __num_elements % __deque_buf_size(sizeof(_Tp)); +} + +template +void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) +{ + _Tp** __cur; + __STL_TRY { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = _M_allocate_node(); + } + __STL_UNWIND(_M_destroy_nodes(__nstart, __cur)); +} + +template +void +_Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) +{ + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); +} + +template +class deque : protected _Deque_base<_Tp, _Alloc> { + + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + + typedef _Deque_base<_Tp, _Alloc> _Base; +public: // Basic types + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +public: // Iterators + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator + const_reverse_iterator; + typedef reverse_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: // Internal typedefs + typedef pointer* _Map_pointer; + static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + + using _Base::_M_map; + using _Base::_M_map_size; + using _Base::_M_start; + using _Base::_M_finish; +#endif /* __STL_USE_NAMESPACES */ + +public: // Basic accessors + iterator begin() { return _M_start; } + iterator end() { return _M_finish; } + const_iterator begin() const { return _M_start; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() { return reverse_iterator(_M_finish); } + reverse_iterator rend() { return reverse_iterator(_M_start); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(_M_finish); } + const_reverse_iterator rend() const + { return const_reverse_iterator(_M_start); } + + reference operator[](size_type __n) + { return _M_start[difference_type(__n)]; } + const_reference operator[](size_type __n) const + { return _M_start[difference_type(__n)]; } + +#ifdef __STL_THROW_RANGE_ERRORS + void _M_range_check(size_type __n) const { + if (__n >= this->size()) + __stl_throw_range_error("deque"); + } + + reference at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + const_reference at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } +#endif /* __STL_THROW_RANGE_ERRORS */ + + reference front() { return *_M_start; } + reference back() { + iterator __tmp = _M_finish; + --__tmp; + return *__tmp; + } + const_reference front() const { return *_M_start; } + const_reference back() const { + const_iterator __tmp = _M_finish; + --__tmp; + return *__tmp; + } + + size_type size() const { return _M_finish - _M_start; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return _M_finish == _M_start; } + +public: // Constructor, destructor. + explicit deque(const allocator_type& __a = allocator_type()) + : _Base(__a, 0) {} + deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) + { uninitialized_copy(__x.begin(), __x.end(), _M_start); } + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a, __n) + { _M_fill_initialize(__value); } + explicit deque(size_type __n) : _Base(allocator_type(), __n) + { _M_fill_initialize(value_type()); } + +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + template + void _M_initialize_dispatch(_InputIter __first, _InputIter __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + deque(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } + deque(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } + +#endif /* __STL_MEMBER_TEMPLATES */ + + ~deque() { destroy(_M_start, _M_finish); } + + deque& operator= (const deque& __x) { + const size_type __len = size(); + if (&__x != this) { + if (__len >= __x.size()) + erase(copy(__x.begin(), __x.end(), _M_start), _M_finish); + else { + const_iterator __mid = __x.begin() + difference_type(__len); + copy(__x.begin(), __mid, _M_start); + insert(_M_finish, __mid, __x.end()); + } + } + return *this; + } + + void swap(deque& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_map, __x._M_map); + __STD::swap(_M_map_size, __x._M_map_size); + } + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void _M_fill_assign(size_type __n, const _Tp& __val) { + if (__n > size()) { + fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else { + erase(begin() + __n, end()); + fill(begin(), end(), __val); + } + } + + void assign(size_type __n, const _Tp& __val) { + _M_fill_assign(__n, __val); + } + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + +private: // helper functions for assign() + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); + } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len > size()) { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + erase(copy(__first, __last, begin()), end()); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: // push_* and pop_* + + void push_back(const value_type& __t) { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur, __t); + ++_M_finish._M_cur; + } + else + _M_push_back_aux(__t); + } + + void push_back() { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur); + ++_M_finish._M_cur; + } + else + _M_push_back_aux(); + } + + void push_front(const value_type& __t) { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1, __t); + --_M_start._M_cur; + } + else + _M_push_front_aux(__t); + } + + void push_front() { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1); + --_M_start._M_cur; + } + else + _M_push_front_aux(); + } + + + void pop_back() { + if (_M_finish._M_cur != _M_finish._M_first) { + --_M_finish._M_cur; + destroy(_M_finish._M_cur); + } + else + _M_pop_back_aux(); + } + + void pop_front() { + if (_M_start._M_cur != _M_start._M_last - 1) { + destroy(_M_start._M_cur); + ++_M_start._M_cur; + } + else + _M_pop_front_aux(); + } + +public: // Insert + + iterator insert(iterator position, const value_type& __x) { + if (position._M_cur == _M_start._M_cur) { + push_front(__x); + return _M_start; + } + else if (position._M_cur == _M_finish._M_cur) { + push_back(__x); + iterator __tmp = _M_finish; + --__tmp; + return __tmp; + } + else { + return _M_insert_aux(position, __x); + } + } + + iterator insert(iterator __position) + { return insert(__position, value_type()); } + + void insert(iterator __pos, size_type __n, const value_type& __x) + { _M_fill_insert(__pos, __n, __x); } + + void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + _M_fill_insert(__pos, (size_type) __n, (value_type) __x); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert(iterator __pos, + const value_type* __first, const value_type* __last); + void insert(iterator __pos, + const_iterator __first, const_iterator __last); + +#endif /* __STL_MEMBER_TEMPLATES */ + + void resize(size_type __new_size, const value_type& __x) { + const size_type __len = size(); + if (__new_size < __len) + erase(_M_start + __new_size, _M_finish); + else + insert(_M_finish, __new_size - __len, __x); + } + + void resize(size_type new_size) { resize(new_size, value_type()); } + +public: // Erase + iterator erase(iterator __pos) { + iterator __next = __pos; + ++__next; + difference_type __index = __pos - _M_start; + if (size_type(__index) < (this->size() >> 1)) { + copy_backward(_M_start, __pos, __next); + pop_front(); + } + else { + copy(__next, _M_finish, __pos); + pop_back(); + } + return _M_start + __index; + } + + iterator erase(iterator __first, iterator __last); + void clear(); + +protected: // Internal construction/destruction + + void _M_fill_initialize(const value_type& __value); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + +protected: // Internal push_* and pop_* + + void _M_push_back_aux(const value_type&); + void _M_push_back_aux(); + void _M_push_front_aux(const value_type&); + void _M_push_front_aux(); + void _M_pop_back_aux(); + void _M_pop_front_aux(); + +protected: // Internal insert functions + +#ifdef __STL_MEMBER_TEMPLATES + + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator _M_insert_aux(iterator __pos, const value_type& __x); + iterator _M_insert_aux(iterator __pos); + void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + +#else /* __STL_MEMBER_TEMPLATES */ + + void _M_insert_aux(iterator __pos, + const value_type* __first, const value_type* __last, + size_type __n); + + void _M_insert_aux(iterator __pos, + const_iterator __first, const_iterator __last, + size_type __n); + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator _M_reserve_elements_at_front(size_type __n) { + size_type __vacancies = _M_start._M_cur - _M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return _M_start - difference_type(__n); + } + + iterator _M_reserve_elements_at_back(size_type __n) { + size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return _M_finish + difference_type(__n); + } + + void _M_new_elements_at_front(size_type __new_elements); + void _M_new_elements_at_back(size_type __new_elements); + +protected: // Allocation of _M_map and nodes + + // Makes sure the _M_map has space for new nodes. Does not actually + // add the nodes. Can invalidate _M_map pointers. (And consequently, + // deque iterators.) + + void _M_reserve_map_at_back (size_type __nodes_to_add = 1) { + if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, false); + } + + void _M_reserve_map_at_front (size_type __nodes_to_add = 1) { + if (__nodes_to_add > size_type(_M_start._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, true); + } + + void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); +}; + +// Non-inline member functions + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void deque<_Tp, _Alloc> + ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) +{ + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos, + size_type __n, const value_type& __x) +{ + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + __STL_TRY { + uninitialized_fill(__new_start, _M_start, __x); + _M_start = __new_start; + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + __STL_TRY { + uninitialized_fill(_M_finish, __new_finish, __x); + _M_finish = __new_finish; + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } + else + _M_insert_aux(__pos, __n, __x); +} + +#ifndef __STL_MEMBER_TEMPLATES + +template +void deque<_Tp, _Alloc>::insert(iterator __pos, + const value_type* __first, + const value_type* __last) { + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + __STL_TRY { + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } + else + _M_insert_aux(__pos, __first, __last, __n); +} + +template +void deque<_Tp,_Alloc>::insert(iterator __pos, + const_iterator __first, const_iterator __last) +{ + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + __STL_TRY { + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } + else + _M_insert_aux(__pos, __first, __last, __n); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +typename deque<_Tp,_Alloc>::iterator +deque<_Tp,_Alloc>::erase(iterator __first, iterator __last) +{ + if (__first == _M_start && __last == _M_finish) { + clear(); + return _M_finish; + } + else { + difference_type __n = __last - __first; + difference_type __elems_before = __first - _M_start; + if (__elems_before < difference_type((this->size() - __n) / 2)) { + copy_backward(_M_start, __first, __last); + iterator __new_start = _M_start + __n; + destroy(_M_start, __new_start); + _M_destroy_nodes(__new_start._M_node, _M_start._M_node); + _M_start = __new_start; + } + else { + copy(__last, _M_finish, __first); + iterator __new_finish = _M_finish - __n; + destroy(__new_finish, _M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1); + _M_finish = __new_finish; + } + return _M_start + __elems_before; + } +} + +template +void deque<_Tp,_Alloc>::clear() +{ + for (_Map_pointer __node = _M_start._M_node + 1; + __node < _M_finish._M_node; + ++__node) { + destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); + } + + if (_M_start._M_node != _M_finish._M_node) { + destroy(_M_start._M_cur, _M_start._M_last); + destroy(_M_finish._M_first, _M_finish._M_cur); + _M_deallocate_node(_M_finish._M_first); + } + else + destroy(_M_start._M_cur, _M_finish._M_cur); + + _M_finish = _M_start; +} + +// Precondition: _M_start and _M_finish have already been initialized, +// but none of the deque's elements have yet been constructed. +template +void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value) { + _Map_pointer __cur; + __STL_TRY { + for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur) + uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); + uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value); + } + __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur))); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + _M_initialize_map(0); + __STL_TRY { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + __STL_UNWIND(clear()); +} + +template template +void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) +{ + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize_map(__n); + + _Map_pointer __cur_node; + __STL_TRY { + for (__cur_node = _M_start._M_node; + __cur_node < _M_finish._M_node; + ++__cur_node) { + _ForwardIterator __mid = __first; + advance(__mid, _S_buffer_size()); + uninitialized_copy(__first, __mid, *__cur_node); + __first = __mid; + } + uninitialized_copy(__first, __last, _M_finish._M_first); + } + __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node))); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template +void deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); + __STL_TRY { + construct(_M_finish._M_cur, __t_copy); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; + } + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); +} + +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template +void deque<_Tp,_Alloc>::_M_push_back_aux() +{ + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); + __STL_TRY { + construct(_M_finish._M_cur); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; + } + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); +} + +// Called only if _M_start._M_cur == _M_start._M_first. +template +void deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); + __STL_TRY { + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur, __t_copy); + } + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); +} + +// Called only if _M_start._M_cur == _M_start._M_first. +template +void deque<_Tp,_Alloc>::_M_push_front_aux() +{ + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); + __STL_TRY { + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur); + } + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); +} + +// Called only if _M_finish._M_cur == _M_finish._M_first. +template +void deque<_Tp,_Alloc>::_M_pop_back_aux() +{ + _M_deallocate_node(_M_finish._M_first); + _M_finish._M_set_node(_M_finish._M_node - 1); + _M_finish._M_cur = _M_finish._M_last - 1; + destroy(_M_finish._M_cur); +} + +// Called only if _M_start._M_cur == _M_start._M_last - 1. Note that +// if the deque has at least one element (a precondition for this member +// function), and if _M_start._M_cur == _M_start._M_last, then the deque +// must have at least two nodes. +template +void deque<_Tp,_Alloc>::_M_pop_front_aux() +{ + destroy(_M_start._M_cur); + _M_deallocate_node(_M_start._M_first); + _M_start._M_set_node(_M_start._M_node + 1); + _M_start._M_cur = _M_start._M_first; +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void deque<_Tp,_Alloc>::insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) +{ + copy(__first, __last, inserter(*this, __pos)); +} + +template template +void +deque<_Tp,_Alloc>::insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + __STL_TRY { + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } + else + _M_insert_aux(__pos, __first, __last, __n); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +typename deque<_Tp, _Alloc>::iterator +deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x) +{ + difference_type __index = __pos - _M_start; + value_type __x_copy = __x; + if (size_type(__index) < this->size() / 2) { + push_front(front()); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); + } + else { + push_back(back()); + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = __x_copy; + return __pos; +} + +template +typename deque<_Tp,_Alloc>::iterator +deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos) +{ + difference_type __index = __pos - _M_start; + if (__index < size() / 2) { + push_front(front()); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); + } + else { + push_back(back()); + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = value_type(); + return __pos; +} + +template +void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, + size_type __n, + const value_type& __x) +{ + const difference_type __elems_before = __pos - _M_start; + size_type __length = this->size(); + value_type __x_copy = __x; + if (__elems_before < difference_type(__length / 2)) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elems_before; + __STL_TRY { + if (__elems_before >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); + } + else { + __uninitialized_copy_fill(_M_start, __pos, __new_start, + _M_start, __x_copy); + _M_start = __new_start; + fill(__old_start, __pos, __x_copy); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = _M_finish - __elems_after; + __STL_TRY { + if (__elems_after > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + fill(__pos, __pos + difference_type(__n), __x_copy); + } + else { + __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n), + __x_copy, __pos, _M_finish); + _M_finish = __new_finish; + fill(__pos, __old_finish, __x_copy); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, + _ForwardIterator __first, + _ForwardIterator __last, + size_type __n) +{ + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; + __STL_TRY { + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); + } + else { + _ForwardIterator __mid = __first; + advance(__mid, difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; + __STL_TRY { + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); + } + else { + _ForwardIterator __mid = __first; + advance(__mid, __elemsafter); + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, + const value_type* __first, + const value_type* __last, + size_type __n) +{ + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; + __STL_TRY { + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); + } + else { + const value_type* __mid = + __first + (difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; + __STL_TRY { + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); + } + else { + const value_type* __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +template +void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, + const_iterator __first, + const_iterator __last, + size_type __n) +{ + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; + __STL_TRY { + if (__elemsbefore >= __n) { + iterator __start_n = _M_start + __n; + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); + } + else { + const_iterator __mid = __first + (__n - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = __length - __elemsbefore; + __pos = _M_finish - __elemsafter; + __STL_TRY { + if (__elemsafter > __n) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); + } + else { + const_iterator __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_front(__new_nodes); + size_type __i; + __STL_TRY { + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_start._M_node - __i) = _M_allocate_node(); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_start._M_node - __j)); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +template +void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_back(__new_nodes); + size_type __i; + __STL_TRY { + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_finish._M_node + __i) = _M_allocate_node(); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_finish._M_node + __j)); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +template +void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add, + bool __add_at_front) +{ + size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1; + size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (_M_map_size > 2 * __new_num_nodes) { + __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < _M_start._M_node) + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); + else + copy_backward(_M_start._M_node, _M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } + else { + size_type __new_map_size = + _M_map_size + max(_M_map_size, __nodes_to_add) + 2; + + _Map_pointer __new_map = _M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); + _M_deallocate_map(_M_map, _M_map_size); + + _M_map = __new_map; + _M_map_size = __new_map_size; + } + + _M_start._M_set_node(__new_nstart); + _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); +} + + +// Nonmember functions. + +template +inline bool operator==(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline bool operator<(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return !(__y < __x); +} +template +inline bool operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return !(__x < __y); +} + +template +inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_exception.h b/darkice/tags/darkice-0_2/stl/stl_exception.h new file mode 100644 index 0000000..37b54d7 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_exception.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_EXCEPTION_H +#define __SGI_STL_EXCEPTION_H + +// This header exists solely for portability. Normally it just includes +// the header . + +// The header contains low-level functions that interact +// with a compiler's exception-handling mechanism. It is assumed to +// be supplied with the compiler, rather than with the library, because +// it is inherently tied very closely to the compiler itself. + +// On platforms where does not exist, this header defines +// an exception base class. This is *not* a substitute for everything +// in , but it suffices to support a bare minimum of STL +// functionality. + +#include + +#ifndef __STL_NO_EXCEPTION_HEADER + +#include +#define __STL_EXCEPTION_BASE exception + +#else /* __STL_NO_EXCEPTION_HEADER */ + +__STL_BEGIN_NAMESPACE + +class _Exception { +public: + virtual ~_Exception() __STL_NOTHROW {} + virtual const char* what() const __STL_NOTHROW { return ""; } +}; + +#define __STL_EXCEPTION_BASE _Exception + +__STL_END_NAMESPACE + +#endif /* __STL_NO_EXCEPTION_HEADER */ + +#endif /* __SGI_STL_EXCEPTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_function.h b/darkice/tags/darkice-0_2/stl/stl_function.h new file mode 100644 index 0000000..90752e2 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_function.h @@ -0,0 +1,725 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_FUNCTION_H +#define __SGI_STL_INTERNAL_FUNCTION_H + +__STL_BEGIN_NAMESPACE + +template +struct unary_function { + typedef _Arg argument_type; + typedef _Result result_type; +}; + +template +struct binary_function { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; +}; + +template +struct plus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } +}; + +template +struct minus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } +}; + +template +struct multiplies : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } +}; + +template +struct divides : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } +}; + +// identity_element (not part of the C++ standard). + +template inline _Tp identity_element(plus<_Tp>) { + return _Tp(0); +} +template inline _Tp identity_element(multiplies<_Tp>) { + return _Tp(1); +} + +template +struct modulus : public binary_function<_Tp,_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } +}; + +template +struct negate : public unary_function<_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x) const { return -__x; } +}; + +template +struct equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } +}; + +template +struct not_equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } +}; + +template +struct greater : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } +}; + +template +struct less : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } +}; + +template +struct greater_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } +}; + +template +struct less_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } +}; + +template +struct logical_and : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } +}; + +template +struct logical_or : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } +}; + +template +struct logical_not : public unary_function<_Tp,bool> +{ + bool operator()(const _Tp& __x) const { return !__x; } +}; + +template +class unary_negate + : public unary_function { +protected: + _Predicate _M_pred; +public: + explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::argument_type& __x) const { + return !_M_pred(__x); + } +}; + +template +inline unary_negate<_Predicate> +not1(const _Predicate& __pred) +{ + return unary_negate<_Predicate>(__pred); +} + +template +class binary_negate + : public binary_function { +protected: + _Predicate _M_pred; +public: + explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { + return !_M_pred(__x, __y); + } +}; + +template +inline binary_negate<_Predicate> +not2(const _Predicate& __pred) +{ + return binary_negate<_Predicate>(__pred); +} + +template +class binder1st + : public unary_function { +protected: + _Operation op; + typename _Operation::first_argument_type value; +public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + return op(value, __x); + } +}; + +template +inline binder1st<_Operation> +bind1st(const _Operation& __fn, const _Tp& __x) +{ + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); +} + +template +class binder2nd + : public unary_function { +protected: + _Operation op; + typename _Operation::second_argument_type value; +public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + return op(__x, value); + } +}; + +template +inline binder2nd<_Operation> +bind2nd(const _Operation& __fn, const _Tp& __x) +{ + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); +} + +// unary_compose and binary_compose (extensions, not part of the standard). + +template +class unary_compose + : public unary_function +{ +protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; +public: + unary_compose(const _Operation1& __x, const _Operation2& __y) + : _M_fn1(__x), _M_fn2(__y) {} + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_fn1(_M_fn2(__x)); + } +}; + +template +inline unary_compose<_Operation1,_Operation2> +compose1(const _Operation1& __fn1, const _Operation2& __fn2) +{ + return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); +} + +template +class binary_compose + : public unary_function { +protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; + _Operation3 _M_fn3; +public: + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_fn1(_M_fn2(__x), _M_fn3(__x)); + } +}; + +template +inline binary_compose<_Operation1, _Operation2, _Operation3> +compose2(const _Operation1& __fn1, const _Operation2& __fn2, + const _Operation3& __fn3) +{ + return binary_compose<_Operation1,_Operation2,_Operation3> + (__fn1, __fn2, __fn3); +} + +template +class pointer_to_unary_function : public unary_function<_Arg, _Result> { +protected: + _Result (*_M_ptr)(_Arg); +public: + pointer_to_unary_function() {} + explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} + _Result operator()(_Arg __x) const { return _M_ptr(__x); } +}; + +template +inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) +{ + return pointer_to_unary_function<_Arg, _Result>(__x); +} + +template +class pointer_to_binary_function : + public binary_function<_Arg1,_Arg2,_Result> { +protected: + _Result (*_M_ptr)(_Arg1, _Arg2); +public: + pointer_to_binary_function() {} + explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + _Result operator()(_Arg1 __x, _Arg2 __y) const { + return _M_ptr(__x, __y); + } +}; + +template +inline pointer_to_binary_function<_Arg1,_Arg2,_Result> +ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { + return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x); +} + +// identity is an extensions: it is not part of the standard. +template +struct _Identity : public unary_function<_Tp,_Tp> { + const _Tp& operator()(const _Tp& __x) const { return __x; } +}; + +template struct identity : public _Identity<_Tp> {}; + +// select1st and select2nd are extensions: they are not part of the standard. +template +struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { + const typename _Pair::first_type& operator()(const _Pair& __x) const { + return __x.first; + } +}; + +template +struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> +{ + const typename _Pair::second_type& operator()(const _Pair& __x) const { + return __x.second; + } +}; + +template struct select1st : public _Select1st<_Pair> {}; +template struct select2nd : public _Select2nd<_Pair> {}; + +// project1st and project2nd are extensions: they are not part of the standard +template +struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { + _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } +}; + +template +struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { + _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } +}; + +template +struct project1st : public _Project1st<_Arg1, _Arg2> {}; + +template +struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; + +// constant_void_fun, constant_unary_fun, and constant_binary_fun are +// extensions: they are not part of the standard. (The same, of course, +// is true of the helper functions constant0, constant1, and constant2.) + +template +struct _Constant_void_fun { + typedef _Result result_type; + result_type _M_val; + + _Constant_void_fun(const result_type& __v) : _M_val(__v) {} + const result_type& operator()() const { return _M_val; } +}; + +template +struct _Constant_unary_fun { + typedef _Argument argument_type; + typedef _Result result_type; + result_type _M_val; + + _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} + const result_type& operator()(const _Argument&) const { return _M_val; } +}; + +template +struct _Constant_binary_fun { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; + _Result _M_val; + + _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} + const result_type& operator()(const _Arg1&, const _Arg2&) const { + return _M_val; + } +}; + +template +struct constant_void_fun : public _Constant_void_fun<_Result> { + constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} +}; + + +template +struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> +{ + constant_unary_fun(const _Result& __v) + : _Constant_unary_fun<_Result, _Argument>(__v) {} +}; + + +template +struct constant_binary_fun + : public _Constant_binary_fun<_Result, _Arg1, _Arg2> +{ + constant_binary_fun(const _Result& __v) + : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} +}; + +template +inline constant_void_fun<_Result> constant0(const _Result& __val) +{ + return constant_void_fun<_Result>(__val); +} + +template +inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) +{ + return constant_unary_fun<_Result,_Result>(__val); +} + +template +inline constant_binary_fun<_Result,_Result,_Result> +constant2(const _Result& __val) +{ + return constant_binary_fun<_Result,_Result,_Result>(__val); +} + +// subtractive_rng is an extension: it is not part of the standard. +// Note: this code assumes that int is 32 bits. +class subtractive_rng : public unary_function { +private: + unsigned int _M_table[55]; + size_t _M_index1; + size_t _M_index2; +public: + unsigned int operator()(unsigned int __limit) { + _M_index1 = (_M_index1 + 1) % 55; + _M_index2 = (_M_index2 + 1) % 55; + _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; + return _M_table[_M_index1] % __limit; + } + + void _M_initialize(unsigned int __seed) + { + unsigned int __k = 1; + _M_table[54] = __seed; + size_t __i; + for (__i = 0; __i < 54; __i++) { + size_t __ii = (21 * (__i + 1) % 55) - 1; + _M_table[__ii] = __k; + __k = __seed - __k; + __seed = _M_table[__ii]; + } + for (int __loop = 0; __loop < 4; __loop++) { + for (__i = 0; __i < 55; __i++) + _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; + } + _M_index1 = 0; + _M_index2 = 31; + } + + subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } + subtractive_rng() { _M_initialize(161803398u); } +}; + + +// Adaptor function objects: pointers to member functions. + +// There are a total of 16 = 2^4 function objects in this family. +// (1) Member functions taking no arguments vs member functions taking +// one argument. +// (2) Call through pointer vs call through reference. +// (3) Member function with void return type vs member function with +// non-void return type. +// (4) Const vs non-const member function. + +// Note that choice (3) is nothing more than a workaround: according +// to the draft, compilers should handle void and non-void the same way. +// This feature is not yet widely implemented, though. You can only use +// member functions returning void if your compiler supports partial +// specialization. + +// All of this complexity is in the function objects themselves. You can +// ignore it by using the helper function mem_fun and mem_fun_ref, +// which create whichever type of adaptor is appropriate. +// (mem_fun1 and mem_fun1_ref are no longer part of the C++ standard, +// but they are provided for backward compatibility.) + + +template +class mem_fun_t : public unary_function<_Tp*,_Ret> { +public: + explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } +private: + _Ret (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_t : public unary_function { +public: + explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + + +template +class mem_fun_ref_t : public unary_function<_Tp,_Ret> { +public: + explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } +private: + _Ret (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { +public: + explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + +template +class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { +public: + explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_t : public binary_function { +public: + explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + +template +class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { +public: + explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { +public: + explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +class mem_fun_t : public unary_function<_Tp*,void> { +public: + explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp* __p) const { (__p->*_M_f)(); } +private: + void (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_t : public unary_function { +public: + explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp* __p) const { (__p->*_M_f)(); } +private: + void (_Tp::*_M_f)() const; +}; + +template +class mem_fun_ref_t : public unary_function<_Tp,void> { +public: + explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp& __r) const { (__r.*_M_f)(); } +private: + void (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_ref_t : public unary_function<_Tp,void> { +public: + explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp& __r) const { (__r.*_M_f)(); } +private: + void (_Tp::*_M_f)() const; +}; + +template +class mem_fun1_t : public binary_function<_Tp*,_Arg,void> { +public: + explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_t + : public binary_function { +public: + explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg) const; +}; + +template +class mem_fun1_ref_t + : public binary_function<_Tp,_Arg,void> { +public: + explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_ref_t + : public binary_function<_Tp,_Arg,void> { +public: + explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg) const; +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Mem_fun adaptor helper functions. There are only two: +// mem_fun and mem_fun_ref. (mem_fun1 and mem_fun1_ref +// are provided for backward compatibility, but they are no longer +// part of the C++ standard.) + +template +inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret,_Tp>(__f); } + +template +inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret,_Tp>(__f); } + +template +inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret,_Tp>(__f); } + +template +inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret,_Tp>(__f); } + +template +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_hash_fun.h b/darkice/tags/darkice-0_2/stl/stl_hash_fun.h new file mode 100644 index 0000000..44ab9bb --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_hash_fun.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_HASH_FUN_H +#define __SGI_STL_HASH_FUN_H + +#include + +__STL_BEGIN_NAMESPACE + +template struct hash { }; + +inline size_t __stl_hash_string(const char* __s) +{ + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5*__h + *__s; + + return size_t(__h); +} + +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } +}; + +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } +}; + +__STL_TEMPLATE_NULL struct hash { + size_t operator()(char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(short __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned short __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(int __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned int __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(long __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned long __x) const { return __x; } +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_HASH_FUN_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_hash_map.h b/darkice/tags/darkice-0_2/stl/stl_hash_map.h new file mode 100644 index 0000000..0d5bc8a --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_hash_map.h @@ -0,0 +1,532 @@ +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_HASH_MAP_H +#define __SGI_STL_INTERNAL_HASH_MAP_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Forward declaration of equality operator; needed for friend declaration. + +template ), + class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Key>), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +class hash_map; + +template +inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, + const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); + +template +class hash_map +{ + // requirements: + + __STL_CLASS_REQUIRES(_Key, _Assignable); + __STL_CLASS_REQUIRES(_Tp, _Assignable); + __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Key); + __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Key, _Key); + +private: + typedef hashtable,_Key,_HashFcn, + _Select1st >,_EqualKey,_Alloc> _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_map(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + +#else + hash_map(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_map(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } + +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, + const hash_map<_K1, _T1, _HF, _EqK, _Al>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); +#endif /* __STL_MEMBER_TEMPLATES */ + + + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } + +public: + pair insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + pair insert_noresize(const value_type& __obj) + { return _M_ht.insert_unique_noresize(__obj); } + + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } + + _Tp& operator[](const key_type& __key) { + return _M_ht.find_or_insert(value_type(__key, _Tp())).second; + } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + return __hm1._M_ht == __hm2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { + return !(__hm1 == __hm2); +} + +template +inline void +swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + __hm1.swap(__hm2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Forward declaration of equality operator; needed for friend declaration. + +template ), + class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Key>), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +class hash_multimap; + +template +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2); + +template +class hash_multimap +{ + // requirements: + + __STL_CLASS_REQUIRES(_Key, _Assignable); + __STL_CLASS_REQUIRES(_Tp, _Assignable); + __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Key); + __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Key, _Key); + +private: + typedef hashtable, _Key, _HashFcn, + _Select1st >, _EqualKey, _Alloc> + _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multimap(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + +#else + hash_multimap(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multimap(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } + +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, + const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const hash_multimap&,const hash_multimap&); +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } + +public: + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + iterator insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) +{ + return __hm1._M_ht == __hm2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { + return !(__hm1 == __hm2); +} + +template +inline void +swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + __hm1.swap(__hm2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Specialization of insert_iterator so that it will work for hash_map +// and hash_multimap. + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +class insert_iterator > { +protected: + typedef hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +template +class insert_iterator > { +protected: + typedef hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_hash_set.h b/darkice/tags/darkice-0_2/stl/stl_hash_set.h new file mode 100644 index 0000000..a4b845b --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_hash_set.h @@ -0,0 +1,514 @@ +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_HASH_SET_H +#define __SGI_STL_INTERNAL_HASH_SET_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Forward declaration of equality operator; needed for friend declaration. + +template ), + class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Value>), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > +class hash_set; + +template +inline bool +operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); + +template +class hash_set +{ + // requirements: + + __STL_CLASS_REQUIRES(_Value, _Assignable); + __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Value); + __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Value, _Value); + +private: + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::const_pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::const_reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_set() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_set(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } +#else + + hash_set(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_set(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } + +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const hash_set<_Val, _HF, _EqK, _Al>&, + const hash_set<_Val, _HF, _EqK, _Al>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const hash_set&, const hash_set&); +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } + +public: + pair insert(const value_type& __obj) + { + pair __p = _M_ht.insert_unique(__obj); + return pair(__p.first, __p.second); + } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + {_M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + pair insert_noresize(const value_type& __obj) + { + pair __p = + _M_ht.insert_unique_noresize(__obj); + return pair(__p.first, __p.second); + } + + iterator find(const key_type& __key) const { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + return __hs1._M_ht == __hs2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { + return !(__hs1 == __hs2); +} + +template +inline void +swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + __hs1.swap(__hs2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template ), + class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Value>), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > +class hash_multiset; + +template +inline bool +operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2); + + +template +class hash_multiset +{ + // requirements: + + __STL_CLASS_REQUIRES(_Value, _Assignable); + __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Value); + __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Value, _Value); + +private: + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::const_pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::const_reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_multiset() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multiset(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } +#else + + hash_multiset(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multiset(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } + +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const hash_multiset<_Val, _HF, _EqK, _Al>&, + const hash_multiset<_Val, _HF, _EqK, _Al>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const hash_multiset&,const hash_multiset&); +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } + +public: + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + iterator insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + iterator find(const key_type& __key) const { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + return __hs1._M_ht == __hs2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + return !(__hs1 == __hs2); +} + +template +inline void +swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + __hs1.swap(__hs2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Specialization of insert_iterator so that it will work for hash_set +// and hash_multiset. + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +class insert_iterator > { +protected: + typedef hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Container; + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +template +class insert_iterator > { +protected: + typedef hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> _Container; + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASH_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_hashtable.h b/darkice/tags/darkice-0_2/stl/stl_hashtable.h new file mode 100644 index 0000000..04a0823 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_hashtable.h @@ -0,0 +1,1054 @@ +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#define __SGI_STL_INTERNAL_HASHTABLE_H + +// Hashtable class, used to implement the hashed associative containers +// hash_set, hash_map, hash_multiset, and hash_multimap. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +__STL_BEGIN_NAMESPACE + +template +struct _Hashtable_node +{ + _Hashtable_node* _M_next; + _Val _M_val; +}; + +template +class hashtable; + +template +struct _Hashtable_iterator; + +template +struct _Hashtable_const_iterator; + +template +struct _Hashtable_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _Val& reference; + typedef _Val* pointer; + + _Node* _M_cur; + _Hashtable* _M_ht; + + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_iterator() {} + reference operator*() const { return _M_cur->_M_val; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + iterator& operator++(); + iterator operator++(int); + bool operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + + +template +struct _Hashtable_const_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_const_iterator() {} + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {} + reference operator*() const { return _M_cur->_M_val; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + const_iterator& operator++(); + const_iterator operator++(int); + bool operator==(const const_iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const const_iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + +// Note: assumes long is at least 32 bits. +enum { __stl_num_primes = 28 }; + +static const unsigned long __stl_prime_list[__stl_num_primes] = +{ + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul +}; + +inline unsigned long __stl_next_prime(unsigned long __n) +{ + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + (int)__stl_num_primes; + const unsigned long* pos = lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; +} + +// Forward declaration of operator==. + +template +class hashtable; + +template +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); + + +// Hashtables handle allocators a bit differently than other containers +// do. If we're using standard-conforming allocators, then a hashtable +// unconditionally has a member variable to hold its allocator, even if +// it so happens that all instances of the allocator type are identical. +// This is because, for hashtables, this extra storage is negligible. +// Additionally, a base class wouldn't serve any other purposes; it +// wouldn't, for example, simplify the exception-handling code. + +template +class hashtable { +public: + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher hash_funct() const { return _M_hash; } + key_equal key_eq() const { return _M_equals; } + +private: + typedef _Hashtable_node<_Val> _Node; + +#ifdef __STL_USE_STD_ALLOCATORS +public: + typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } +private: + typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator; + _Node* _M_get_node() { return _M_node_allocator.allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) _M_node_allocator(__a), +#else /* __STL_USE_STD_ALLOCATORS */ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } +private: + typedef simple_alloc<_Node, _Alloc> _M_node_allocator_type; + _Node* _M_get_node() { return _M_node_allocator_type::allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator_type::deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) +#endif /* __STL_USE_STD_ALLOCATORS */ + +private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + vector<_Node*,_Alloc> _M_buckets; + size_type _M_num_elements; + +public: + typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey, + _Alloc> + const_iterator; + + friend struct + _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; + friend struct + _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; + +public: + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : __HASH_ALLOC_INIT(__a) + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(__ext), + _M_buckets(__a), + _M_num_elements(0) + { + _M_initialize_buckets(__n); + } + + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : __HASH_ALLOC_INIT(__a) + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(_ExtractKey()), + _M_buckets(__a), + _M_num_elements(0) + { + _M_initialize_buckets(__n); + } + + hashtable(const hashtable& __ht) + : __HASH_ALLOC_INIT(__ht.get_allocator()) + _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), + _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), + _M_num_elements(0) + { + _M_copy_from(__ht); + } + +#undef __HASH_ALLOC_INIT + + hashtable& operator= (const hashtable& __ht) + { + if (&__ht != this) { + clear(); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); + } + return *this; + } + + ~hashtable() { clear(); } + + size_type size() const { return _M_num_elements; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return size() == 0; } + + void swap(hashtable& __ht) + { + __STD::swap(_M_hash, __ht._M_hash); + __STD::swap(_M_equals, __ht._M_equals); + __STD::swap(_M_get_key, __ht._M_get_key); + _M_buckets.swap(__ht._M_buckets); + __STD::swap(_M_num_elements, __ht._M_num_elements); + } + + iterator begin() + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); + return end(); + } + + iterator end() { return iterator(0, this); } + + const_iterator begin() const + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); + return end(); + } + + const_iterator end() const { return const_iterator(0, this); } + +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, + const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&); +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + + size_type bucket_count() const { return _M_buckets.size(); } + + size_type max_bucket_count() const + { return __stl_prime_list[(int)__stl_num_primes - 1]; } + + size_type elems_in_bucket(size_type __bucket) const + { + size_type __result = 0; + for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) + __result += 1; + return __result; + } + + pair insert_unique(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); + } + + iterator insert_equal(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); + } + + pair insert_unique_noresize(const value_type& __obj); + iterator insert_equal_noresize(const value_type& __obj); + +#ifdef __STL_MEMBER_TEMPLATES + template + void insert_unique(_InputIterator __f, _InputIterator __l) + { + insert_unique(__f, __l, __ITERATOR_CATEGORY(__f)); + } + + template + void insert_equal(_InputIterator __f, _InputIterator __l) + { + insert_equal(__f, __l, __ITERATOR_CATEGORY(__f)); + } + + template + void insert_unique(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template + void insert_equal(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template + void insert_unique(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template + void insert_equal(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + +#else /* __STL_MEMBER_TEMPLATES */ + void insert_unique(const value_type* __f, const value_type* __l) + { + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + void insert_equal(const value_type* __f, const value_type* __l) + { + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + + void insert_unique(const_iterator __f, const_iterator __l) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + void insert_equal(const_iterator __f, const_iterator __l) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } +#endif /*__STL_MEMBER_TEMPLATES */ + + reference find_or_insert(const value_type& __obj); + + iterator find(const key_type& __key) + { + size_type __n = _M_bkt_num_key(__key); + _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + {} + return iterator(__first, this); + } + + const_iterator find(const key_type& __key) const + { + size_type __n = _M_bkt_num_key(__key); + const _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + {} + return const_iterator(__first, this); + } + + size_type count(const key_type& __key) const + { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + + for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) + ++__result; + return __result; + } + + pair + equal_range(const key_type& __key); + + pair + equal_range(const key_type& __key) const; + + size_type erase(const key_type& __key); + void erase(const iterator& __it); + void erase(iterator __first, iterator __last); + + void erase(const const_iterator& __it); + void erase(const_iterator __first, const_iterator __last); + + void resize(size_type __num_elements_hint); + void clear(); + +private: + size_type _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } + + void _M_initialize_buckets(size_type __n) + { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; + } + + size_type _M_bkt_num_key(const key_type& __key) const + { + return _M_bkt_num_key(__key, _M_buckets.size()); + } + + size_type _M_bkt_num(const value_type& __obj) const + { + return _M_bkt_num_key(_M_get_key(__obj)); + } + + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const + { + return _M_hash(__key) % __n; + } + + size_type _M_bkt_num(const value_type& __obj, size_t __n) const + { + return _M_bkt_num_key(_M_get_key(__obj), __n); + } + + _Node* _M_new_node(const value_type& __obj) + { + _Node* __n = _M_get_node(); + __n->_M_next = 0; + __STL_TRY { + construct(&__n->_M_val, __obj); + return __n; + } + __STL_UNWIND(_M_put_node(__n)); + } + + void _M_delete_node(_Node* __n) + { + destroy(&__n->_M_val); + _M_put_node(__n); + } + + void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + void _M_erase_bucket(const size_type __n, _Node* __last); + + void _M_copy_from(const hashtable& __ht); + +}; + +template +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template +inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + iterator __tmp = *this; + ++*this; + return __tmp; +} + +template +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template +inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + const_iterator __tmp = *this; + ++*this; + return __tmp; +} + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline forward_iterator_tag +iterator_category(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return forward_iterator_tag(); +} + +template +inline _Val* +value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (_Val*) 0; +} + +template +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; +} + +template +inline forward_iterator_tag +iterator_category(const _Hashtable_const_iterator<_Val,_Key,_HF, + _ExK,_EqK,_All>&) +{ + return forward_iterator_tag(); +} + +template +inline _Val* +value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (_Val*) 0; +} + +template +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) +{ + typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) + {} + if (__cur1 || __cur2) + return false; + } + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { + return !(__ht1 == __ht2); +} + +template +inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { + __ht1.swap(__ht2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template +pair::iterator, bool> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_unique_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return pair(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair(iterator(__tmp, this), true); +} + +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_equal_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); +} + +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) +{ + resize(_M_num_elements + 1); + + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; +} + +template +pair::iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) +{ + typedef pair _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); + } + return _Pii(end(), end()); +} + +template +pair::const_iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::equal_range(const key_type& __key) const +{ + typedef pair _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n] ; + __first; + __first = __first->_M_next) { + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (const _Node* __cur = __first->_M_next; + __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); + } + } + return _Pii(end(), end()); +} + +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key) +{ + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) { + if (_M_equals(_M_get_key(__next->_M_val), __key)) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; + } + } + return __erased; +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) +{ + _Node* __p = __it._M_cur; + if (__p) { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; + } + else { + _Node* __next = __cur->_M_next; + while (__next) { + if (__next == __p) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; + break; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + } + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::erase(iterator __first, iterator __last) +{ + size_type __f_bucket = __first._M_cur ? + _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); + size_type __l_bucket = __last._M_cur ? + _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); + + if (__first._M_cur == __last._M_cur) + return; + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); + else { + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); + } +} + +template +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, + const_iterator __last) +{ + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast(__last._M_ht))); +} + +template +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) +{ + erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast(__it._M_ht))); +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::resize(size_type __num_elements_hint) +{ + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) { + vector<_Node*, _All> __tmp(__n, (_Node*)(0), + _M_buckets.get_allocator()); + __STL_TRY { + for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { + _Node* __first = _M_buckets[__bucket]; + while (__first) { + size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); + _M_buckets[__bucket] = __first->_M_next; + __first->_M_next = __tmp[__new_bucket]; + __tmp[__new_bucket] = __first; + __first = _M_buckets[__bucket]; + } + } + _M_buckets.swap(__tmp); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { + while (__tmp[__bucket]) { + _Node* __next = __tmp[__bucket]->_M_next; + _M_delete_node(__tmp[__bucket]); + __tmp[__bucket] = __next; + } + } + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ + } + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); + else { + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) + ; + while (__next != __last) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear() +{ + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + } + _M_buckets[__i] = 0; + } + _M_num_elements = 0; +} + + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_copy_from(const hashtable& __ht) +{ + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); + __STL_TRY { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + const _Node* __cur = __ht._M_buckets[__i]; + if (__cur) { + _Node* __copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) { + __copy->_M_next = _M_new_node(__next->_M_val); + __copy = __copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + __STL_UNWIND(clear()); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_heap.h b/darkice/tags/darkice-0_2/stl/stl_heap.h new file mode 100644 index 0000000..651d21a --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_heap.h @@ -0,0 +1,297 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_HEAP_H +#define __SGI_STL_INTERNAL_HEAP_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. + +template +void +__push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; +} + +template +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1))); +} + +template +inline void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, + _LessThanComparable); + __push_heap_aux(__first, __last, + __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); +} + +template +void +__push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; +} + +template +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp, + _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1)), __comp); +} + +template +inline void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + __push_heap_aux(__first, __last, __comp, + __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); +} + +template +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value) +{ + _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) { + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + __push_heap(__first, __holeIndex, __topIndex, __value); +} + +template +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); +} + +template +inline void +__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Tp*) +{ + __pop_heap(__first, __last - 1, __last - 1, + _Tp(*(__last - 1)), __DISTANCE_TYPE(__first)); +} + +template +inline void pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, + _LessThanComparable); + __pop_heap_aux(__first, __last, __VALUE_TYPE(__first)); +} + +template +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value, _Compare __comp) +{ + _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) { + if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + __push_heap(__first, __holeIndex, __topIndex, __value, __comp); +} + +template +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Compare __comp, + _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); +} + +template +inline void +__pop_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _Compare __comp) +{ + __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, + __DISTANCE_TYPE(__first)); +} + +template +inline void +pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp); +} + +template +void +__make_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _Distance*) +{ + if (__last - __first < 2) return; + _Distance __len = __last - __first; + _Distance __parent = (__len - 2)/2; + + while (true) { + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); + if (__parent == 0) return; + __parent--; + } +} + +template +inline void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, + _LessThanComparable); + __make_heap(__first, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} + +template +void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp, _Tp*, _Distance*) +{ + if (__last - __first < 2) return; + _Distance __len = __last - __first; + _Distance __parent = (__len - 2)/2; + + while (true) { + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)), + __comp); + if (__parent == 0) return; + __parent--; + } +} + +template +inline void +make_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + __make_heap(__first, __last, __comp, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} + +template +void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, + _LessThanComparable); + while (__last - __first > 1) + pop_heap(__first, __last--); +} + +template +void +sort_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); + while (__last - __first > 1) + pop_heap(__first, __last--, __comp); +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_iterator.h b/darkice/tags/darkice-0_2/stl/stl_iterator.h new file mode 100644 index 0000000..807871e --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_iterator.h @@ -0,0 +1,964 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#define __SGI_STL_INTERNAL_ITERATOR_H + +__STL_BEGIN_NAMESPACE + + +template +class back_insert_iterator { +protected: + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit back_insert_iterator(_Container& __x) : container(&__x) {} + back_insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->push_back(__value); + return *this; + } + back_insert_iterator<_Container>& operator*() { return *this; } + back_insert_iterator<_Container>& operator++() { return *this; } + back_insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const back_insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline back_insert_iterator<_Container> back_inserter(_Container& __x) { + return back_insert_iterator<_Container>(__x); +} + +template +class front_insert_iterator { +protected: + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit front_insert_iterator(_Container& __x) : container(&__x) {} + front_insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->push_front(__value); + return *this; + } + front_insert_iterator<_Container>& operator*() { return *this; } + front_insert_iterator<_Container>& operator++() { return *this; } + front_insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const front_insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline front_insert_iterator<_Container> front_inserter(_Container& __x) { + return front_insert_iterator<_Container>(__x); +} + +template +class insert_iterator { +protected: + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x), iter(__i) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + iter = container->insert(iter, __value); + ++iter; + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline +insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) +{ + typedef typename _Container::iterator __iter; + return insert_iterator<_Container>(__x, __iter(__i)); +} + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template +#else +template +#endif +class reverse_bidirectional_iterator { + typedef reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance> _Self; +protected: + _BidirectionalIterator current; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; + + reverse_bidirectional_iterator() {} + explicit reverse_bidirectional_iterator(_BidirectionalIterator __x) + : current(__x) {} + _BidirectionalIterator base() const { return current; } + _Reference operator*() const { + _BidirectionalIterator __tmp = current; + return *--__tmp; + } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + _Self& operator++() { + --current; + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + --current; + return __tmp; + } + _Self& operator--() { + ++current; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + ++current; + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline bidirectional_iterator_tag +iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, _Reference, + _Distance>&) +{ + return bidirectional_iterator_tag(); +} + +template +inline _Tp* +value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; +} + +template +inline _Distance* +distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, + _Reference, _Distance>&) +{ + return (_Distance*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline bool operator==( + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) +{ + return __x.base() == __y.base(); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=( + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) +{ + return !(__x == __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +// This is the new version of reverse_iterator, as defined in the +// draft C++ standard. It relies on the iterator_traits template, +// which in turn relies on partial specialization. The class +// reverse_bidirectional_iterator is no longer part of the draft +// standard, but it is retained for backward compatibility. + +template +class reverse_iterator +{ +protected: + _Iterator current; +public: + typedef typename iterator_traits<_Iterator>::iterator_category + iterator_category; + typedef typename iterator_traits<_Iterator>::value_type + value_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::pointer + pointer; + typedef typename iterator_traits<_Iterator>::reference + reference; + + typedef _Iterator iterator_type; + typedef reverse_iterator<_Iterator> _Self; + +public: + reverse_iterator() {} + explicit reverse_iterator(iterator_type __x) : current(__x) {} + + reverse_iterator(const _Self& __x) : current(__x.current) {} +#ifdef __STL_MEMBER_TEMPLATES + template + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) {} +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator_type base() const { return current; } + reference operator*() const { + _Iterator __tmp = current; + return *--__tmp; + } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() { + --current; + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + --current; + return __tmp; + } + _Self& operator--() { + ++current; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + ++current; + return __tmp; + } + + _Self operator+(difference_type __n) const { + return _Self(current - __n); + } + _Self& operator+=(difference_type __n) { + current -= __n; + return *this; + } + _Self operator-(difference_type __n) const { + return _Self(current + __n); + } + _Self& operator-=(difference_type __n) { + current += __n; + return *this; + } + reference operator[](difference_type __n) const { return *(*this + __n); } +}; + +template +inline bool operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __x.base() == __y.base(); +} + +template +inline bool operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y.base() < __x.base(); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline typename reverse_iterator<_Iterator>::difference_type +operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y.base() - __x.base(); +} + +template +inline reverse_iterator<_Iterator> +operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) { + return reverse_iterator<_Iterator>(__x.base() - __n); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// This is the old version of reverse_iterator, as found in the original +// HP STL. It does not use partial specialization. + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template +#else +template +#endif +class reverse_iterator { + typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance> + _Self; +protected: + _RandomAccessIterator current; +public: + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; + + reverse_iterator() {} + explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {} + _RandomAccessIterator base() const { return current; } + _Reference operator*() const { return *(current - 1); } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + _Self& operator++() { + --current; + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + --current; + return __tmp; + } + _Self& operator--() { + ++current; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + ++current; + return __tmp; + } + _Self operator+(_Distance __n) const { + return _Self(current - __n); + } + _Self& operator+=(_Distance __n) { + current -= __n; + return *this; + } + _Self operator-(_Distance __n) const { + return _Self(current + __n); + } + _Self& operator-=(_Distance __n) { + current += __n; + return *this; + } + _Reference operator[](_Distance __n) const { return *(*this + __n); } +}; + +template +inline random_access_iterator_tag +iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return random_access_iterator_tag(); +} + +template +inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; +} + +template +inline _Distance* +distance_type(const reverse_iterator<_RandomAccessIterator, + _Tp, _Reference, _Distance>&) +{ + return (_Distance*) 0; +} + + +template +inline bool +operator==(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __x.base() == __y.base(); +} + +template +inline bool +operator<(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() < __x.base(); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) { + return !(__x == __y); +} + +template +inline bool +operator>(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) { + return __y < __x; +} + +template +inline bool +operator<=(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) { + return !(__y < __x); +} + +template +inline bool +operator>=(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline _Distance +operator-(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() - __x.base(); +} + +template +inline reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist> +operator+(_Dist __n, + const reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>& __x) +{ + return reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>(__x.base() - __n); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// istream_iterator and ostream_iterator look very different if we're +// using new, templatized iostreams than if we're using the old cfront +// version. + +#ifdef __STL_USE_NEW_IOSTREAMS + +template , + class _Dist = ptrdiff_t> +class istream_iterator { +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT, _Traits> istream_type; + + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Dist difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + istream_iterator() : _M_stream(0), _M_ok(false) {} + istream_iterator(istream_type& __s) : _M_stream(&__s) { _M_read(); } + + reference operator*() const { return _M_value; } + pointer operator->() const { return &(operator*()); } + + istream_iterator& operator++() { + _M_read(); + return *this; + } + istream_iterator operator++(int) { + istream_iterator __tmp = *this; + _M_read(); + return __tmp; + } + + bool _M_equal(const istream_iterator& __x) const + { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } + +private: + istream_type* _M_stream; + _Tp _M_value; + bool _M_ok; + + void _M_read() { + _M_ok = (_M_stream && *_M_stream) ? true : false; + if (_M_ok) { + *_M_stream >> _M_value; + _M_ok = *_M_stream ? true : false; + } + } +}; + +template +inline bool +operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { + return __x._M_equal(__y); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { + return !__x._M_equal(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template > +class ostream_iterator { +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} + ostream_iterator(ostream_type& __s, const _CharT* __c) + : _M_stream(&__s), _M_string(__c) {} + ostream_iterator<_Tp>& operator=(const _Tp& __value) { + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; + return *this; + } + ostream_iterator<_Tp>& operator*() { return *this; } + ostream_iterator<_Tp>& operator++() { return *this; } + ostream_iterator<_Tp>& operator++(int) { return *this; } +private: + ostream_type* _M_stream; + const _CharT* _M_string; +}; + +// The default template argument is declared in iosfwd + +// We do not read any characters until operator* is called. The first +// time operator* is called, it calls getc. Subsequent calls to getc +// return a cached character, and calls to operator++ use snextc. Before +// operator* or operator++ has been called, _M_is_initialized is false. +template +class istreambuf_iterator + : public iterator +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + +public: + istreambuf_iterator(streambuf_type* __p = 0) { this->_M_init(__p); } + istreambuf_iterator(istream_type& __is) { this->_M_init(__is.rdbuf()); } + + char_type operator*() const + { return _M_is_initialized ? _M_c : _M_dereference_aux(); } + + istreambuf_iterator& operator++() { this->_M_nextc(); return *this; } + istreambuf_iterator operator++(int) { + if (!_M_is_initialized) + _M_postincr_aux(); + istreambuf_iterator __tmp = *this; + this->_M_nextc(); + return __tmp; + } + + bool equal(const istreambuf_iterator& __i) const { + return this->_M_is_initialized && __i._M_is_initialized + ? this->_M_eof == __i._M_eof + : this->_M_equal_aux(__i); + } + +private: + void _M_init(streambuf_type* __p) { + _M_buf = __p; + _M_eof = !__p; + _M_is_initialized = _M_eof; + } + + char_type _M_dereference_aux() const; + bool _M_equal_aux(const istreambuf_iterator&) const; + void _M_postincr_aux(); + + void _M_nextc() { + int_type __c = _M_buf->snextc(); + _M_c = traits_type::to_char_type(__c); + _M_eof = traits_type::eq_int_type(__c, traits_type::eof()); + _M_is_initialized = true; + } + + void _M_getc() const { + int_type __c = _M_buf->sgetc(); + _M_c = traits_type::to_char_type(__c); + _M_eof = traits_type::eq_int_type(__c, traits_type::eof()); + _M_is_initialized = true; + } + +private: + streambuf_type* _M_buf; + mutable _CharT _M_c; + mutable bool _M_eof : 1; + mutable bool _M_is_initialized : 1; +}; + +template +_CharT istreambuf_iterator<_CharT, _Traits>::_M_dereference_aux() const +{ + this->_M_getc(); + return _M_c; +} + +template +bool istreambuf_iterator<_CharT, _Traits> + ::_M_equal_aux(const istreambuf_iterator& __i) const +{ + if (!this->_M_is_initialized) + this->_M_getc(); + if (!__i._M_is_initialized) + __i._M_getc(); + + return this->_M_eof == __i._M_eof; +} + +template +void istreambuf_iterator<_CharT, _Traits>::_M_postincr_aux() +{ + this->_M_getc(); +} + +template +inline bool operator==(const istreambuf_iterator<_CharT, _Traits>& __x, + const istreambuf_iterator<_CharT, _Traits>& __y) { + return __x.equal(__y); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const istreambuf_iterator<_CharT, _Traits>& __x, + const istreambuf_iterator<_CharT, _Traits>& __y) { + return !__x.equal(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// The default template argument is declared in iosfwd +template +class ostreambuf_iterator + : public iterator +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + +public: + ostreambuf_iterator(streambuf_type* __buf) : _M_buf(__buf), _M_ok(__buf) {} + ostreambuf_iterator(ostream_type& __o) + : _M_buf(__o.rdbuf()), _M_ok(__o.rdbuf() != 0) {} + + ostreambuf_iterator& operator=(char_type __c) { + _M_ok = _M_ok && !traits_type::eq_int_type(_M_buf->sputc(__c), + traits_type::eof()); + return *this; + } + + ostreambuf_iterator& operator*() { return *this; } + ostreambuf_iterator& operator++() { return *this; } + ostreambuf_iterator& operator++(int) { return *this; } + + bool failed() const { return !_M_ok; } + +private: + streambuf_type* _M_buf; + bool _M_ok; +}; + +#else /* __STL_USE_NEW_IOSTREAMS */ + +template class istream_iterator; + +template +inline bool operator==(const istream_iterator<_Tp, _Dist>&, + const istream_iterator<_Tp, _Dist>&); + +template +class istream_iterator { +#ifdef __STL_TEMPLATE_FRIENDS + template + friend bool operator==(const istream_iterator<_T1, _D1>&, + const istream_iterator<_T1, _D1>&); +#else /* __STL_TEMPLATE_FRIENDS */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const istream_iterator&, + const istream_iterator&); +#endif /* __STL_TEMPLATE_FRIENDS */ + +protected: + istream* _M_stream; + _Tp _M_value; + bool _M_end_marker; + void _M_read() { + _M_end_marker = (*_M_stream) ? true : false; + if (_M_end_marker) *_M_stream >> _M_value; + _M_end_marker = (*_M_stream) ? true : false; + } +public: + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Dist difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} + istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } + reference operator*() const { return _M_value; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + istream_iterator<_Tp, _Dist>& operator++() { + _M_read(); + return *this; + } + istream_iterator<_Tp, _Dist> operator++(int) { + istream_iterator<_Tp, _Dist> __tmp = *this; + _M_read(); + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline input_iterator_tag +iterator_category(const istream_iterator<_Tp, _Dist>&) +{ + return input_iterator_tag(); +} + +template +inline _Tp* +value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; } + +template +inline _Dist* +distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; } + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline bool operator==(const istream_iterator<_Tp, _Distance>& __x, + const istream_iterator<_Tp, _Distance>& __y) { + return (__x._M_stream == __y._M_stream && + __x._M_end_marker == __y._M_end_marker) || + __x._M_end_marker == false && __y._M_end_marker == false; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const istream_iterator<_Tp, _Distance>& __x, + const istream_iterator<_Tp, _Distance>& __y) { + return !(__x == __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +class ostream_iterator { +protected: + ostream* _M_stream; + const char* _M_string; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} + ostream_iterator(ostream& __s, const char* __c) + : _M_stream(&__s), _M_string(__c) {} + ostream_iterator<_Tp>& operator=(const _Tp& __value) { + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; + return *this; + } + ostream_iterator<_Tp>& operator*() { return *this; } + ostream_iterator<_Tp>& operator++() { return *this; } + ostream_iterator<_Tp>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const ostream_iterator<_Tp>&) { + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +#endif /* __STL_USE_NEW_IOSTREAMS */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_iterator_base.h b/darkice/tags/darkice-0_2/stl/stl_iterator_base.h new file mode 100644 index 0000000..9c54225 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_iterator_base.h @@ -0,0 +1,367 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_ITERATOR_BASE_H +#define __SGI_STL_INTERNAL_ITERATOR_BASE_H + +// This file contains all of the general iterator-related utilities. +// The internal file stl_iterator.h contains predefined iterators, +// such as front_insert_iterator and istream_iterator. + +#include + +__STL_BEGIN_NAMESPACE + +struct input_iterator_tag {}; +struct output_iterator_tag {}; +struct forward_iterator_tag : public input_iterator_tag {}; +struct bidirectional_iterator_tag : public forward_iterator_tag {}; +struct random_access_iterator_tag : public bidirectional_iterator_tag {}; + +// The base classes input_iterator, output_iterator, forward_iterator, +// bidirectional_iterator, and random_access_iterator are not part of +// the C++ standard. (They have been replaced by struct iterator.) +// They are included for backward compatibility with the HP STL. + +template struct input_iterator { + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +struct output_iterator { + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; +}; + +template struct forward_iterator { + typedef forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + + +template struct bidirectional_iterator { + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +template struct random_access_iterator { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +#ifdef __STL_USE_NAMESPACES +template +struct iterator { + typedef _Category iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; +}; +#endif /* __STL_USE_NAMESPACES */ + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +struct iterator_traits { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; +}; + +template +struct iterator_traits<_Tp*> { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +template +struct iterator_traits { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; +}; + +// The overloaded functions iterator_category, distance_type, and +// value_type are not part of the C++ standard. (They have been +// replaced by struct iterator_traits.) They are included for +// backward compatibility with the HP STL. + +// We introduce internal names for these functions. + +template +inline typename iterator_traits<_Iter>::iterator_category +__iterator_category(const _Iter&) +{ + typedef typename iterator_traits<_Iter>::iterator_category _Category; + return _Category(); +} + +template +inline typename iterator_traits<_Iter>::difference_type* +__distance_type(const _Iter&) +{ + return static_cast::difference_type*>(0); +} + +template +inline typename iterator_traits<_Iter>::value_type* +__value_type(const _Iter&) +{ + return static_cast::value_type*>(0); +} + +template +inline typename iterator_traits<_Iter>::iterator_category +iterator_category(const _Iter& __i) { return __iterator_category(__i); } + + +template +inline typename iterator_traits<_Iter>::difference_type* +distance_type(const _Iter& __i) { return __distance_type(__i); } + +template +inline typename iterator_traits<_Iter>::value_type* +value_type(const _Iter& __i) { return __value_type(__i); } + +#define __ITERATOR_CATEGORY(__i) __iterator_category(__i) +#define __DISTANCE_TYPE(__i) __distance_type(__i) +#define __VALUE_TYPE(__i) __value_type(__i) + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline input_iterator_tag +iterator_category(const input_iterator<_Tp, _Distance>&) + { return input_iterator_tag(); } + +inline output_iterator_tag iterator_category(const output_iterator&) + { return output_iterator_tag(); } + +template +inline forward_iterator_tag +iterator_category(const forward_iterator<_Tp, _Distance>&) + { return forward_iterator_tag(); } + +template +inline bidirectional_iterator_tag +iterator_category(const bidirectional_iterator<_Tp, _Distance>&) + { return bidirectional_iterator_tag(); } + +template +inline random_access_iterator_tag +iterator_category(const random_access_iterator<_Tp, _Distance>&) + { return random_access_iterator_tag(); } + +template +inline random_access_iterator_tag iterator_category(const _Tp*) + { return random_access_iterator_tag(); } + +template +inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } + +template +inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline _Distance* +distance_type(const bidirectional_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline _Distance* +distance_type(const random_access_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); } + +// Without partial specialization we can't use iterator_traits, so +// we must keep the old iterator query functions around. + +#define __ITERATOR_CATEGORY(__i) iterator_category(__i) +#define __DISTANCE_TYPE(__i) distance_type(__i) +#define __VALUE_TYPE(__i) value_type(__i) + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline void __distance(_InputIterator __first, _InputIterator __last, + _Distance& __n, input_iterator_tag) +{ + while (__first != __last) { ++__first; ++__n; } +} + +template +inline void __distance(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance& __n, random_access_iterator_tag) +{ + __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); + __n += __last - __first; +} + +template +inline void distance(_InputIterator __first, + _InputIterator __last, _Distance& __n) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + __distance(__first, __last, __n, iterator_category(__first)); +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline typename iterator_traits<_InputIterator>::difference_type +__distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) +{ + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; + } + return __n; +} + +template +inline typename iterator_traits<_RandomAccessIterator>::difference_type +__distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) { + __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); + return __last - __first; +} + +template +inline typename iterator_traits<_InputIterator>::difference_type +distance(_InputIterator __first, _InputIterator __last) { + typedef typename iterator_traits<_InputIterator>::iterator_category + _Category; + __STL_REQUIRES(_InputIterator, _InputIterator); + return __distance(__first, __last, _Category()); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { + while (__n--) ++__i; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1183 +#endif + +template +inline void __advance(_BidirectionalIterator& __i, _Distance __n, + bidirectional_iterator_tag) { + __STL_REQUIRES(_BidirectionalIterator, _BidirectionalIterator); + if (__n >= 0) + while (__n--) ++__i; + else + while (__n++) --__i; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1183 +#endif + +template +inline void __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) { + __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); + __i += __n; +} + +template +inline void advance(_InputIterator& __i, _Distance __n) { + __STL_REQUIRES(_InputIterator, _InputIterator); + __advance(__i, __n, iterator_category(__i)); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ITERATOR_BASE_H */ + + + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_list.h b/darkice/tags/darkice-0_2/stl/stl_list.h new file mode 100644 index 0000000..1aa603a --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_list.h @@ -0,0 +1,885 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_LIST_H +#define __SGI_STL_INTERNAL_LIST_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +struct _List_node_base { + _List_node_base* _M_next; + _List_node_base* _M_prev; +}; + +template +struct _List_node : public _List_node_base { + _Tp _M_data; +}; + +struct _List_iterator_base { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + + _List_node_base* _M_node; + + _List_iterator_base(_List_node_base* __x) : _M_node(__x) {} + _List_iterator_base() {} + + void _M_incr() { _M_node = _M_node->_M_next; } + void _M_decr() { _M_node = _M_node->_M_prev; } + + bool operator==(const _List_iterator_base& __x) const { + return _M_node == __x._M_node; + } + bool operator!=(const _List_iterator_base& __x) const { + return _M_node != __x._M_node; + } +}; + +template +struct _List_iterator : public _List_iterator_base { + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; + + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _List_node<_Tp> _Node; + + _List_iterator(_Node* __x) : _List_iterator_base(__x) {} + _List_iterator() {} + _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {} + + reference operator*() const { return ((_Node*) _M_node)->_M_data; } + +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() { + this->_M_incr(); + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + this->_M_incr(); + return __tmp; + } + _Self& operator--() { + this->_M_decr(); + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + this->_M_decr(); + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +inline bidirectional_iterator_tag +iterator_category(const _List_iterator_base&) +{ + return bidirectional_iterator_tag(); +} + +template +inline _Tp* +value_type(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ + return 0; +} + +inline ptrdiff_t* +distance_type(const _List_iterator_base&) +{ + return 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template +class _List_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _Node_allocator; } + + _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {} + +protected: + _List_node<_Tp>* _M_get_node() + { return _Node_allocator.allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) + { _Node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type + _Node_allocator; + _List_node<_Tp>* _M_node; +}; + +// Specialization for instanceless allocators. + +template +class _List_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _List_node<_Tp>* _M_node; +}; + +template +class _List_base + : public _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _List_base(const allocator_type& __a) : _Base(__a) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _List_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_base(const allocator_type&) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); + +protected: + typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _List_node<_Tp>* _M_node; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +void +_List_base<_Tp,_Alloc>::clear() +{ + _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next; + while (__cur != _M_node) { + _List_node<_Tp>* __tmp = __cur; + __cur = (_List_node<_Tp>*) __cur->_M_next; + _Destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; +} + +template +class list : protected _List_base<_Tp, _Alloc> { + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + + typedef _List_base<_Tp, _Alloc> _Base; +protected: + typedef void* _Void_pointer; + +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _List_node<_Tp> _Node; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +public: + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator + const_reverse_iterator; + typedef reverse_bidirectional_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_node; + using _Base::_M_put_node; + using _Base::_M_get_node; +#endif /* __STL_HAS_NAMESPACES */ + +protected: + _Node* _M_create_node(const _Tp& __x) + { + _Node* __p = _M_get_node(); + __STL_TRY { + _Construct(&__p->_M_data, __x); + } + __STL_UNWIND(_M_put_node(__p)); + return __p; + } + + _Node* _M_create_node() + { + _Node* __p = _M_get_node(); + __STL_TRY { + _Construct(&__p->_M_data); + } + __STL_UNWIND(_M_put_node(__p)); + return __p; + } + +public: + explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + iterator begin() { return (_Node*)(_M_node->_M_next); } + const_iterator begin() const { return (_Node*)(_M_node->_M_next); } + + iterator end() { return _M_node; } + const_iterator end() const { return _M_node; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + bool empty() const { return _M_node->_M_next == _M_node; } + size_type size() const { + size_type __result = 0; + distance(begin(), end(), __result); + return __result; + } + size_type max_size() const { return size_type(-1); } + + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(--end()); } + const_reference back() const { return *(--end()); } + + void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); } + + iterator insert(iterator __position, const _Tp& __x) { + _Node* __tmp = _M_create_node(__x); + __tmp->_M_next = __position._M_node; + __tmp->_M_prev = __position._M_node->_M_prev; + __position._M_node->_M_prev->_M_next = __tmp; + __position._M_node->_M_prev = __tmp; + return __tmp; + } + iterator insert(iterator __position) { return insert(__position, _Tp()); } +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + _M_fill_insert(__pos, (size_type) __n, (_Tp) __x); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type); + + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, const _Tp* __first, const _Tp* __last); + void insert(iterator __position, + const_iterator __first, const_iterator __last); +#endif /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __pos, size_type __n, const _Tp& __x) + { _M_fill_insert(__pos, __n, __x); } + void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x); + + void push_front(const _Tp& __x) { insert(begin(), __x); } + void push_front() {insert(begin());} + void push_back(const _Tp& __x) { insert(end(), __x); } + void push_back() {insert(end());} + + iterator erase(iterator __position) { + _List_node_base* __next_node = __position._M_node->_M_next; + _List_node_base* __prev_node = __position._M_node->_M_prev; + _Node* __n = (_Node*) __position._M_node; + __prev_node->_M_next = __next_node; + __next_node->_M_prev = __prev_node; + _Destroy(&__n->_M_data); + _M_put_node(__n); + return iterator((_Node*) __next_node); + } + iterator erase(iterator __first, iterator __last); + void clear() { _Base::clear(); } + + void resize(size_type __new_size, const _Tp& __x); + void resize(size_type __new_size) { this->resize(__new_size, _Tp()); } + + void pop_front() { erase(begin()); } + void pop_back() { + iterator __tmp = end(); + erase(--__tmp); + } + list(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __n, __value); } + explicit list(size_type __n) + : _Base(allocator_type()) + { insert(begin(), __n, _Tp()); } + +#ifdef __STL_MEMBER_TEMPLATES + + // We don't need any dispatching tricks here, because insert does all of + // that anyway. + template + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + +#else /* __STL_MEMBER_TEMPLATES */ + + list(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __first, __last); } + list(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __first, __last); } + +#endif /* __STL_MEMBER_TEMPLATES */ + list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator()) + { insert(begin(), __x.begin(), __x.end()); } + + ~list() { } + + list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x); + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } + + void _M_fill_assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#endif /* __STL_MEMBER_TEMPLATES */ + +protected: + void transfer(iterator __position, iterator __first, iterator __last) { + if (__position != __last) { + // Remove [first, last) from its old position. + __last._M_node->_M_prev->_M_next = __position._M_node; + __first._M_node->_M_prev->_M_next = __last._M_node; + __position._M_node->_M_prev->_M_next = __first._M_node; + + // Splice [first, last) into its new position. + _List_node_base* __tmp = __position._M_node->_M_prev; + __position._M_node->_M_prev = __last._M_node->_M_prev; + __last._M_node->_M_prev = __first._M_node->_M_prev; + __first._M_node->_M_prev = __tmp; + } + } + +public: + void splice(iterator __position, list& __x) { + if (!__x.empty()) + this->transfer(__position, __x.begin(), __x.end()); + } + void splice(iterator __position, list&, iterator __i) { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) return; + this->transfer(__position, __i, __j); + } + void splice(iterator __position, list&, iterator __first, iterator __last) { + if (__first != __last) + this->transfer(__position, __first, __last); + } + void remove(const _Tp& __value); + void unique(); + void merge(list& __x); + void reverse(); + void sort(); + +#ifdef __STL_MEMBER_TEMPLATES + template void remove_if(_Predicate); + template void unique(_BinaryPredicate); + template void merge(list&, _StrictWeakOrdering); + template void sort(_StrictWeakOrdering); +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template +inline bool +operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) +{ + typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = __x.end(); + const_iterator __end2 = __y.end(); + + const_iterator __i1 = __x.begin(); + const_iterator __i2 = __y.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; +} + +template +inline bool operator<(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline void +swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) +{ + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position, + _InputIter __first, _InputIter __last, + __false_type) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +list<_Tp, _Alloc>::insert(iterator __position, + const _Tp* __first, const _Tp* __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); +} + +template +void +list<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +list<_Tp, _Alloc>::_M_fill_insert(iterator __position, + size_type __n, const _Tp& __x) +{ + for ( ; __n > 0; --__n) + insert(__position, __x); +} + +template +typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, + iterator __last) +{ + while (__first != __last) + erase(__first++); + return __last; +} + +template +void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) +{ + iterator __i = begin(); + size_type __len = 0; + for ( ; __i != end() && __len < __new_size; ++__i, ++__len) + ; + if (__len == __new_size) + erase(__i, end()); + else // __i == end() + insert(end(), __new_size - __len, __x); +} + +template +list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) +{ + if (this != &__x) { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + *__first1++ = *__first2++; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + return *this; +} + +template +void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { + iterator __i = begin(); + for ( ; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2, + __false_type) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void list<_Tp, _Alloc>::remove(const _Tp& __value) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (*__first == __value) erase(__first); + __first = __next; + } +} + +template +void list<_Tp, _Alloc>::unique() +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } +} + +template +void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) { + iterator __next = __first2; + transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); +} + +inline void __List_base_reverse(_List_node_base* __p) +{ + _List_node_base* __tmp = __p; + do { + __STD::swap(__tmp->_M_next, __tmp->_M_prev); + __tmp = __tmp->_M_prev; // Old next node is now prev. + } while (__tmp != __p); +} + +template +inline void list<_Tp, _Alloc>::reverse() +{ + __List_base_reverse(this->_M_node); +} + +template +void list<_Tp, _Alloc>::sort() +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _Alloc> __counter[64]; + int __fill = 0; + while (!empty()) { + __carry.splice(__carry.begin(), *this, begin()); + int __i = 0; + while(__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i++]); + } + __carry.swap(__counter[__i]); + if (__i == __fill) ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + swap(__counter[__fill-1]); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void list<_Tp, _Alloc>::remove_if(_Predicate __pred) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (__pred(*__first)) erase(__first); + __first = __next; + } +} + +template template +void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (__binary_pred(*__first, *__next)) + erase(__next); + else + __first = __next; + __next = __first; + } +} + +template template +void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x, + _StrictWeakOrdering __comp) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) { + iterator __next = __first2; + transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); +} + +template template +void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _Alloc> __counter[64]; + int __fill = 0; + while (!empty()) { + __carry.splice(__carry.begin(), *this, begin()); + int __i = 0; + while(__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i++]); + } + __carry.swap(__counter[__i]); + if (__i == __fill) ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + swap(__counter[__fill-1]); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_map.h b/darkice/tags/darkice-0_2/stl/stl_map.h new file mode 100644 index 0000000..a2ea66c --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_map.h @@ -0,0 +1,295 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_MAP_H +#define __SGI_STL_INTERNAL_MAP_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Forward declarations of operators == and <, needed for friend declarations. +template ), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +class map; + +template +inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y); + +template +inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y); + +template +class map { +public: + +// requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); + +// typedefs: + + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function { + friend class map<_Key,_Tp,_Compare,_Alloc>; + protected : + _Compare comp; + value_compare(_Compare __c) : comp(__c) {} + public: + bool operator()(const value_type& __x, const value_type& __y) const { + return comp(__x.first, __y.first); + } + }; + +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing map +public: + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + map() : _M_t(_Compare(), allocator_type()) {} + explicit map(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template + map(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } +#else + map(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + +#endif /* __STL_MEMBER_TEMPLATES */ + + map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + map<_Key,_Tp,_Compare,_Alloc>& + operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + _Tp& operator[](const key_type& __k) { + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) + __i = insert(__i, value_type(__k, _Tp())); + return (*__i).second; + } + void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + + pair insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + iterator insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); + } +#else + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); + } + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_unique(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_t.clear(); } + + // map operations: + + iterator find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { + return _M_t.find(__x) == _M_t.end() ? 0 : 1; + } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + + pair equal_range(const key_type& __x) { + return _M_t.equal_range(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template + friend bool operator== (const map<_K1, _T1, _C1, _A1>&, + const map<_K1, _T1, _C1, _A1>&); + template + friend bool operator< (const map<_K1, _T1, _C1, _A1>&, + const map<_K1, _T1, _C1, _A1>&); +#else /* __STL_TEMPLATE_FRIENDS */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const map&, const map&); + friend bool __STD_QUALIFIER + operator< __STL_NULL_TMPL_ARGS (const map&, const map&); +#endif /* __STL_TEMPLATE_FRIENDS */ +}; + +template +inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, + map<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_multimap.h b/darkice/tags/darkice-0_2/stl/stl_multimap.h new file mode 100644 index 0000000..ecd959c --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_multimap.h @@ -0,0 +1,282 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_MULTIMAP_H +#define __SGI_STL_INTERNAL_MULTIMAP_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Forward declaration of operators < and ==, needed for friend declaration. + +template ), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +class multimap; + +template +inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + +template +inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + +template +class multimap { + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); + +public: + +// typedefs: + + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare : public binary_function { + friend class multimap<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare comp; + value_compare(_Compare __c) : comp(__c) {} + public: + bool operator()(const value_type& __x, const value_type& __y) const { + return comp(__x.first, __y.first); + } + }; + +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multimap +public: + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + +// allocation/deallocation + + multimap() : _M_t(_Compare(), allocator_type()) { } + explicit multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + +#ifdef __STL_MEMBER_TEMPLATES + template + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } +#else + multimap(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multimap(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { } + multimap<_Key,_Tp,_Compare,_Alloc>& + operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + + iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } + iterator insert(iterator __position, const value_type& __x) { + return _M_t.insert_equal(__position, __x); + } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); + } +#else + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); + } + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_equal(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_t.clear(); } + + // multimap operations: + + iterator find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + pair equal_range(const key_type& __x) { + return _M_t.equal_range(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template + friend bool operator== (const multimap<_K1, _T1, _C1, _A1>&, + const multimap<_K1, _T1, _C1, _A1>&); + template + friend bool operator< (const multimap<_K1, _T1, _C1, _A1>&, + const multimap<_K1, _T1, _C1, _A1>&); +#else /* __STL_TEMPLATE_FRIENDS */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); + friend bool __STD_QUALIFIER + operator< __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); +#endif /* __STL_TEMPLATE_FRIENDS */ +}; + +template +inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, + multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_multiset.h b/darkice/tags/darkice-0_2/stl/stl_multiset.h new file mode 100644 index 0000000..5365ffb --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_multiset.h @@ -0,0 +1,274 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_MULTISET_H +#define __SGI_STL_INTERNAL_MULTISET_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Forward declaration of operators < and ==, needed for friend declaration. + +template ), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > +class multiset; + +template +inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + +template +inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + +template +class multiset { + // requirements: + + __STL_CLASS_REQUIRES(_Key, _Assignable); + __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); + +public: + + // typedefs: + + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multiset +public: + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + multiset() : _M_t(_Compare(), allocator_type()) {} + explicit multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + + template + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + +#else + + multiset(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + +#endif /* __STL_MEMBER_TEMPLATES */ + + multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + iterator insert(const value_type& __x) { + return _M_t.insert_equal(__x); + } + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); + } + +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); + } +#else + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); + } + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_equal(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + size_type erase(const key_type& __x) { + return _M_t.erase(__x); + } + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + void clear() { _M_t.clear(); } + + // multiset operations: + + iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template + friend bool operator== (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + template + friend bool operator< (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); +#else /* __STL_TEMPLATE_FRIENDS */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); + friend bool __STD_QUALIFIER + operator< __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); +#endif /* __STL_TEMPLATE_FRIENDS */ +}; + +template +inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline void swap(multiset<_Key,_Compare,_Alloc>& __x, + multiset<_Key,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_numeric.h b/darkice/tags/darkice-0_2/stl/stl_numeric.h new file mode 100644 index 0000000..f8e9594 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_numeric.h @@ -0,0 +1,255 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + + +#ifndef __SGI_STL_INTERNAL_NUMERIC_H +#define __SGI_STL_INTERNAL_NUMERIC_H + +__STL_BEGIN_NAMESPACE + +template +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + for ( ; __first != __last; ++__first) + __init = __init + *__first; + return __init; +} + +template +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, + _BinaryOperation __binary_op) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + for ( ; __first != __last; ++__first) + __init = __binary_op(__init, *__first); + return __init; +} + +template +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) +{ + __STL_REQUIRES(_InputIterator2, _InputIterator); + __STL_REQUIRES(_InputIterator2, _InputIterator); + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __init + (*__first1 * *__first2); + return __init; +} + +template +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) +{ + __STL_REQUIRES(_InputIterator2, _InputIterator); + __STL_REQUIRES(_InputIterator2, _InputIterator); + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); + return __init; +} + +template +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __value + *__first; + *++__result = __value; + } + return ++__result; +} + +template +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + __STL_REQUIRES(_OutputIterator, _OutputIterator); + if (__first == __last) return __result; + *__result = *__first; + return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first)); +} + +template +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __binary_op(__value, *__first); + *++__result = __value; + } + return ++__result; +} + +template +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + __STL_REQUIRES(_OutputIterator, _OutputIterator); + if (__first == __last) return __result; + *__result = *__first; + return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first), + __binary_op); +} + +template +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __tmp - __value; + __value = __tmp; + } + return ++__result; +} + +template +_OutputIterator +adjacent_difference(_InputIterator __first, + _InputIterator __last, _OutputIterator __result) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + __STL_REQUIRES(_OutputIterator, _OutputIterator); + if (__first == __last) return __result; + *__result = *__first; + return __adjacent_difference(__first, __last, __result, + __VALUE_TYPE(__first)); +} + +template +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, + _BinaryOperation __binary_op) { + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __binary_op(__tmp, __value); + __value = __tmp; + } + return ++__result; +} + +template +_OutputIterator +adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + __STL_REQUIRES(_OutputIterator, _OutputIterator); + if (__first == __last) return __result; + *__result = *__first; + return __adjacent_difference(__first, __last, __result, + __VALUE_TYPE(__first), + __binary_op); +} + +// Returns __x ** __n, where __n >= 0. _Note that "multiplication" +// is required to be associative, but not necessarily commutative. + + +template +_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr) +{ + if (__n == 0) + return identity_element(__opr); + else { + while ((__n & 1) == 0) { + __n >>= 1; + __x = __opr(__x, __x); + } + + _Tp __result = __x; + __n >>= 1; + while (__n != 0) { + __x = __opr(__x, __x); + if ((__n & 1) != 0) + __result = __opr(__result, __x); + __n >>= 1; + } + return __result; + } +} + +template +inline _Tp __power(_Tp __x, _Integer __n) +{ + return __power(__x, __n, multiplies<_Tp>()); +} + +// Alias for the internal name __power. Note that power is an extension, +// not part of the C++ standard. + +template +inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __opr) +{ + return __power(__x, __n, __opr); +} + +template +inline _Tp power(_Tp __x, _Integer __n) +{ + return __power(__x, __n); +} + +// iota is not part of the C++ standard. It is an extension. + +template +void +iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) +{ + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); + while (__first != __last) + *__first++ = __value++; +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_NUMERIC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_pair.h b/darkice/tags/darkice-0_2/stl/stl_pair.h new file mode 100644 index 0000000..a6155a6 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_pair.h @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_PAIR_H +#define __SGI_STL_INTERNAL_PAIR_H + +__STL_BEGIN_NAMESPACE + +template +struct pair { + typedef _T1 first_type; + typedef _T2 second_type; + + _T1 first; + _T2 second; + pair() : first(_T1()), second(_T2()) {} + pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} +#endif +}; + +template +inline bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) +{ + return __x.first == __y.first && __x.second == __y.second; +} + +template +inline bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) +{ + return __x.first < __y.first || + (!(__y.first < __x.first) && __x.second < __y.second); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline pair<_T1, _T2> make_pair(const _T1& __x, const _T2& __y) +{ + return pair<_T1, _T2>(__x, __y); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_queue.h b/darkice/tags/darkice-0_2/stl/stl_queue.h new file mode 100644 index 0000000..833e45f --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_queue.h @@ -0,0 +1,243 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_QUEUE_H +#define __SGI_STL_INTERNAL_QUEUE_H + +#include + +__STL_BEGIN_NAMESPACE + +// Forward declarations of operators < and ==, needed for friend declaration. + +template ) > +class queue; + +template +inline bool operator==(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); + +template +inline bool operator<(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); + + +template +class queue { + + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + __STL_CLASS_REQUIRES(_Sequence, _FrontInsertionSequence); + __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence); + typedef typename _Sequence::value_type _Sequence_value_type; + __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type); + + +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const queue<_Tp1, _Seq1>&, + const queue<_Tp1, _Seq1>&); + template + friend bool operator< (const queue<_Tp1, _Seq1>&, + const queue<_Tp1, _Seq1>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&); + friend bool __STD_QUALIFIER + operator< __STL_NULL_TMPL_ARGS (const queue&, const queue&); +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; +protected: + _Sequence c; +public: + queue() : c() {} + explicit queue(const _Sequence& __c) : c(__c) {} + + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + reference front() { return c.front(); } + const_reference front() const { return c.front(); } + reference back() { return c.back(); } + const_reference back() const { return c.back(); } + void push(const value_type& __x) { c.push_back(__x); } + void pop() { c.pop_front(); } +}; + +template +bool +operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c == __y.c; +} + +template +bool +operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c < __y.c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +bool +operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x == __y); +} + +template +bool +operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __y < __x; +} + +template +bool +operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__y < __x); +} + +template +bool +operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template ), + class _Compare + __STL_DEPENDENT_DEFAULT_TMPL(less) > +class priority_queue { + + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + __STL_CLASS_REQUIRES(_Sequence, _Sequence); + __STL_CLASS_REQUIRES(_Sequence, _RandomAccessContainer); + typedef typename _Sequence::value_type _Sequence_value_type; + __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type); + __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); + +public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; +protected: + _Sequence c; + _Compare comp; +public: + priority_queue() : c() {} + explicit priority_queue(const _Compare& __x) : c(), comp(__x) {} + priority_queue(const _Compare& __x, const _Sequence& __s) + : c(__s), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + +#ifdef __STL_MEMBER_TEMPLATES + template + priority_queue(_InputIterator __first, _InputIterator __last) + : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } + + template + priority_queue(_InputIterator __first, + _InputIterator __last, const _Compare& __x) + : c(__first, __last), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + + template + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x, const _Sequence& __s) + : c(__s), comp(__x) + { + c.insert(c.end(), __first, __last); + make_heap(c.begin(), c.end(), comp); + } + +#else /* __STL_MEMBER_TEMPLATES */ + priority_queue(const value_type* __first, const value_type* __last) + : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x) + : c(__first, __last), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x, const _Sequence& __c) + : c(__c), comp(__x) + { + c.insert(c.end(), __first, __last); + make_heap(c.begin(), c.end(), comp); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + const_reference top() const { return c.front(); } + void push(const value_type& __x) { + __STL_TRY { + c.push_back(__x); + push_heap(c.begin(), c.end(), comp); + } + __STL_UNWIND(c.clear()); + } + void pop() { + __STL_TRY { + pop_heap(c.begin(), c.end(), comp); + c.pop_back(); + } + __STL_UNWIND(c.clear()); + } +}; + +// no equality is provided + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_QUEUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_range_errors.h b/darkice/tags/darkice-0_2/stl/stl_range_errors.h new file mode 100644 index 0000000..3ddde6d --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_range_errors.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __STL_RANGE_ERRORS_H +#define __STL_RANGE_ERRORS_H + +// A few places in the STL throw range errors, using standard exception +// classes defined in . This header file provides functions +// to throw those exception objects. + +// __STL_DONT_THROW_RANGE_ERRORS is a hook so that users can disable +// this exception throwing. + +#include + +#if defined(__STL_CAN_THROW_RANGE_ERRORS) && \ + defined(__STL_USE_EXCEPTIONS) && \ + !defined(__STL_DONT_THROW_RANGE_ERRORS) +# define __STL_THROW_RANGE_ERRORS +#endif + +// For the SGI 7.3 compiler, declare these functions here and define them +// elsewhere. +#if defined(__STL_THROW_RANGE_ERRORS) && \ + defined(__sgi) && !defined(__GNUC__) && \ + _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) + +__STL_BEGIN_NAMESPACE +void __stl_throw_range_error(const char* __msg); +void __stl_throw_length_error(const char* __msg); +__STL_END_NAMESPACE + +// For other compilers where we're throwing range errors, include the +// stdexcept header and throw the appropriate exceptions directly. +#elif defined(__STL_THROW_RANGE_ERRORS) + +#include + +__STL_BEGIN_NAMESPACE +inline void __stl_throw_range_error(const char* __msg) + { throw range_error(__msg); } +inline void __stl_throw_length_error(const char* __msg) + { throw length_error(__msg); } +__STL_END_NAMESPACE + +// Otherwise, define inline functions that do nothing. +#else + +__STL_BEGIN_NAMESPACE +inline void __stl_throw_range_error(const char*) {} +inline void __stl_throw_length_error(const char*) {} +__STL_END_NAMESPACE + +#endif + +#endif /* __STL_RANGE_ERRORS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_raw_storage_iter.h b/darkice/tags/darkice-0_2/stl/stl_raw_storage_iter.h new file mode 100644 index 0000000..6f3951c --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_raw_storage_iter.h @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H +#define __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H + +__STL_BEGIN_NAMESPACE + +template +class raw_storage_iterator { +protected: + _ForwardIterator _M_iter; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} + raw_storage_iterator& operator*() { return *this; } + raw_storage_iterator& operator=(const _Tp& __element) { + construct(&*_M_iter, __element); + return *this; + } + raw_storage_iterator<_ForwardIterator, _Tp>& operator++() { + ++_M_iter; + return *this; + } + raw_storage_iterator<_ForwardIterator, _Tp> operator++(int) { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const raw_storage_iterator<_ForwardIterator, _Tp>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_relops.h b/darkice/tags/darkice-0_2/stl/stl_relops.h new file mode 100644 index 0000000..16cad1b --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_relops.h @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_RELOPS +#define __SGI_STL_INTERNAL_RELOPS + +__STL_BEGIN_RELOPS_NAMESPACE + +template +inline bool operator!=(const _Tp& __x, const _Tp& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const _Tp& __x, const _Tp& __y) { + return __y < __x; +} + +template +inline bool operator<=(const _Tp& __x, const _Tp& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const _Tp& __x, const _Tp& __y) { + return !(__x < __y); +} + +__STL_END_RELOPS_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_RELOPS */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_rope.h b/darkice/tags/darkice-0_2/stl/stl_rope.h new file mode 100644 index 0000000..54ddb70 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_rope.h @@ -0,0 +1,2714 @@ +/* + * Copyright (c) 1997-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +// rope<_CharT,_Alloc> is a sequence of _CharT. +// Ropes appear to be mutable, but update operations +// really copy enough of the data structure to leave the original +// valid. Thus ropes can be logically copied by just copying +// a pointer value. + +#ifndef __SGI_STL_INTERNAL_ROPE_H +# define __SGI_STL_INTERNAL_ROPE_H + +# ifdef __GC +# define __GC_CONST const +# else +# include +# define __GC_CONST // constant except for deallocation +# endif +# ifdef __STL_SGI_THREADS +# include +# endif + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// The _S_eos function is used for those functions that +// convert to/from C-like strings to detect the end of the string. + +// The end-of-C-string character. +// This is what the draft standard says it should be. +template +inline _CharT _S_eos(_CharT*) { return _CharT(); } + +// Test for basic character types. +// For basic character types leaves having a trailing eos. +template +inline bool _S_is_basic_char_type(_CharT*) { return false; } +template +inline bool _S_is_one_byte_char_type(_CharT*) { return false; } + +inline bool _S_is_basic_char_type(char*) { return true; } +inline bool _S_is_one_byte_char_type(char*) { return true; } +inline bool _S_is_basic_char_type(wchar_t*) { return true; } + +// Store an eos iff _CharT is a basic character type. +// Do not reference _S_eos if it isn't. +template +inline void _S_cond_store_eos(_CharT&) {} + +inline void _S_cond_store_eos(char& __c) { __c = 0; } +inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } + +// char_producers are logically functions that generate a section of +// a string. These can be convereted to ropes. The resulting rope +// invokes the char_producer on demand. This allows, for example, +// files to be viewed as ropes without reading the entire file. +template +class char_producer { + public: + virtual ~char_producer() {}; + virtual void operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. +}; + +// Sequence buffers: +// +// Sequence must provide an append operation that appends an +// array to the sequence. Sequence buffers are useful only if +// appending an entire array is cheaper than appending element by element. +// This is true for many string representations. +// This should perhaps inherit from ostream +// and be implemented correspondingly, so that they can be used +// for formatted. For the sake of portability, we don't do this yet. +// +// For now, sequence buffers behave as output iterators. But they also +// behave a little like basic_ostringstream and a +// little like containers. + +template +// The 3rd parameter works around a common compiler bug. +class sequence_buffer : public output_iterator { + public: +# ifndef __TYPEDEF_WORKAROUND + typedef typename _Sequence::value_type value_type; +# else + typedef _V value_type; +# endif + protected: + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; + public: + void flush() { + _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); + _M_buf_count = 0; + } + ~sequence_buffer() { flush(); } + sequence_buffer() : _M_prefix(0), _M_buf_count(0) {} + sequence_buffer(const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + } + sequence_buffer(sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + } + sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {} + sequence_buffer& operator= (sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + return *this; + } + sequence_buffer& operator= (const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + return *this; + } + void push_back(value_type __x) + { + if (_M_buf_count < _Buf_sz) { + _M_buffer[_M_buf_count] = __x; + ++_M_buf_count; + } else { + flush(); + _M_buffer[0] = __x; + _M_buf_count = 1; + } + } + void append(value_type* __s, size_t __len) + { + if (__len + _M_buf_count <= _Buf_sz) { + size_t __i = _M_buf_count; + size_t __j = 0; + for (; __j < __len; __i++, __j++) { + _M_buffer[__i] = __s[__j]; + } + _M_buf_count += __len; + } else if (0 == _M_buf_count) { + _M_prefix->append(__s, __s + __len); + } else { + flush(); + append(__s, __len); + } + } + sequence_buffer& write(value_type* __s, size_t __len) + { + append(__s, __len); + return *this; + } + sequence_buffer& put(value_type __x) + { + push_back(__x); + return *this; + } + sequence_buffer& operator=(const value_type& __rhs) + { + push_back(__rhs); + return *this; + } + sequence_buffer& operator*() { return *this; } + sequence_buffer& operator++() { return *this; } + sequence_buffer& operator++(int) { return *this; } +}; + +// The following should be treated as private, at least for now. +template +class _Rope_char_consumer { + public: + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() {}; + virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; +}; + +// First a lot of forward declarations. The standard seems to require +// much stricter "declaration before use" than many of the implementations +// that preceded it. +template class rope; +template struct _Rope_RopeConcatenation; +template struct _Rope_RopeLeaf; +template struct _Rope_RopeFunction; +template struct _Rope_RopeSubstring; +template class _Rope_iterator; +template class _Rope_const_iterator; +template class _Rope_char_ref_proxy; +template class _Rope_char_ptr_proxy; + +template +bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); + +template +_Rope_const_iterator<_CharT,_Alloc> operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_const_iterator<_CharT,_Alloc> operator+ + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_const_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); + +template +bool operator== + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template +bool operator< + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template +ptrdiff_t operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template +_Rope_iterator<_CharT,_Alloc> operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_iterator<_CharT,_Alloc> operator+ + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); + +template +bool operator== + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template +bool operator< + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template +ptrdiff_t operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + +template +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + +template +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + _CharT __right); + +// Some helpers, so we can use power on ropes. +// See below for why this isn't local to the implementation. + +// This uses a nonstandard refcount convention. +// The result has refcount 0. +template +struct _Rope_Concat_fn + : public binary_function, rope<_CharT,_Alloc>, + rope<_CharT,_Alloc> > { + rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x, + const rope<_CharT,_Alloc>& __y) { + return __x + __y; + } +}; + +template +inline +rope<_CharT,_Alloc> +identity_element(_Rope_Concat_fn<_CharT, _Alloc>) +{ + return rope<_CharT,_Alloc>(); +} + + +// +// What follows should really be local to rope. Unfortunately, +// that doesn't work, since it makes it impossible to define generic +// equality on rope iterators. According to the draft standard, the +// template parameters for such an equality operator cannot be inferred +// from the occurence of a member class as a parameter. +// (SGI compilers in fact allow this, but the __result wouldn't be +// portable.) +// Similarly, some of the static member functions are member functions +// only to avoid polluting the global namespace, and to circumvent +// restrictions on type inference for template functions. +// + +// +// The internal data structure for representing a rope. This is +// private to the implementation. A rope is really just a pointer +// to one of these. +// +// A few basic functions for manipulating this data structure +// are members of _RopeRep. Most of the more complex algorithms +// are implemented as rope members. +// +// Some of the static member functions of _RopeRep have identically +// named functions in rope that simply invoke the _RopeRep versions. +// +// A macro to introduce various allocation and deallocation functions +// These need to be defined differently depending on whether or not +// we are using standard conforming allocators, and whether the allocator +// instances have real state. Thus this macro is invoked repeatedly +// with different definitions of __ROPE_DEFINE_ALLOC. +// __ROPE_DEFINE_ALLOC(type,name) defines +// type * name_allocate(size_t) and +// void name_deallocate(tipe *, size_t) +// Both functions may or may not be static. + +#define __ROPE_DEFINE_ALLOCS(__a) \ + __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ + typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ + __ROPE_DEFINE_ALLOC(__C,_C) \ + typedef _Rope_RopeLeaf<_CharT,__a> __L; \ + __ROPE_DEFINE_ALLOC(__L,_L) \ + typedef _Rope_RopeFunction<_CharT,__a> __F; \ + __ROPE_DEFINE_ALLOC(__F,_F) \ + typedef _Rope_RopeSubstring<_CharT,__a> __S; \ + __ROPE_DEFINE_ALLOC(__S,_S) + +// Internal rope nodes potentially store a copy of the allocator +// instance used to allocate them. This is mostly redundant. +// But the alternative would be to pass allocator instances around +// in some form to nearly all internal functions, since any pointer +// assignment may result in a zero reference count and thus require +// deallocation. +// The _Rope_rep_base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +#define __STATIC_IF_SGI_ALLOC /* not static */ + +// Base class for ordinary allocators. +template +class _Rope_rep_alloc_base { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_rep_alloc_base(size_t __size, const allocator_type& __a) + : _M_size(__size), _M_data_allocator(__a) {} + size_t _M_size; // This is here only to avoid wasting space + // for an otherwise empty base class. + + +protected: + allocator_type _M_data_allocator; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + /*static*/ _Tp * __name##_allocate(size_t __n) \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Rope_rep_alloc_base<_CharT,_Allocator,true> { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_rep_alloc_base(size_t __size, const allocator_type&) + : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +template +struct _Rope_rep_base + : public _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + _Rope_rep_base(size_t __size, const allocator_type& __a) + : _Base(__size, __a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +#define __STATIC_IF_SGI_ALLOC static + +template +class _Rope_rep_base { +public: + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_rep_base(size_t __size, const allocator_type&) : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc); +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + + +template +struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> +# ifndef __GC + , _Refcount_Base +# endif +{ + public: + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; + _Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeRep(_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _Rope_rep_base<_CharT,_Alloc>(__size, __a), +# ifndef __GC + _Refcount_Base(1), +# endif + _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) + { } +# ifdef __GC + void _M_incr () {} +# endif +# ifdef __STL_USE_STD_ALLOCATORS + static void _S_free_string(__GC_CONST _CharT*, size_t __len, + allocator_type __a); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); +# else + static void _S_free_string(__GC_CONST _CharT*, size_t __len); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l); +# endif + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. +# ifndef __GC + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void _M_unref_nonnil() + { + if (0 == _M_decr()) _M_free_tree(); + } + void _M_ref_nonnil() + { + _M_incr(); + } + static void _S_unref(_Rope_RopeRep* __t) + { + if (0 != __t) { + __t->_M_unref_nonnil(); + } + } + static void _S_ref(_Rope_RopeRep* __t) + { + if (0 != __t) __t->_M_incr(); + } + static void _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_ref_count) __t->_M_free_tree(); + } +# else /* __GC */ + void _M_unref_nonnil() {} + void _M_ref_nonnil() {} + static void _S_unref(_Rope_RopeRep*) {} + static void _S_ref(_Rope_RopeRep*) {} + static void _S_free_if_unref(_Rope_RopeRep*) {} +# endif + +}; + +template +struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> { + public: + // Apparently needed by VC++ + // The data fields of leaves are allocated with some + // extra space, to accomodate future growth and for basic + // character types, to hold a trailing eos character. + enum { _S_alloc_granularity = 8 }; + static size_t _S_rounded_up_size(size_t __n) { + size_t __size_with_eos; + + if (_S_is_basic_char_type((_CharT*)0)) { + __size_with_eos = __n + 1; + } else { + __size_with_eos = __n; + } +# ifdef __GC + return __size_with_eos; +# else + // Allow slop for in-place expansion. + return (__size_with_eos + _S_alloc_granularity-1) + &~ (_S_alloc_granularity-1); +# endif + } + __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* _S_rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_S_leaf, 0, true, __size, __a), + _M_data(__d) + { + __stl_assert(__size > 0); + if (_S_is_basic_char_type((_CharT *)0)) { + // already eos terminated. + _M_c_string = __d; + } + } + // The constructor assumes that d has been allocated with + // the proper allocator and the properly padded size. + // In contrast, the destructor deallocates the data: +# ifndef __GC + ~_Rope_RopeLeaf() { + if (_M_data != _M_c_string) { + _M_free_c_string(); + } + __STL_FREE_STRING(_M_data, _M_size, get_allocator()); + } +# endif +}; + +template +struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { + public: + _Rope_RopeRep<_CharT,_Alloc>* _M_left; + _Rope_RopeRep<_CharT,_Alloc>* _M_right; + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, + _Rope_RopeRep<_CharT,_Alloc>* __r, + allocator_type __a) + + : _Rope_RopeRep<_CharT,_Alloc>(_S_concat, + max(__l->_M_depth, __r->_M_depth) + 1, + false, + __l->_M_size + __r->_M_size, __a), + _M_left(__l), _M_right(__r) + {} +# ifndef __GC + ~_Rope_RopeConcatenation() { + _M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +# endif +}; + +template +struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { + public: + char_producer<_CharT>* _M_fn; +# ifndef __GC + bool _M_delete_when_done; // Char_producer is owned by the + // rope and should be explicitly + // deleted when the rope becomes + // inaccessible. +# else + // In the GC case, we either register the rope for + // finalization, or not. Thus the field is unnecessary; + // the information is stored in the collector data structures. + // We do need a finalization procedure to be invoked by the + // collector. + static void _S_fn_finalization_proc(void * __tree, void *) { + delete ((_Rope_RopeFunction *)__tree) -> _M_fn; + } +# endif + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_S_function, 0, true, __size, __a) + , _M_fn(__f) +# ifndef __GC + , _M_delete_when_done(__d) +# endif + { + __stl_assert(__size > 0); +# ifdef __GC + if (__d) { + GC_REGISTER_FINALIZER( + this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); + } +# endif + } +# ifndef __GC + ~_Rope_RopeFunction() { + _M_free_c_string(); + if (_M_delete_when_done) { + delete _M_fn; + } + } +# endif +}; +// Substring results are usually represented using just +// concatenation nodes. But in the case of very long flat ropes +// or ropes with a functional representation that isn't practical. +// In that case, we represent the __result as a special case of +// RopeFunction, whose char_producer points back to the rope itself. +// In all cases except repeated substring operations and +// deallocation, we treat the __result as a RopeFunction. +template +struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>, + public char_producer<_CharT> { + public: + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + virtual void operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) { + switch(_M_base->_M_tag) { + case _S_function: + case _S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + __stl_assert(__start_pos + __req_len <= _M_size); + __stl_assert(_M_start + _M_size <= _M_base->_M_size); + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case _S_leaf: + { + __GC_CONST _CharT* __s = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; + uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, + __buffer); + } + break; + default: + __stl_assert(false); + } + } + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + : _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a), + char_producer<_CharT>(), + _M_base(__b), + _M_start(__s) + { + __stl_assert(__l > 0); + __stl_assert(__s + __l <= __b->_M_size); +# ifndef __GC + _M_base->_M_ref_nonnil(); +# endif + _M_tag = _S_substringfn; + } + virtual ~_Rope_RopeSubstring() + { +# ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +# endif + } +}; + + +// Self-destructing pointers to Rope_rep. +// These are not conventional smart pointers. Their +// only purpose in life is to ensure that unref is called +// on the pointer either at normal exit or if an exception +// is raised. It is the caller's responsibility to +// adjust reference counts when these pointers are initialized +// or assigned to. (This convention significantly reduces +// the number of potentially expensive reference count +// updates.) +#ifndef __GC + template + struct _Rope_self_destruct_ptr { + _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } +# ifdef __STL_USE_EXCEPTIONS + _Rope_self_destruct_ptr() : _M_ptr(0) {}; +# else + _Rope_self_destruct_ptr() {}; +# endif + _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {} + _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; } + _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; } + operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; } + _Rope_self_destruct_ptr& operator= (_Rope_RopeRep<_CharT,_Alloc>* __x) + { _M_ptr = __x; return *this; } + }; +#endif + +// Dereferencing a nonconst iterator has to return something +// that behaves almost like a reference. It's not possible to +// return an actual reference since assignment requires extra +// work. And we would get into the same problems as with the +// CD2 version of basic_string. +template +class _Rope_char_ref_proxy { + friend class rope<_CharT,_Alloc>; + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef rope<_CharT,_Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. + public: + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) + : _M_pos(__p), _M_current_valid(false), _M_root(__r) {} + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) + : _M_pos(__x._M_pos), _M_current_valid(false), _M_root(__x._M_root) {} + // Don't preserve cache if the reference can outlive the + // expression. We claim that's not possible without calling + // a copy constructor or generating reference to a proxy + // reference. We declare the latter to have undefined semantics. + _Rope_char_ref_proxy(_My_rope* __r, size_t __p, _CharT __c) + : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) {} + inline operator _CharT () const; + _Rope_char_ref_proxy& operator= (_CharT __c); + _Rope_char_ptr_proxy<_CharT,_Alloc> operator& () const; + _Rope_char_ref_proxy& operator= (const _Rope_char_ref_proxy& __c) { + return operator=((_CharT)__c); + } +}; + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + template + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; + } +#else +// There is no really acceptable way to handle this. The default +// definition of swap doesn't work for proxy references. +// It can't really be made to work, even with ugly hacks, since +// the only unusual operation it uses is the copy constructor, which +// is needed for other purposes. We provide a macro for +// full specializations, and instantiate the most common case. +# define _ROPE_SWAP_SPECIALIZATION(_CharT, __Alloc) \ + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, \ + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { \ + _CharT __tmp = __a; \ + __a = __b; \ + __b = __tmp; \ + } + +_ROPE_SWAP_SPECIALIZATION(char,__STL_DEFAULT_ALLOCATOR(char)) + +#endif /* !__STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +class _Rope_char_ptr_proxy { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. + public: + _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy() {} + _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { + __stl_assert(0 == __x); + } + _Rope_char_ptr_proxy& + operator= (const _Rope_char_ptr_proxy& __x) { + _M_pos = __x._M_pos; + _M_root = __x._M_root; + return *this; + } +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __x, + const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __y); +#else + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); +#endif + _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const { + return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos); + } +}; + + +// Rope iterators: +// Unlike in the C version, we cache only part of the stack +// for rope iterators, since they must be efficiently copyable. +// When we run out of cache, we have to reconstruct the iterator +// value. +// Pointers from iterators are not included in reference counts. +// Iterators are assumed to be thread private. Ropes can +// be shared. + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1375 +#endif + +template +class _Rope_iterator_base + : public random_access_iterator<_CharT, ptrdiff_t> { + friend class rope<_CharT,_Alloc>; + public: + typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // Borland doesnt want this to be protected. + protected: + enum { _S_path_cache_len = 4 }; // Must be <= 9. + enum { _S_iterator_buf_len = 15 }; + size_t _M_current_pos; + _RopeRep* _M_root; // The whole rope. + size_t _M_leaf_pos; // Starting position for current leaf + __GC_CONST _CharT* _M_buf_start; + // Buffer possibly + // containing current char. + __GC_CONST _CharT* _M_buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST _CharT* _M_buf_end; + // One past __last valid char in buffer. + // What follows is the path cache. We go out of our + // way to make this compact. + // Path_end contains the bottom section of the path from + // the root to the current leaf. + const _RopeRep* _M_path_end[_S_path_cache_len]; + int _M_leaf_index; // Last valid __pos in path_end; + // _M_path_end[0] ... _M_path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char _M_path_directions; + // (path_directions >> __i) & 1 is 1 + // iff we got from _M_path_end[leaf_index - __i - 1] + // to _M_path_end[leaf_index - __i] by going to the + // __right. Assumes path_cache_len <= 9. + _CharT _M_tmp_buf[_S_iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. + // The cached path is generally assumed to be valid + // only if the buffer is valid. + static void _S_setbuf(_Rope_iterator_base& __x); + // Set buffer contents given + // path cache. + static void _S_setcache(_Rope_iterator_base& __x); + // Set buffer contents and + // path cache. + static void _S_setcache_for_incr(_Rope_iterator_base& __x); + // As above, but assumes path + // cache is valid for previous posn. + _Rope_iterator_base() {} + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) {} + void _M_incr(size_t __n); + void _M_decr(size_t __n); + public: + size_t index() const { return _M_current_pos; } + _Rope_iterator_base(const _Rope_iterator_base& __x) { + if (0 != __x._M_buf_ptr) { + *this = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + } +}; + +template class _Rope_iterator; + +template +class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: +# ifdef __STL_HAS_NAMESPACES + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // The one from the base class may not be directly visible. +# endif + _Rope_const_iterator(const _RopeRep* __root, size_t __pos): + _Rope_iterator_base<_CharT,_Alloc>( + const_cast<_RopeRep*>(__root), __pos) + // Only nonconst iterators modify root ref count + {} + public: + typedef _CharT reference; // Really a value. Returning a reference + // Would be a mess, since it would have + // to be included in refcount. + typedef const _CharT* pointer; + + public: + _Rope_const_iterator() {}; + _Rope_const_iterator(const _Rope_const_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { } + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) : + _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {} + _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) { + if (0 != __x._M_buf_ptr) { + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + return(*this); + } + reference operator*() { + if (0 == _M_buf_ptr) _S_setcache(*this); + return *_M_buf_ptr; + } + _Rope_const_iterator& operator++() { + __GC_CONST _CharT* __next; + if (0 != _M_buf_ptr && (__next = _M_buf_ptr + 1) < _M_buf_end) { + _M_buf_ptr = __next; + ++_M_current_pos; + } else { + _M_incr(1); + } + return *this; + } + _Rope_const_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; + } + _Rope_const_iterator& operator--() { + _M_decr(1); + return *this; + } + _Rope_const_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; + } + _Rope_const_iterator operator++(int) { + size_t __old_pos = _M_current_pos; + _M_incr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? + } + _Rope_const_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); + } +#if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) + template + friend _Rope_const_iterator<_CharT2,_Alloc2> operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT2,_Alloc2>& __x); +#else + friend _Rope_const_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); +#endif + + reference operator[](size_t __n) { + return rope<_CharT,_Alloc>::_S_fetch(_M_root, _M_current_pos + __n); + } + +#if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) + template + friend bool operator== + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template + friend bool operator< + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template + friend ptrdiff_t operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); +#else + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + friend bool operator< __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); +#endif +}; + +template +class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: + rope<_CharT,_Alloc>* _M_root_rope; + // root is treated as a cached version of this, + // and is used to detect changes to the underlying + // rope. + // Root is included in the reference count. + // This is necessary so that we can detect changes reliably. + // Unfortunately, it requires careful bookkeeping for the + // nonGC case. + _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos), + _M_root_rope(__r) + { _RopeRep::_S_ref(_M_root); if (!(__r -> empty()))_S_setcache(*this); } + + void _M_check(); + public: + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer; + + public: + rope<_CharT,_Alloc>& container() { return *_M_root_rope; } + _Rope_iterator() { + _M_root = 0; // Needed for reference counting. + }; + _Rope_iterator(const _Rope_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { + _M_root_rope = __x._M_root_rope; + _RopeRep::_S_ref(_M_root); + } + _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); + ~_Rope_iterator() { + _RopeRep::_S_unref(_M_root); + } + _Rope_iterator& operator= (const _Rope_iterator& __x) { + _RopeRep* __old = _M_root; + + _RopeRep::_S_ref(__x._M_root); + if (0 != __x._M_buf_ptr) { + _M_root_rope = __x._M_root_rope; + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_root_rope = __x._M_root_rope; + _M_buf_ptr = 0; + } + _RopeRep::_S_unref(__old); + return(*this); + } + reference operator*() { + _M_check(); + if (0 == _M_buf_ptr) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos); + } else { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos, *_M_buf_ptr); + } + } + _Rope_iterator& operator++() { + _M_incr(1); + return *this; + } + _Rope_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; + } + _Rope_iterator& operator--() { + _M_decr(1); + return *this; + } + _Rope_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; + } + _Rope_iterator operator++(int) { + size_t __old_pos = _M_current_pos; + _M_incr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + _Rope_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + reference operator[](ptrdiff_t __n) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos + __n); + } + +#if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) + template + friend bool operator== + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template + friend bool operator< + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template + friend ptrdiff_t operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template + friend _Rope_iterator<_CharT2,_Alloc2> operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT2,_Alloc2>& __x); +#else + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend bool operator< __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend _Rope_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); +#endif +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1375 +#endif + +// The rope base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Rope_alloc_base { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_alloc_base(_RopeRep *__t, const allocator_type& __a) + : _M_tree_ptr(__t), _M_data_allocator(__a) {} + _Rope_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a) {} + +protected: + // The only data members of a rope: + allocator_type _M_data_allocator; + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + _Tp* __name##_allocate(size_t __n) const \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) const \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Rope_alloc_base<_CharT,_Allocator,true> { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_alloc_base(_RopeRep *__t, const allocator_type&) + : _M_tree_ptr(__t) {} + _Rope_alloc_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +template +struct _Rope_base + : public _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // The one in _Base may not be visible due to template rules. + _Rope_base(_RopeRep* __t, const allocator_type& __a) : _Base(__t, __a) {} + _Rope_base(const allocator_type& __a) : _Base(__a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +template +class _Rope_base { +public: + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_base(_RopeRep * __t, const allocator_type&) : _M_tree_ptr(__t) {} + _Rope_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + + +template +class rope : public _Rope_base<_CharT,_Alloc> { + public: + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT,_Alloc> iterator; + typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer; + + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_const_iterator<_CharT,_Alloc>; + friend struct _Rope_RopeRep<_CharT,_Alloc>; + friend class _Rope_iterator_base<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + friend struct _Rope_RopeSubstring<_CharT,_Alloc>; + + protected: + typedef _Rope_base<_CharT,_Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; +# ifdef __STL_USE_NAMESPACES + using _Base::_M_tree_ptr; +# endif + typedef __GC_CONST _CharT* _Cstrptr; + + static _CharT _S_empty_c_str[1]; + + static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); } + enum { _S_copy_max = 23 }; + // For strings shorter than _S_copy_max, we copy to + // concatenate. + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation; + typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf; + typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction; + typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring; + + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); + +# ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); +# endif + + static bool _S_apply_to_pieces( + // should be template parameter + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end); + // begin and end are assumed to be in range. + +# ifndef __GC + static void _S_unref(_RopeRep* __t) + { + _RopeRep::_S_unref(__t); + } + static void _S_ref(_RopeRep* __t) + { + _RopeRep::_S_ref(__t); + } +# else /* __GC */ + static void _S_unref(_RopeRep*) {} + static void _S_ref(_RopeRep*) {} +# endif + + +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + + // _Result is counted in refcount. + static _RopeRep* _S_substring(_RopeRep* __base, + size_t __start, size_t __endp1); + + static _RopeRep* _S_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen); + // Concatenate rope and char ptr, copying __s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen) + // As above, but one reference to __r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevent reference counts are 1. +# ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return _S_concat_char_iter(__r, __iter, __slen); } +# else + ; +# endif + + static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); + // General concatenation on _RopeRep. _Result + // has refcount of 1. Adjusts argument refcounts. + + public: + void apply_to_pieces( size_t __begin, size_t __end, + _Rope_char_consumer<_CharT>& __c) const { + _S_apply_to_pieces(__c, _M_tree_ptr, __begin, __end); + } + + + protected: + + static size_t _S_rounded_up_size(size_t __n) { + return _RopeLeaf::_S_rounded_up_size(__n); + } + + static size_t _S_allocated_capacity(size_t __n) { + if (_S_is_basic_char_type((_CharT*)0)) { + return _S_rounded_up_size(__n) - 1; + } else { + return _S_rounded_up_size(__n); + } + } + + // Allocate and construct a RopeLeaf using the supplied allocator + // Takes ownership of s instead of copying. + static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s, + size_t __size, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeLeaf* __space = _LAllocator(__a).allocate(1); +# else + _RopeLeaf* __space = _L_allocate(1); +# endif + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* _S_new_RopeConcatenation( + _RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeConcatenation* __space = _CAllocator(__a).allocate(1); +# else + _RopeConcatenation* __space = _C_allocate(1); +# endif + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeFunction* __space = _FAllocator(__a).allocate(1); +# else + _RopeFunction* __space = _F_allocate(1); +# endif + return new(__space) _RopeFunction(__f, __size, __d, __a); + } + + static _RopeSubstring* _S_new_RopeSubstring( + _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeSubstring* __space = _SAllocator(__a).allocate(1); +# else + _RopeSubstring* __space = _S_allocate(1); +# endif + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + +# ifdef __STL_USE_STD_ALLOCATORS + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, + size_t __size, allocator_type __a) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) +# else + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr2(const _CharT* __s, + size_t __size) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr2(__s, __size) +# endif + { + if (0 == __size) return 0; +# ifdef __STL_USE_STD_ALLOCATORS + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); +# else + _CharT* __buf = _Data_allocate(_S_rounded_up_size(__size)); + allocator_type __a = allocator_type(); +# endif + + uninitialized_copy_n(__s, __size, __buf); + _S_cond_store_eos(__buf[__size]); + __STL_TRY { + return _S_new_RopeLeaf(__buf, __size, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, __size, __a)) + } + + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static _RopeRep* + _S_tree_concat(_RopeRep* __left, _RopeRep* __right); + + // Concatenation helper functions + static _RopeLeaf* + _S_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +# ifndef __GC + static _RopeLeaf* _S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __slen); + // A version that potentially clobbers __r if __r->_M_ref_count == 1. +# endif + + private: + + static size_t _S_char_ptr_len(const _CharT* __s); + // slightly generalized strlen + + rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) + : _Base(__t,__a) { } + + + // Copy __r to the _CharT buffer. + // Returns __buffer + __r->_M_size. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer); + + static const unsigned long + _S_min_len[_RopeRep::_S_max_rope_depth + 1]; + + static bool _S_is_balanced(_RopeRep* __r) + { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } + + static bool _S_is_almost_balanced(_RopeRep* __r) + { return (__r->_M_depth == 0 || + __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } + + static bool _S_is_roughly_balanced(_RopeRep* __r) + { return (__r->_M_depth <= 1 || + __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } + + // Assumes the result is not empty. + static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, + _RopeRep* __right) + { + _RopeRep* __result = _S_concat(__left, __right); + if (_S_is_balanced(__result)) __result->_M_is_balanced = true; + return __result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of __r. + // The result is within height 2 of balanced by the above + // definition. + static _RopeRep* _S_balance(_RopeRep* __r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); + + // Add __r to forest, assuming __r is already balanced. + static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); + + // Print to stdout, exposing structure + static void _S_dump(_RopeRep* __r, int __indent = 0); + + // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. + static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); + + public: + bool empty() const { return 0 == _M_tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int compare(const rope& __y) const { + return _S_compare(_M_tree_ptr, __y._M_tree_ptr); + } + + rope(const _CharT* __s, const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), + __a),__a) + { } + + rope(const _CharT* __s, size_t __len, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a) + { } + + // Should perhaps be templatized with respect to the iterator type + // and use Sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const _CharT *__s, const _CharT *__e, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) + { } + + rope(const const_iterator& __s, const const_iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(const iterator& __s, const iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(_CharT __c, const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _CharT* __buf = _Data_allocate(_S_rounded_up_size(1)); + + construct(__buf, __c); + __STL_TRY { + _M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, 1, __a)) + } + + rope(size_t __n, _CharT __c, + const allocator_type& __a = allocator_type()); + + rope(const allocator_type& __a = allocator_type()) + : _Base(0, __a) {} + + // Construct a rope from a function that can compute its members + rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_tree_ptr = (0 == __len) ? + 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); + } + + rope(const rope& __x, const allocator_type& __a = allocator_type()) + : _Base(__x._M_tree_ptr, __a) + { + _S_ref(_M_tree_ptr); + } + + ~rope() + { + _S_unref(_M_tree_ptr); + } + + rope& operator=(const rope& __x) + { + _RopeRep* __old = _M_tree_ptr; +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __x.get_allocator()); +# endif + _M_tree_ptr = __x._M_tree_ptr; + _S_ref(_M_tree_ptr); + _S_unref(__old); + return(*this); + } + + void clear() + { + _S_unref(_M_tree_ptr); + _M_tree_ptr = 0; + } + + void push_back(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_destr_concat_char_iter(_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void pop_back() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = + _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT back() const + { + return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1); + } + + void push_front(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator()); + __STL_TRY { + _M_tree_ptr = _S_concat(__left, _M_tree_ptr); + _S_unref(__old); + _S_unref(__left); + } + __STL_UNWIND(_S_unref(__left)) + } + + void pop_front() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT front() const + { + return _S_fetch(_M_tree_ptr, 0); + } + + void balance() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_balance(_M_tree_ptr); + _S_unref(__old); + } + + void copy(_CharT* __buffer) const { + destroy(__buffer, __buffer + size()); + _S_flatten(_M_tree_ptr, __buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const + { + size_t __size = size(); + size_t __len = (__pos + __n > __size? __size - __pos : __n); + + destroy(__buffer, __buffer + __len); + _S_flatten(_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void dump() { + _S_dump(_M_tree_ptr); + } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const _CharT* c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const _CharT* replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void delete_c_str () { + if (0 == _M_tree_ptr) return; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && + ((_RopeLeaf*)_M_tree_ptr)->_M_data == + _M_tree_ptr->_M_c_string) { + // Representation shared + return; + } +# ifndef __GC + _M_tree_ptr->_M_free_c_string(); +# endif + _M_tree_ptr->_M_c_string = 0; + } + + _CharT operator[] (size_type __pos) const { + return _S_fetch(_M_tree_ptr, __pos); + } + + _CharT at(size_type __pos) const { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + const_iterator begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + // An easy way to get a const iterator from a non-const container. + const_iterator const_begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + const_iterator end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + const_iterator const_end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + size_type size() const { + return(0 == _M_tree_ptr? 0 : _M_tree_ptr->_M_size); + } + + size_type length() const { + return size(); + } + + size_type max_size() const { + return _S_min_len[_RopeRep::_S_max_rope_depth-1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } + +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator const_reverse_iterator; +# endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator const_rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator const_rend() const { + return const_reverse_iterator(begin()); + } + +#if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) + template + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const rope<_CharT2,_Alloc2>& __right); + + template + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const _CharT2* __right); + + template + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, _CharT2 __right); +#else + friend rope<_CharT,_Alloc> __STD_QUALIFIER + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + + friend rope<_CharT,_Alloc> __STD_QUALIFIER + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + + friend rope<_CharT,_Alloc> __STD_QUALIFIER + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + _CharT __right); +#endif + // The symmetric cases are intentionally omitted, since they're presumed + // to be less common, and we don't handle them as well. + + // The following should really be templatized. + // The first argument should be an input iterator or + // forward iterator with value_type _CharT. + rope& append(const _CharT* __iter, size_t __n) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __iter, __n); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const _CharT* __c_string) { + size_t __len = _S_char_ptr_len(__c_string); + append(__c_string, __len); + return(*this); + } + + rope& append(const _CharT* __s, const _CharT* __e) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __s, __e - __s); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const_iterator __s, const_iterator __e) { + __stl_assert(__s._M_root == __e._M_root); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __s._M_root->get_allocator()); +# endif + _Self_destruct_ptr __appendee(_S_substring( + __s._M_root, __s._M_current_pos, __e._M_current_pos)); + _RopeRep* __result = + _S_concat(_M_tree_ptr, (_RopeRep*)__appendee); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(_CharT __c) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, &__c, 1); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append() { return append(_CharT()); } // XXX why? + + rope& append(const rope& __y) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__y.get_allocator() == get_allocator()); +# endif + _RopeRep* __result = _S_concat(_M_tree_ptr, __y._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __last(__n, __c); + return append(__last); + } + + void swap(rope& __b) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __b.get_allocator()); +# endif + _RopeRep* __tmp = _M_tree_ptr; + _M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } + + + protected: + // Result is included in refcount. + static _RopeRep* replace(_RopeRep* __old, size_t __pos1, + size_t __pos2, _RopeRep* __r) { + if (0 == __old) { _S_ref(__r); return __r; } + _Self_destruct_ptr __left( + _S_substring(__old, 0, __pos1)); + _Self_destruct_ptr __right( + _S_substring(__old, __pos2, __old->_M_size)); + _RopeRep* __result; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__old->get_allocator() == __r->get_allocator()); +# endif + if (0 == __r) { + __result = _S_concat(__left, __right); + } else { + _Self_destruct_ptr __left_result(_S_concat(__left, __r)); + __result = _S_concat(__left_result, __right); + } + return __result; + } + + public: + void insert(size_t __p, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p, __r._M_tree_ptr); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __r.get_allocator()); +# endif + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __r(__n,__c); + insert(__p, __r); + } + + void insert(size_t __p, const _CharT* __i, size_t __n) { + _Self_destruct_ptr __left(_S_substring(_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(_M_tree_ptr, __p, size())); + _Self_destruct_ptr __left_result( + _S_concat_char_iter(__left, __i, __n)); + // _S_ destr_concat_char_iter should be safe here. + // But as it stands it's probably not a win, since __left + // is likely to have additional references. + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, const _CharT* __c_string) { + insert(__p, __c_string, _S_char_ptr_len(__c_string)); + } + + void insert(size_t __p, _CharT __c) { + insert(__p, &__c, 1); + } + + void insert(size_t __p) { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } + + void insert(size_t __p, const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const iterator& __i, + const iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + // (position, length) versions of replace operations: + + void replace(size_t __p, size_t __n, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, size_t __i_len) { + rope __r(__i, __i_len); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, _CharT __c) { + rope __r(__c); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, const _CharT* __c_string) { + rope __r(__c_string); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const const_iterator& __i, const const_iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const iterator& __i, const iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + // Single character variants: + void replace(size_t __p, _CharT __c) { + iterator __i(this, __p); + *__i = __c; + } + + void replace(size_t __p, const rope& __r) { + replace(__p, 1, __r); + } + + void replace(size_t __p, const _CharT* __i, size_t __i_len) { + replace(__p, 1, __i, __i_len); + } + + void replace(size_t __p, const _CharT* __c_string) { + replace(__p, 1, __c_string); + } + + void replace(size_t __p, const _CharT* __i, const _CharT* __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const iterator& __i, + const iterator& __j) { + replace(__p, 1, __i, __j); + } + + // Erase, (position, size) variant. + void erase(size_t __p, size_t __n) { + _RopeRep* __result = replace(_M_tree_ptr, __p, __p + __n, 0); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + // Erase, single character + void erase(size_t __p) { + erase(__p, __p + 1); + } + + // Insert, iterator variants. + iterator insert(const iterator& __p, const rope& __r) + { insert(__p.index(), __r); return __p; } + iterator insert(const iterator& __p, size_t __n, _CharT __c) + { insert(__p.index(), __n, __c); return __p; } + iterator insert(const iterator& __p, _CharT __c) + { insert(__p.index(), __c); return __p; } + iterator insert(const iterator& __p ) + { insert(__p.index()); return __p; } + iterator insert(const iterator& __p, const _CharT* c_string) + { insert(__p.index(), c_string); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, size_t __n) + { insert(__p.index(), __i, __n); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, + const _CharT* __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const const_iterator& __i, const const_iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const iterator& __i, const iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + + // Replace, range variants. + void replace(const iterator& __p, const iterator& __q, + const rope& __r) + { replace(__p.index(), __q.index() - __p.index(), __r); } + void replace(const iterator& __p, const iterator& __q, _CharT __c) + { replace(__p.index(), __q.index() - __p.index(), __c); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __c_string) + { replace(__p.index(), __q.index() - __p.index(), __c_string); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, size_t __n) + { replace(__p.index(), __q.index() - __p.index(), __i, __n); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const const_iterator& __i, const const_iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const iterator& __i, const iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + // Replace, iterator variants. + void replace(const iterator& __p, const rope& __r) + { replace(__p.index(), __r); } + void replace(const iterator& __p, _CharT __c) + { replace(__p.index(), __c); } + void replace(const iterator& __p, const _CharT* __c_string) + { replace(__p.index(), __c_string); } + void replace(const iterator& __p, const _CharT* __i, size_t __n) + { replace(__p.index(), __i, __n); } + void replace(const iterator& __p, const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, const_iterator __i, + const_iterator __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, iterator __i, iterator __j) + { replace(__p.index(), __i, __j); } + + // Iterator and range variants of erase + iterator erase(const iterator& __p, const iterator& __q) { + size_t __p_index = __p.index(); + erase(__p_index, __q.index() - __p_index); + return iterator(this, __p_index); + } + iterator erase(const iterator& __p) { + size_t __p_index = __p.index(); + erase(__p_index, 1); + return iterator(this, __p_index); + } + + rope substr(size_t __start, size_t __len = 1) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start, __start + __len)); + } + + rope substr(iterator __start, iterator __end) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope substr(iterator __start) const { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + rope substr(const_iterator __start, const_iterator __end) const { + // This might eventually take advantage of the cache in the + // iterator. + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope<_CharT,_Alloc> substr(const_iterator __start) { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + size_type find(const _CharT* __s, size_type __pos = 0) const { + size_type __result_pos; + const_iterator __result = search(const_begin() + __pos, const_end(), + __s, __s + _S_char_ptr_len(__s)); + __result_pos = __result.index(); +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; + } + + iterator mutable_begin() { + return(iterator(this, 0)); + } + + iterator mutable_end() { + return(iterator(this, size())); + } + +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator reverse_iterator; +# endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + reverse_iterator mutable_rbegin() { + return reverse_iterator(mutable_end()); + } + + reverse_iterator mutable_rend() { + return reverse_iterator(mutable_begin()); + } + + reference mutable_reference_at(size_type __pos) { + return reference(this, __pos); + } + +# ifdef __STD_STUFF + reference operator[] (size_type __pos) { + return _char_ref_proxy(this, __pos); + } + + reference at(size_type __pos) { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + void resize(size_type __n, _CharT __c) {} + void resize(size_type __n) {} + void reserve(size_type __res_arg = 0) {} + size_type capacity() const { + return max_size(); + } + + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const { + return copy(__pos, __n, __buffer); + } + + iterator end() { return mutable_end(); } + + iterator begin() { return mutable_begin(); } + + reverse_iterator rend() { return mutable_rend(); } + + reverse_iterator rbegin() { return mutable_rbegin(); } + +# else + + const_iterator end() { return const_end(); } + + const_iterator begin() { return const_begin(); } + + const_reverse_iterator rend() { return const_rend(); } + + const_reverse_iterator rbegin() { return const_rbegin(); } + +# endif + +}; + +template +const rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = + (size_type)(-1); + +template +inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root == __y._M_root); +} + +template +inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator> (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos - __n); +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template +inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root_rope == __y._M_root_rope); +} + +template +inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator> (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos - __n); +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left.get_allocator() == __right.get_allocator()); +# endif + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); + // Inlining this should make it possible to keep __left and + // __right in registers. +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ + __left.append(__right); + return __left; +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, __right, __rlen)); +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + __left.append(__right); + return __left; +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, &__right, 1)); +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { + __left.append(__right); + return __left; +} + +template +bool +operator< (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) < 0; +} + +template +bool +operator== (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) == 0; +} + +template +inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool +operator> (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool +operator<= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool +operator>= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline bool operator!= (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifdef __STL_USE_NEW_IOSTREAMS + template + basic_ostream<_CharT, _Traits>& operator<< + (basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r); +#else + template + ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r); +#endif + +typedef rope crope; +typedef rope wrope; + +inline crope::reference __mutable_reference_at(crope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) { + __x.swap(__y); +} + +#else + +inline void swap(crope __x, crope __y) { __x.swap(__y); } +inline void swap(wrope __x, wrope __y) { __x.swap(__y); } + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Hash functions should probably be revisited later: +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const crope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + + +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const wrope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +# include + +# endif /* __SGI_STL_INTERNAL_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_set.h b/darkice/tags/darkice-0_2/stl/stl_set.h new file mode 100644 index 0000000..1916d21 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_set.h @@ -0,0 +1,268 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_SET_H +#define __SGI_STL_INTERNAL_SET_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Forward declarations of operators < and ==, needed for friend declaration. + +template ), + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > +class set; + +template +inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + +template +inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + +template +class set { + // requirements: + + __STL_CLASS_REQUIRES(_Key, _Assignable); + __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); + +public: + // typedefs: + + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing set +public: + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + set() : _M_t(_Compare(), allocator_type()) {} + explicit set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template + set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } +#else + set(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + pair insert(const value_type& __x) { + pair __p = _M_t.insert_unique(__x); + return pair(__p.first, __p.second); + } + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_unique((_Rep_iterator&)__position, __x); + } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); + } +#else + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_unique(__first, __last); + } + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + size_type erase(const key_type& __x) { + return _M_t.erase(__x); + } + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + void clear() { _M_t.clear(); } + + // set operations: + + iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { + return _M_t.find(__x) == _M_t.end() ? 0 : 1; + } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template + friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + template + friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); +#else /* __STL_TEMPLATE_FRIENDS */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const set&, const set&); + friend bool __STD_QUALIFIER + operator< __STL_NULL_TMPL_ARGS (const set&, const set&); +#endif /* __STL_TEMPLATE_FRIENDS */ +}; + +template +inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool operator!=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline void swap(set<_Key,_Compare,_Alloc>& __x, + set<_Key,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_slist.h b/darkice/tags/darkice-0_2/stl/stl_slist.h new file mode 100644 index 0000000..a748d1a --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_slist.h @@ -0,0 +1,1048 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_SLIST_H +#define __SGI_STL_INTERNAL_SLIST_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +struct _Slist_node_base +{ + _Slist_node_base* _M_next; +}; + +inline _Slist_node_base* +__slist_make_link(_Slist_node_base* __prev_node, + _Slist_node_base* __new_node) +{ + __new_node->_M_next = __prev_node->_M_next; + __prev_node->_M_next = __new_node; + return __new_node; +} + +inline _Slist_node_base* +__slist_previous(_Slist_node_base* __head, + const _Slist_node_base* __node) +{ + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; +} + +inline const _Slist_node_base* +__slist_previous(const _Slist_node_base* __head, + const _Slist_node_base* __node) +{ + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; +} + +inline void __slist_splice_after(_Slist_node_base* __pos, + _Slist_node_base* __before_first, + _Slist_node_base* __before_last) +{ + if (__pos != __before_first && __pos != __before_last) { + _Slist_node_base* __first = __before_first->_M_next; + _Slist_node_base* __after = __pos->_M_next; + __before_first->_M_next = __before_last->_M_next; + __pos->_M_next = __first; + __before_last->_M_next = __after; + } +} + +inline void +__slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head) +{ + _Slist_node_base* __before_last = __slist_previous(__head, 0); + if (__before_last != __head) { + _Slist_node_base* __after = __pos->_M_next; + __pos->_M_next = __head->_M_next; + __head->_M_next = 0; + __before_last->_M_next = __after; + } +} + +inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node) +{ + _Slist_node_base* __result = __node; + __node = __node->_M_next; + __result->_M_next = 0; + while(__node) { + _Slist_node_base* __next = __node->_M_next; + __node->_M_next = __result; + __result = __node; + __node = __next; + } + return __result; +} + +inline size_t __slist_size(_Slist_node_base* __node) +{ + size_t __result = 0; + for ( ; __node != 0; __node = __node->_M_next) + ++__result; + return __result; +} + +template +struct _Slist_node : public _Slist_node_base +{ + _Tp _M_data; +}; + +struct _Slist_iterator_base +{ + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef forward_iterator_tag iterator_category; + + _Slist_node_base* _M_node; + + _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {} + void _M_incr() { _M_node = _M_node->_M_next; } + + bool operator==(const _Slist_iterator_base& __x) const { + return _M_node == __x._M_node; + } + bool operator!=(const _Slist_iterator_base& __x) const { + return _M_node != __x._M_node; + } +}; + +template +struct _Slist_iterator : public _Slist_iterator_base +{ + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; + + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _Slist_node<_Tp> _Node; + + _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {} + _Slist_iterator() : _Slist_iterator_base(0) {} + _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {} + + reference operator*() const { return ((_Node*) _M_node)->_M_data; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() + { + _M_incr(); + return *this; + } + _Self operator++(int) + { + _Self __tmp = *this; + _M_incr(); + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +inline ptrdiff_t* distance_type(const _Slist_iterator_base&) { + return 0; +} + +inline forward_iterator_tag iterator_category(const _Slist_iterator_base&) { + return forward_iterator_tag(); +} + +template +inline _Tp* value_type(const _Slist_iterator<_Tp, _Ref, _Ptr>&) { + return 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template +class _Slist_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {} + +protected: + _Slist_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type + _M_node_allocator; + _Slist_node_base _M_head; +}; + +// Specialization for instanceless allocators. +template +class _Slist_alloc_base<_Tp,_Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _Slist_node_base _M_head; +}; + + +template +struct _Slist_base + : public _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Slist_base(const allocator_type& __a) + : _Base(__a) { this->_M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&this->_M_head, 0); } + +protected: + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +struct _Slist_base { + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_base(const allocator_type&) { _M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&_M_head, 0); } + +protected: + typedef simple_alloc<_Slist_node<_Tp>, _Alloc> _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); + +protected: + _Slist_node_base _M_head; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +_Slist_node_base* +_Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, + _Slist_node_base* __last_node) { + _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); + while (__cur != __last_node) { + _Slist_node<_Tp>* __tmp = __cur; + __cur = (_Slist_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; +} + +template +class slist : private _Slist_base<_Tp,_Alloc> +{ + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + +private: + typedef _Slist_base<_Tp,_Alloc> _Base; +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +private: + typedef _Slist_node<_Tp> _Node; + typedef _Slist_node_base _Node_base; + typedef _Slist_iterator_base _Iterator_base; + + _Node* _M_create_node(const value_type& __x) { + _Node* __node = this->_M_get_node(); + __STL_TRY { + construct(&__node->_M_data, __x); + __node->_M_next = 0; + } + __STL_UNWIND(this->_M_put_node(__node)); + return __node; + } + + _Node* _M_create_node() { + _Node* __node = this->_M_get_node(); + __STL_TRY { + construct(&__node->_M_data); + __node->_M_next = 0; + } + __STL_UNWIND(this->_M_put_node(__node)); + return __node; + } + +public: + explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + slist(size_type __n, const value_type& __x, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_fill(&this->_M_head, __n, __x); } + + explicit slist(size_type __n) : _Base(allocator_type()) + { _M_insert_after_fill(&this->_M_head, __n, value_type()); } + +#ifdef __STL_MEMBER_TEMPLATES + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&this->_M_head, __first, __last); } + +#else /* __STL_MEMBER_TEMPLATES */ + slist(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&this->_M_head, __first, __last); } + slist(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&this->_M_head, __first, __last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + slist(const slist& __x) : _Base(__x.get_allocator()) + { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); } + + slist& operator= (const slist& __x); + + ~slist() {} + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val) + { _M_fill_assign(__n, __val); } + + void _M_fill_assign(size_type __n, const _Tp& __val); + + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + + iterator begin() { return iterator((_Node*)this->_M_head._M_next); } + const_iterator begin() const + { return const_iterator((_Node*)this->_M_head._M_next);} + + iterator end() { return iterator(0); } + const_iterator end() const { return const_iterator(0); } + + // Experimental new feature: before_begin() returns a + // non-dereferenceable iterator that, when incremented, yields + // begin(). This iterator may be used as the argument to + // insert_after, erase_after, etc. Note that even for an empty + // slist, before_begin() is not the same iterator as end(). It + // is always necessary to increment before_begin() at least once to + // obtain end(). + iterator before_begin() { return iterator((_Node*) &this->_M_head); } + const_iterator before_begin() const + { return const_iterator((_Node*) &this->_M_head); } + + size_type size() const { return __slist_size(this->_M_head._M_next); } + + size_type max_size() const { return size_type(-1); } + + bool empty() const { return this->_M_head._M_next == 0; } + + void swap(slist& __x) + { __STD::swap(this->_M_head._M_next, __x._M_head._M_next); } + +public: + + reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; } + const_reference front() const + { return ((_Node*) this->_M_head._M_next)->_M_data; } + void push_front(const value_type& __x) { + __slist_make_link(&this->_M_head, _M_create_node(__x)); + } + void push_front() { __slist_make_link(&this->_M_head, _M_create_node()); } + void pop_front() { + _Node* __node = (_Node*) this->_M_head._M_next; + this->_M_head._M_next = __node->_M_next; + destroy(&__node->_M_data); + this->_M_put_node(__node); + } + + iterator previous(const_iterator __pos) { + return iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node)); + } + const_iterator previous(const_iterator __pos) const { + return const_iterator((_Node*) __slist_previous(&this->_M_head, + __pos._M_node)); + } + +private: + _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) { + return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); + } + + _Node* _M_insert_after(_Node_base* __pos) { + return (_Node*) (__slist_make_link(__pos, _M_create_node())); + } + + void _M_insert_after_fill(_Node_base* __pos, + size_type __n, const value_type& __x) { + for (size_type __i = 0; __i < __n; ++__i) + __pos = __slist_make_link(__pos, _M_create_node(__x)); + } + +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last) { + typedef typename _Is_integer<_InIter>::_Integral _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) { + _M_insert_after_fill(__pos, __n, __x); + } + + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last, + __false_type) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void _M_insert_after_range(_Node_base* __pos, + const_iterator __first, const_iterator __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + void _M_insert_after_range(_Node_base* __pos, + const value_type* __first, + const value_type* __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + + iterator insert_after(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__pos._M_node, __x)); + } + + iterator insert_after(iterator __pos) { + return insert_after(__pos, value_type()); + } + + void insert_after(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__pos._M_node, __n, __x); + } + +#ifdef __STL_MEMBER_TEMPLATES + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert_after(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert_after(iterator __pos, + const_iterator __first, const_iterator __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + void insert_after(iterator __pos, + const value_type* __first, const value_type* __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator insert(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + __x)); + } + + iterator insert(iterator __pos) { + return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + value_type())); + } + + void insert(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node), + __n, __x); + } + +#ifdef __STL_MEMBER_TEMPLATES + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), + __first, __last); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert(iterator __pos, const_iterator __first, const_iterator __last) { + _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), + __first, __last); + } + void insert(iterator __pos, const value_type* __first, + const value_type* __last) { + _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), + __first, __last); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + +public: + iterator erase_after(iterator __pos) { + return iterator((_Node*) this->_M_erase_after(__pos._M_node)); + } + iterator erase_after(iterator __before_first, iterator __last) { + return iterator((_Node*) this->_M_erase_after(__before_first._M_node, + __last._M_node)); + } + + iterator erase(iterator __pos) { + return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head, + __pos._M_node)); + } + iterator erase(iterator __first, iterator __last) { + return (_Node*) this->_M_erase_after( + __slist_previous(&this->_M_head, __first._M_node), __last._M_node); + } + + void resize(size_type new_size, const _Tp& __x); + void resize(size_type new_size) { resize(new_size, _Tp()); } + void clear() { this->_M_erase_after(&this->_M_head, 0); } + +public: + // Moves the range [__before_first + 1, __before_last + 1) to *this, + // inserting it immediately after __pos. This is constant time. + void splice_after(iterator __pos, + iterator __before_first, iterator __before_last) + { + if (__before_first != __before_last) + __slist_splice_after(__pos._M_node, __before_first._M_node, + __before_last._M_node); + } + + // Moves the element that follows __prev to *this, inserting it immediately + // after __pos. This is constant time. + void splice_after(iterator __pos, iterator __prev) + { + __slist_splice_after(__pos._M_node, + __prev._M_node, __prev._M_node->_M_next); + } + + + // Removes all of the elements from the list __x to *this, inserting + // them immediately after __pos. __x must not be *this. Complexity: + // linear in __x.size(). + void splice_after(iterator __pos, slist& __x) + { + __slist_splice_after(__pos._M_node, &__x._M_head); + } + + // Linear in distance(begin(), __pos), and linear in __x.size(). + void splice(iterator __pos, slist& __x) { + if (__x._M_head._M_next) + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + &__x._M_head, __slist_previous(&__x._M_head, 0)); + } + + // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). + void splice(iterator __pos, slist& __x, iterator __i) { + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __i._M_node), + __i._M_node); + } + + // Linear in distance(begin(), __pos), in distance(__x.begin(), __first), + // and in distance(__first, __last). + void splice(iterator __pos, slist& __x, iterator __first, iterator __last) + { + if (__first != __last) + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __first._M_node), + __slist_previous(__first._M_node, __last._M_node)); + } + +public: + void reverse() { + if (this->_M_head._M_next) + this->_M_head._M_next = __slist_reverse(this->_M_head._M_next); + } + + void remove(const _Tp& __val); + void unique(); + void merge(slist& __x); + void sort(); + +#ifdef __STL_MEMBER_TEMPLATES + template + void remove_if(_Predicate __pred); + + template + void unique(_BinaryPredicate __pred); + + template + void merge(slist&, _StrictWeakOrdering); + + template + void sort(_StrictWeakOrdering __comp); +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template +slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) +{ + if (&__x != this) { + _Node_base* __p1 = &this->_M_head; + _Node* __n1 = (_Node*) this->_M_head._M_next; + const _Node* __n2 = (const _Node*) __x._M_head._M_next; + while (__n1 && __n2) { + __n1->_M_data = __n2->_M_data; + __p1 = __n1; + __n1 = (_Node*) __n1->_M_next; + __n2 = (const _Node*) __n2->_M_next; + } + if (__n2 == 0) + this->_M_erase_after(__p1, 0); + else + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); + } + return *this; +} + +template +void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_M_head._M_next; + for ( ; __node != 0 && __n > 0 ; --__n) { + __node->_M_data = __val; + __prev = __node; + __node = (_Node*) __node->_M_next; + } + if (__n > 0) + _M_insert_after_fill(__prev, __n, __val); + else + this->_M_erase_after(__prev, 0); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last, + __false_type) +{ + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_M_head._M_next; + while (__node != 0 && __first != __last) { + __node->_M_data = *__first; + __prev = __node; + __node = (_Node*) __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + this->_M_erase_after(__prev, 0); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +inline bool +operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) +{ + typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = _SL1.end(); + const_iterator __end2 = _SL2.end(); + + const_iterator __i1 = _SL1.begin(); + const_iterator __i2 = _SL2.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; +} + + +template +inline bool +operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) +{ + return lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL1 == _SL2); +} + +template +inline bool +operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return _SL2 < _SL1; +} + +template +inline bool +operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL2 < _SL1); +} + +template +inline bool +operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL1 < _SL2); +} + +template +inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template +void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) +{ + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next != 0 && __len > 0) { + --__len; + __cur = __cur->_M_next; + } + if (__cur->_M_next) + this->_M_erase_after(__cur, 0); + else + _M_insert_after_fill(__cur, __len, __x); +} + +template +void slist<_Tp,_Alloc>::remove(const _Tp& __val) +{ + _Node_base* __cur = &this->_M_head; + while (__cur && __cur->_M_next) { + if (((_Node*) __cur->_M_next)->_M_data == __val) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template +void slist<_Tp,_Alloc>::unique() +{ + _Node_base* __cur = this->_M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (((_Node*)__cur)->_M_data == + ((_Node*)(__cur->_M_next))->_M_data) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } +} + +template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) +{ + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (((_Node*) __x._M_head._M_next)->_M_data < + ((_Node*) __n1->_M_next)->_M_data) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template +void slist<_Tp,_Alloc>::sort() +{ + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) +{ + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next) { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template template +void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred) +{ + _Node* __cur = (_Node*) this->_M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + this->_M_erase_after(__cur); + else + __cur = (_Node*) __cur->_M_next; + } + } +} + +template template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, + _StrictWeakOrdering __comp) +{ + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (__comp(((_Node*) __x._M_head._M_next)->_M_data, + ((_Node*) __n1->_M_next)->_M_data)) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template template +void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) +{ + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +// Specialization of insert_iterator so that insertions will be constant +// time rather than linear time. + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +class insert_iterator > { +protected: + typedef slist<_Tp, _Alloc> _Container; + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x) { + if (__i == __x.begin()) + iter = __x.before_begin(); + else + iter = __x.previous(__i); + } + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + iter = container->insert_after(iter, __value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_stack.h b/darkice/tags/darkice-0_2/stl/stl_stack.h new file mode 100644 index 0000000..0693e57 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_stack.h @@ -0,0 +1,143 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_STACK_H +#define __SGI_STL_INTERNAL_STACK_H + +#include + +__STL_BEGIN_NAMESPACE + +// Forward declarations of operators == and <, needed for friend declaration. + +template ) > +class stack; + +template +bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + +template +bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + + +template +class stack { + + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence); + typedef typename _Sequence::value_type _Sequence_value_type; + __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type); + + +#ifdef __STL_MEMBER_TEMPLATES + template + friend bool operator== (const stack<_Tp1, _Seq1>&, + const stack<_Tp1, _Seq1>&); + template + friend bool operator< (const stack<_Tp1, _Seq1>&, + const stack<_Tp1, _Seq1>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); + friend bool __STD_QUALIFIER + operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; +protected: + _Sequence c; +public: + stack() : c() {} + explicit stack(const _Sequence& __s) : c(__s) {} + + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + reference top() { return c.back(); } + const_reference top() const { return c.back(); } + void push(const value_type& __x) { c.push_back(__x); } + void pop() { c.pop_back(); } +}; + +template +bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x.c == __y.c; +} + +template +bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x.c < __y.c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x == __y); +} + +template +bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __y < __x; +} + +template +bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__y < __x); +} + +template +bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_string_fwd.h b/darkice/tags/darkice-0_2/stl/stl_string_fwd.h new file mode 100644 index 0000000..8e59de7 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_string_fwd.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_STRING_FWD_H +#define __SGI_STL_STRING_FWD_H + +#include +#include +#include +#include + +__STL_BEGIN_NAMESPACE + +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_CharT) > +class basic_string; + +typedef basic_string string; +typedef basic_string wstring; + +static const char* __get_c_string(const string&); + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_STRING_FWD_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_tempbuf.h b/darkice/tags/darkice-0_2/stl/stl_tempbuf.h new file mode 100644 index 0000000..0fc68d6 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_tempbuf.h @@ -0,0 +1,162 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_TEMPBUF_H +#define __SGI_STL_INTERNAL_TEMPBUF_H + + +__STL_BEGIN_NAMESPACE + +template +pair<_Tp*, ptrdiff_t> +__get_temporary_buffer(ptrdiff_t __len, _Tp*) +{ + if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) + __len = INT_MAX / sizeof(_Tp); + + while (__len > 0) { + _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; + } + + return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); +} + +#ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS + +template +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +#endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ + +// This overload is not required by the standard; it is an extension. +// It is supported for backward compatibility with the HP STL, and +// because not all compilers support the language feature (explicit +// function template arguments) that is required for the standard +// version of get_temporary_buffer. +template +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +template +void return_temporary_buffer(_Tp* __p) { + free(__p); +} + +template +class _Temporary_buffer { +private: + ptrdiff_t _M_original_len; + ptrdiff_t _M_len; + _Tp* _M_buffer; + + void _M_allocate_buffer() { + _M_original_len = _M_len; + _M_buffer = 0; + + if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp))) + _M_len = INT_MAX / sizeof(_Tp); + + while (_M_len > 0) { + _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp)); + if (_M_buffer) + break; + _M_len /= 2; + } + } + + void _M_initialize_buffer(const _Tp&, __true_type) {} + void _M_initialize_buffer(const _Tp& val, __false_type) { + uninitialized_fill_n(_M_buffer, _M_len, val); + } + +public: + ptrdiff_t size() const { return _M_len; } + ptrdiff_t requested_size() const { return _M_original_len; } + _Tp* begin() { return _M_buffer; } + _Tp* end() { return _M_buffer + _M_len; } + + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) { + // Workaround for a __type_traits bug in the pre-7.3 compiler. +# if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION < 730 + typedef typename __type_traits<_Tp>::is_POD_type _Trivial; +# else + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; +# endif + + __STL_TRY { + _M_len = 0; + distance(__first, __last, _M_len); + _M_allocate_buffer(); + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); + } + __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0); + } + + ~_Temporary_buffer() { + destroy(_M_buffer, _M_buffer + _M_len); + free(_M_buffer); + } + +private: + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&) {} + void operator=(const _Temporary_buffer&) {} +}; + +// Class temporary_buffer is not part of the standard. It is an extension. + +template ::value_type +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + > +struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> +{ + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {} + ~temporary_buffer() {} +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_threads.h b/darkice/tags/darkice-0_2/stl/stl_threads.h new file mode 100644 index 0000000..4b0a643 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_threads.h @@ -0,0 +1,374 @@ +/* + * Copyright (c) 1997-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +// WARNING: This is an internal header file, included by other C++ +// standard library headers. You should not attempt to use this header +// file directly. +// Stl_config.h should be included before this file. + +#ifndef __SGI_STL_INTERNAL_THREADS_H +#define __SGI_STL_INTERNAL_THREADS_H + +// Supported threading models are native SGI, pthreads, uithreads +// (similar to pthreads, but based on an earlier draft of the Posix +// threads standard), and Win32 threads. Uithread support by Jochen +// Schlick, 1999. + +#if defined(__STL_SGI_THREADS) +#include +#include +#elif defined(__STL_PTHREADS) +#include +#elif defined(__STL_UITHREADS) +#include +#include +#elif defined(__STL_WIN32THREADS) +#include +#endif + +__STL_BEGIN_NAMESPACE + + +// Class _Refcount_Base provides a type, _RC_t, a data member, +// _M_ref_count, and member functions _M_incr and _M_decr, which perform +// atomic preincrement/predecrement. The constructor initializes +// _M_ref_count. + +// Hack for SGI o32 compilers. +#if defined(__STL_SGI_THREADS) && !defined(__add_and_fetch) && \ + (__mips < 3 || !(defined (_ABIN32) || defined(_ABI64))) +# define __add_and_fetch(__l,__v) add_then_test((unsigned long*)__l,__v) +# define __test_and_set(__l,__v) test_and_set(__l,__v) +#endif /* o32 */ + +struct _Refcount_Base +{ + // The type _RC_t +# ifdef __STL_WIN32THREADS + typedef long _RC_t; +# else + typedef size_t _RC_t; +#endif + + // The data member _M_ref_count + volatile _RC_t _M_ref_count; + + // Constructor +# ifdef __STL_PTHREADS + pthread_mutex_t _M_ref_count_lock; + _Refcount_Base(_RC_t __n) : _M_ref_count(__n) + { pthread_mutex_init(&_M_ref_count_lock, 0); } +# elif defined(__STL_UITHREADS) + mutex_t _M_ref_count_lock; + _Refcount_Base(_RC_t __n) : _M_ref_count(__n) + { mutex_init(&_M_ref_count_lock, USYNC_THREAD, 0); } +# else + _Refcount_Base(_RC_t __n) : _M_ref_count(__n) {} +# endif + + // _M_incr and _M_decr +# ifdef __STL_SGI_THREADS + void _M_incr() { __add_and_fetch(&_M_ref_count, 1); } + _RC_t _M_decr() { return __add_and_fetch(&_M_ref_count, (size_t) -1); } +# elif defined (__STL_WIN32THREADS) + void _M_incr() { InterlockedIncrement((_RC_t*)&_M_ref_count); } + _RC_t _M_decr() { return InterlockedDecrement((_RC_t*)&_M_ref_count); } +# elif defined(__STL_PTHREADS) + void _M_incr() { + pthread_mutex_lock(&_M_ref_count_lock); + ++_M_ref_count; + pthread_mutex_unlock(&_M_ref_count_lock); + } + _RC_t _M_decr() { + pthread_mutex_lock(&_M_ref_count_lock); + volatile _RC_t __tmp = --_M_ref_count; + pthread_mutex_unlock(&_M_ref_count_lock); + return __tmp; + } +# elif defined(__STL_UITHREADS) + void _M_incr() { + mutex_lock(&_M_ref_count_lock); + ++_M_ref_count; + mutex_unlock(&_M_ref_count_lock); + } + _RC_t _M_decr() { + mutex_lock(&_M_ref_count_lock); + /*volatile*/ _RC_t __tmp = --_M_ref_count; + mutex_unlock(&_M_ref_count_lock); + return __tmp; + } +# else /* No threads */ + void _M_incr() { ++_M_ref_count; } + _RC_t _M_decr() { return --_M_ref_count; } +# endif +}; + +// Atomic swap on unsigned long +// This is guaranteed to behave as though it were atomic only if all +// possibly concurrent updates use _Atomic_swap. +// In some cases the operation is emulated with a lock. +# ifdef __STL_SGI_THREADS + inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { +# if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) + return test_and_set(__p, __q); +# else + return __test_and_set(__p, (unsigned long)__q); +# endif + } +# elif defined(__STL_WIN32THREADS) + inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { + return (unsigned long) InterlockedExchange((LPLONG)__p, (LONG)__q); + } +# elif defined(__STL_PTHREADS) + // We use a template here only to get a unique initialized instance. + template + struct _Swap_lock_struct { + static pthread_mutex_t _S_swap_lock; + }; + + template + pthread_mutex_t + _Swap_lock_struct<__dummy>::_S_swap_lock = PTHREAD_MUTEX_INITIALIZER; + + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { + pthread_mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock); + unsigned long __result = *__p; + *__p = __q; + pthread_mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock); + return __result; + } +# elif defined(__STL_UITHREADS) + // We use a template here only to get a unique initialized instance. + template + struct _Swap_lock_struct { + static mutex_t _S_swap_lock; + }; + + template + mutex_t + _Swap_lock_struct<__dummy>::_S_swap_lock = DEFAULTMUTEX; + + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { + mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock); + unsigned long __result = *__p; + *__p = __q; + mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock); + return __result; + } +# elif defined (__STL_SOLARIS_THREADS) + // any better solutions ? + // We use a template here only to get a unique initialized instance. + template + struct _Swap_lock_struct { + static mutex_t _S_swap_lock; + }; + +# if ( __STL_STATIC_TEMPLATE_DATA > 0 ) + template + mutex_t + _Swap_lock_struct<__dummy>::_S_swap_lock = DEFAULTMUTEX; +# else + __DECLARE_INSTANCE(mutex_t, _Swap_lock_struct<__dummy>::_S_swap_lock, + =DEFAULTMUTEX); +# endif /* ( __STL_STATIC_TEMPLATE_DATA > 0 ) */ + + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { + mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock); + unsigned long __result = *__p; + *__p = __q; + mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock); + return __result; + } +# else + static inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { + unsigned long __result = *__p; + *__p = __q; + return __result; + } +# endif + +// Locking class. Note that this class *does not have a constructor*. +// It must be initialized either statically, with __STL_MUTEX_INITIALIZER, +// or dynamically, by explicitly calling the _M_initialize member function. +// (This is similar to the ways that a pthreads mutex can be initialized.) +// There are explicit member functions for acquiring and releasing the lock. + +// There is no constructor because static initialization is essential for +// some uses, and only a class aggregate (see section 8.5.1 of the C++ +// standard) can be initialized that way. That means we must have no +// constructors, no base classes, no virtual functions, and no private or +// protected members. + +// Helper struct. This is a workaround for various compilers that don't +// handle static variables in inline functions properly. +template +struct _STL_mutex_spin { + enum { __low_max = 30, __high_max = 1000 }; + // Low if we suspect uniprocessor, high for multiprocessor. + + static unsigned __max; + static unsigned __last; +}; + +template +unsigned _STL_mutex_spin<__inst>::__max = _STL_mutex_spin<__inst>::__low_max; + +template +unsigned _STL_mutex_spin<__inst>::__last = 0; + +struct _STL_mutex_lock +{ +#if defined(__STL_SGI_THREADS) || defined(__STL_WIN32THREADS) + // It should be relatively easy to get this to work on any modern Unix. + volatile unsigned long _M_lock; + void _M_initialize() { _M_lock = 0; } + static void _S_nsec_sleep(int __log_nsec) { +# ifdef __STL_SGI_THREADS + struct timespec __ts; + /* Max sleep is 2**27nsec ~ 60msec */ + __ts.tv_sec = 0; + __ts.tv_nsec = 1 << __log_nsec; + nanosleep(&__ts, 0); +# elif defined(__STL_WIN32THREADS) + if (__log_nsec <= 20) { + Sleep(0); + } else { + Sleep(1 << (__log_nsec - 20)); + } +# else +# error unimplemented +# endif + } + void _M_acquire_lock() { + volatile unsigned long* __lock = &this->_M_lock; + + if (!_Atomic_swap((unsigned long*)__lock, 1)) { + return; + } + unsigned __my_spin_max = _STL_mutex_spin<0>::__max; + unsigned __my_last_spins = _STL_mutex_spin<0>::__last; + volatile unsigned __junk = 17; // Value doesn't matter. + unsigned __i; + for (__i = 0; __i < __my_spin_max; __i++) { + if (__i < __my_last_spins/2 || *__lock) { + __junk *= __junk; __junk *= __junk; + __junk *= __junk; __junk *= __junk; + continue; + } + if (!_Atomic_swap((unsigned long*)__lock, 1)) { + // got it! + // Spinning worked. Thus we're probably not being scheduled + // against the other process with which we were contending. + // Thus it makes sense to spin longer the next time. + _STL_mutex_spin<0>::__last = __i; + _STL_mutex_spin<0>::__max = _STL_mutex_spin<0>::__high_max; + return; + } + } + // We are probably being scheduled against the other process. Sleep. + _STL_mutex_spin<0>::__max = _STL_mutex_spin<0>::__low_max; + for (__i = 0 ;; ++__i) { + int __log_nsec = __i + 6; + + if (__log_nsec > 27) __log_nsec = 27; + if (!_Atomic_swap((unsigned long *)__lock, 1)) { + return; + } + _S_nsec_sleep(__log_nsec); + } + } + void _M_release_lock() { + volatile unsigned long* __lock = &_M_lock; +# if defined(__STL_SGI_THREADS) && defined(__GNUC__) && __mips >= 3 + asm("sync"); + *__lock = 0; +# elif defined(__STL_SGI_THREADS) && __mips >= 3 \ + && (defined (_ABIN32) || defined(_ABI64)) + __lock_release(__lock); +# else + *__lock = 0; + // This is not sufficient on many multiprocessors, since + // writes to protected variables and the lock may be reordered. +# endif + } + +// We no longer use win32 critical sections. +// They appear to be slower in the contention-free case, +// and they appear difficult to initialize without introducing a race. + +#elif defined(__STL_PTHREADS) + pthread_mutex_t _M_lock; + void _M_initialize() { pthread_mutex_init(&_M_lock, NULL); } + void _M_acquire_lock() { pthread_mutex_lock(&_M_lock); } + void _M_release_lock() { pthread_mutex_unlock(&_M_lock); } +#elif defined(__STL_UITHREADS) + mutex_t _M_lock; + void _M_initialize() { mutex_init(&_M_lock, USYNC_THREAD, 0); } + void _M_acquire_lock() { mutex_lock(&_M_lock); } + void _M_release_lock() { mutex_unlock(&_M_lock); } +#else /* No threads */ + void _M_initialize() {} + void _M_acquire_lock() {} + void _M_release_lock() {} +#endif +}; + +#ifdef __STL_PTHREADS +// Pthreads locks must be statically initialized to something other than +// the default value of zero. +# define __STL_MUTEX_INITIALIZER = { PTHREAD_MUTEX_INITIALIZER } +#elif defined(__STL_UITHREADS) +// UIthreads locks must be statically initialized to something other than +// the default value of zero. +# define __STL_MUTEX_INITIALIZER = { DEFAULTMUTEX } +#elif defined(__STL_SGI_THREADS) || defined(__STL_WIN32THREADS) +# define __STL_MUTEX_INITIALIZER = { 0 } +#else +# define __STL_MUTEX_INITIALIZER +#endif + + +// A locking class that uses _STL_mutex_lock. The constructor takes a +// reference to an _STL_mutex_lock, and acquires a lock. The +// destructor releases the lock. It's not clear that this is exactly +// the right functionality. It will probably change in the future. + +struct _STL_auto_lock +{ + _STL_mutex_lock& _M_lock; + + _STL_auto_lock(_STL_mutex_lock& __lock) : _M_lock(__lock) + { _M_lock._M_acquire_lock(); } + ~_STL_auto_lock() { _M_lock._M_release_lock(); } + +private: + void operator=(const _STL_auto_lock&); + _STL_auto_lock(const _STL_auto_lock&); +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_THREADS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_tree.h b/darkice/tags/darkice-0_2/stl/stl_tree.h new file mode 100644 index 0000000..1049ba3 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_tree.h @@ -0,0 +1,1366 @@ +/* + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_TREE_H +#define __SGI_STL_INTERNAL_TREE_H + +/* + +Red-black tree class, designed for use in implementing STL +associative containers (set, multiset, map, and multimap). The +insertion and deletion algorithms are based on those in Cormen, +Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990), +except that + +(1) the header cell is maintained with links not only to the root +but also to the leftmost node of the tree, to enable constant time +begin(), and to the rightmost node of the tree, to enable linear time +performance when used with the generic set algorithms (set_union, +etc.); + +(2) when a node being deleted has two children its successor node is +relinked into its place, rather than copied, so that the only +iterators invalidated are those referring to the deleted node. + +*/ + +#include +#include +#include +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1375 +#endif + +typedef bool _Rb_tree_Color_type; +const _Rb_tree_Color_type _S_rb_tree_red = false; +const _Rb_tree_Color_type _S_rb_tree_black = true; + +struct _Rb_tree_node_base +{ + typedef _Rb_tree_Color_type _Color_type; + typedef _Rb_tree_node_base* _Base_ptr; + + _Color_type _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr _S_minimum(_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr _S_maximum(_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } +}; + +template +struct _Rb_tree_node : public _Rb_tree_node_base +{ + typedef _Rb_tree_node<_Value>* _Link_type; + _Value _M_value_field; +}; + + +struct _Rb_tree_base_iterator +{ + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + _Base_ptr _M_node; + + void _M_increment() + { + if (_M_node->_M_right != 0) { + _M_node = _M_node->_M_right; + while (_M_node->_M_left != 0) + _M_node = _M_node->_M_left; + } + else { + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_right) { + _M_node = __y; + __y = __y->_M_parent; + } + if (_M_node->_M_right != __y) + _M_node = __y; + } + } + + void _M_decrement() + { + if (_M_node->_M_color == _S_rb_tree_red && + _M_node->_M_parent->_M_parent == _M_node) + _M_node = _M_node->_M_right; + else if (_M_node->_M_left != 0) { + _Base_ptr __y = _M_node->_M_left; + while (__y->_M_right != 0) + __y = __y->_M_right; + _M_node = __y; + } + else { + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_left) { + _M_node = __y; + __y = __y->_M_parent; + } + _M_node = __y; + } + } +}; + +template +struct _Rb_tree_iterator : public _Rb_tree_base_iterator +{ + typedef _Value value_type; + typedef _Ref reference; + typedef _Ptr pointer; + typedef _Rb_tree_iterator<_Value, _Value&, _Value*> + iterator; + typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*> + const_iterator; + typedef _Rb_tree_iterator<_Value, _Ref, _Ptr> + _Self; + typedef _Rb_tree_node<_Value>* _Link_type; + + _Rb_tree_iterator() {} + _Rb_tree_iterator(_Link_type __x) { _M_node = __x; } + _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; } + + reference operator*() const { return _Link_type(_M_node)->_M_value_field; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() { _M_increment(); return *this; } + _Self operator++(int) { + _Self __tmp = *this; + _M_increment(); + return __tmp; + } + + _Self& operator--() { _M_decrement(); return *this; } + _Self operator--(int) { + _Self __tmp = *this; + _M_decrement(); + return __tmp; + } +}; + +inline bool operator==(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node == __y._M_node; +} + +inline bool operator!=(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node != __y._M_node; +} + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +inline bidirectional_iterator_tag +iterator_category(const _Rb_tree_base_iterator&) { + return bidirectional_iterator_tag(); +} + +inline _Rb_tree_base_iterator::difference_type* +distance_type(const _Rb_tree_base_iterator&) { + return (_Rb_tree_base_iterator::difference_type*) 0; +} + +template +inline _Value* value_type(const _Rb_tree_iterator<_Value, _Ref, _Ptr>&) { + return (_Value*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +inline void +_Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) +{ + _Rb_tree_node_base* __y = __x->_M_right; + __x->_M_right = __y->_M_left; + if (__y->_M_left !=0) + __y->_M_left->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_left) + __x->_M_parent->_M_left = __y; + else + __x->_M_parent->_M_right = __y; + __y->_M_left = __x; + __x->_M_parent = __y; +} + +inline void +_Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) +{ + _Rb_tree_node_base* __y = __x->_M_left; + __x->_M_left = __y->_M_right; + if (__y->_M_right != 0) + __y->_M_right->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_right) + __x->_M_parent->_M_right = __y; + else + __x->_M_parent->_M_left = __y; + __y->_M_right = __x; + __x->_M_parent = __y; +} + +inline void +_Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) +{ + __x->_M_color = _S_rb_tree_red; + while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) { + if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) { + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; + } + else { + if (__x == __x->_M_parent->_M_right) { + __x = __x->_M_parent; + _Rb_tree_rotate_left(__x, __root); + } + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root); + } + } + else { + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; + } + else { + if (__x == __x->_M_parent->_M_left) { + __x = __x->_M_parent; + _Rb_tree_rotate_right(__x, __root); + } + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); + } + } + } + __root->_M_color = _S_rb_tree_black; +} + +inline _Rb_tree_node_base* +_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z, + _Rb_tree_node_base*& __root, + _Rb_tree_node_base*& __leftmost, + _Rb_tree_node_base*& __rightmost) +{ + _Rb_tree_node_base* __y = __z; + _Rb_tree_node_base* __x = 0; + _Rb_tree_node_base* __x_parent = 0; + if (__y->_M_left == 0) // __z has at most one non-null child. y == z. + __x = __y->_M_right; // __x might be null. + else + if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. + __x = __y->_M_left; // __x is not null. + else { // __z has two non-null children. Set __y to + __y = __y->_M_right; // __z's successor. __x might be null. + while (__y->_M_left != 0) + __y = __y->_M_left; + __x = __y->_M_right; + } + if (__y != __z) { // relink y in place of z. y is z's successor + __z->_M_left->_M_parent = __y; + __y->_M_left = __z->_M_left; + if (__y != __z->_M_right) { + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + __y->_M_parent->_M_left = __x; // __y must be a child of _M_left + __y->_M_right = __z->_M_right; + __z->_M_right->_M_parent = __y; + } + else + __x_parent = __y; + if (__root == __z) + __root = __y; + else if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __y; + else + __z->_M_parent->_M_right = __y; + __y->_M_parent = __z->_M_parent; + __STD::swap(__y->_M_color, __z->_M_color); + __y = __z; + // __y now points to node to be actually deleted + } + else { // __y == __z + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + if (__root == __z) + __root = __x; + else + if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __x; + else + __z->_M_parent->_M_right = __x; + if (__leftmost == __z) + if (__z->_M_right == 0) // __z->_M_left must be null also + __leftmost = __z->_M_parent; + // makes __leftmost == _M_header if __z == __root + else + __leftmost = _Rb_tree_node_base::_S_minimum(__x); + if (__rightmost == __z) + if (__z->_M_left == 0) // __z->_M_right must be null also + __rightmost = __z->_M_parent; + // makes __rightmost == _M_header if __z == __root + else // __x == __z->_M_left + __rightmost = _Rb_tree_node_base::_S_maximum(__x); + } + if (__y->_M_color != _S_rb_tree_red) { + while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black)) + if (__x == __x_parent->_M_left) { + _Rb_tree_node_base* __w = __x_parent->_M_right; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x_parent, __root); + __w = __x_parent->_M_right; + } + if ((__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) && + (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; + } else { + if (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) { + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__w, __root); + __w = __x_parent->_M_right; + } + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_left(__x_parent, __root); + break; + } + } else { // same as above, with _M_right <-> _M_left. + _Rb_tree_node_base* __w = __x_parent->_M_left; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x_parent, __root); + __w = __x_parent->_M_left; + } + if ((__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) && + (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; + } else { + if (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) { + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__w, __root); + __w = __x_parent->_M_left; + } + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_right(__x_parent, __root); + break; + } + } + if (__x) __x->_M_color = _S_rb_tree_black; + } + return __y; +} + +// Base class to encapsulate the differences between old SGI-style +// allocators and standard-conforming allocators. In order to avoid +// having an empty base class, we arbitrarily move one of rb_tree's +// data members into the base class. + +#ifdef __STL_USE_STD_ALLOCATORS + +// _Base for general standard-conforming allocators. +template +class _Rb_tree_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Rb_tree_alloc_base(const allocator_type& __a) + : _M_node_allocator(__a), _M_header(0) {} + +protected: + typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type + _M_node_allocator; + _Rb_tree_node<_Tp>* _M_header; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } +}; + +// Specialization for instanceless allocators. +template +class _Rb_tree_alloc_base<_Tp, _Alloc, true> { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type + _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +template +struct _Rb_tree_base + : public _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Rb_tree_base(const allocator_type& __a) + : _Base(__a) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +struct _Rb_tree_base +{ + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_base(const allocator_type&) + : _M_header(0) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef simple_alloc<_Rb_tree_node<_Tp>, _Alloc> _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> { + typedef _Rb_tree_base<_Value, _Alloc> _Base; +protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef _Rb_tree_node<_Value> _Rb_tree_node; + typedef _Rb_tree_Color_type _Color_type; +public: + typedef _Key key_type; + typedef _Value value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node* _Link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_header; +#endif /* __STL_USE_NAMESPACES */ + +protected: + + _Link_type _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); + __STL_TRY { + construct(&__tmp->_M_value_field, __x); + } + __STL_UNWIND(_M_put_node(__tmp)); + return __tmp; + } + + _Link_type _M_clone_node(_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; + } + + void destroy_node(_Link_type __p) + { + destroy(&__p->_M_value_field); + _M_put_node(__p); + } + +protected: + size_type _M_node_count; // keeps track of size of tree + _Compare _M_key_compare; + + _Link_type& _M_root() const + { return (_Link_type&) _M_header->_M_parent; } + _Link_type& _M_leftmost() const + { return (_Link_type&) _M_header->_M_left; } + _Link_type& _M_rightmost() const + { return (_Link_type&) _M_header->_M_right; } + + static _Link_type& _S_left(_Link_type __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Link_type __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Link_type __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Link_type __x) + { return __x->_M_value_field; } + static const _Key& _S_key(_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + static _Color_type& _S_color(_Link_type __x) + { return (_Color_type&)(__x->_M_color); } + + static _Link_type& _S_left(_Base_ptr __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Base_ptr __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Base_ptr __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Base_ptr __x) + { return ((_Link_type)__x)->_M_value_field; } + static const _Key& _S_key(_Base_ptr __x) + { return _KeyOfValue()(_S_value(_Link_type(__x)));} + static _Color_type& _S_color(_Base_ptr __x) + { return (_Color_type&)(_Link_type(__x)->_M_color); } + + static _Link_type _S_minimum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } + + static _Link_type _S_maximum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } + +public: + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_iterator + const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator + reverse_iterator; + typedef reverse_bidirectional_iterator + const_reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +private: + iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + _Link_type _M_copy(_Link_type __x, _Link_type __p); + void _M_erase(_Link_type __x); + +public: + // allocation/deallocation + _Rb_tree() + : _Base(allocator_type()), _M_node_count(0), _M_key_compare() + { _M_empty_initialize(); } + + _Rb_tree(const _Compare& __comp) + : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } + + _Rb_tree(const _Compare& __comp, const allocator_type& __a) + : _Base(__a), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } + + _Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) + : _Base(__x.get_allocator()), + _M_node_count(0), _M_key_compare(__x._M_key_compare) + { + if (__x._M_root() == 0) + _M_empty_initialize(); + else { + _S_color(_M_header) = _S_rb_tree_red; + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + } + _M_node_count = __x._M_node_count; + } + ~_Rb_tree() { clear(); } + _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& + operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x); + +private: + void _M_empty_initialize() { + _S_color(_M_header) = _S_rb_tree_red; // used to distinguish header from + // __root, in iterator.operator++ + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; + } + +public: + // accessors: + _Compare key_comp() const { return _M_key_compare; } + iterator begin() { return _M_leftmost(); } + const_iterator begin() const { return _M_leftmost(); } + iterator end() { return _M_header; } + const_iterator end() const { return _M_header; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + bool empty() const { return _M_node_count == 0; } + size_type size() const { return _M_node_count; } + size_type max_size() const { return size_type(-1); } + + void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __t) { + __STD::swap(_M_header, __t._M_header); + __STD::swap(_M_node_count, __t._M_node_count); + __STD::swap(_M_key_compare, __t._M_key_compare); + } + +public: + // insert/erase + pair insert_unique(const value_type& __x); + iterator insert_equal(const value_type& __x); + + iterator insert_unique(iterator __position, const value_type& __x); + iterator insert_equal(iterator __position, const value_type& __x); + +#ifdef __STL_MEMBER_TEMPLATES + template + void insert_unique(_InputIterator __first, _InputIterator __last); + template + void insert_equal(_InputIterator __first, _InputIterator __last); +#else /* __STL_MEMBER_TEMPLATES */ + void insert_unique(const_iterator __first, const_iterator __last); + void insert_unique(const value_type* __first, const value_type* __last); + void insert_equal(const_iterator __first, const_iterator __last); + void insert_equal(const value_type* __first, const value_type* __last); +#endif /* __STL_MEMBER_TEMPLATES */ + + void erase(iterator __position); + size_type erase(const key_type& __x); + void erase(iterator __first, iterator __last); + void erase(const key_type* __first, const key_type* __last); + void clear() { + if (_M_node_count != 0) { + _M_erase(_M_root()); + _M_leftmost() = _M_header; + _M_root() = 0; + _M_rightmost() = _M_header; + _M_node_count = 0; + } + } + +public: + // set operations: + iterator find(const key_type& __x); + const_iterator find(const key_type& __x) const; + size_type count(const key_type& __x) const; + iterator lower_bound(const key_type& __x); + const_iterator lower_bound(const key_type& __x) const; + iterator upper_bound(const key_type& __x); + const_iterator upper_bound(const key_type& __x) const; + pair equal_range(const key_type& __x); + pair equal_range(const key_type& __x) const; + +public: + // Debugging. + bool __rb_verify() const; +}; + +template +inline bool +operator==(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline bool +operator<(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool +operator>(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool +operator<=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool +operator>=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + + +template +inline void +swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) +{ + if (this != &__x) { + // Note that _Key may be a constant type. + clear(); + _M_node_count = 0; + _M_key_compare = __x._M_key_compare; + if (__x._M_root() == 0) { + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; + } + else { + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_node_count = __x._M_node_count; + } + } + return *this; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v) +{ + _Link_type __x = (_Link_type) __x_; + _Link_type __y = (_Link_type) __y_; + _Link_type __z; + + if (__y == _M_header || __x != 0 || + _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) { + __z = _M_create_node(__v); + _S_left(__y) = __z; // also makes _M_leftmost() = __z + // when __y == _M_header + if (__y == _M_header) { + _M_root() = __z; + _M_rightmost() = __z; + } + else if (__y == _M_leftmost()) + _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node + } + else { + __z = _M_create_node(__v); + _S_right(__y) = __z; + if (__y == _M_rightmost()) + _M_rightmost() = __z; // maintain _M_rightmost() pointing to max node + } + _S_parent(__z) = __y; + _S_left(__z) = 0; + _S_right(__z) = 0; + _Rb_tree_rebalance(__z, _M_header->_M_parent); + ++_M_node_count; + return iterator(__z); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::insert_equal(const _Value& __v) +{ + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + while (__x != 0) { + __y = __x; + __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert(__x, __y, __v); +} + + +template +pair::iterator, + bool> +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::insert_unique(const _Value& __v) +{ + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + bool __comp = true; + while (__x != 0) { + __y = __x; + __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); + } + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair(_M_insert(__x, __y, __v), true); + else + --__j; + if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair(_M_insert(__x, __y, __v), true); + return pair(__j, false); +} + + +template +typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator +_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> + ::insert_unique(iterator __position, const _Val& __v) +{ + if (__position._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_unique(__v).first; + } else if (__position._M_node == _M_header) { // end() + if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_unique(__v).first; + } else { + iterator __before = __position; + --__before; + if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) + && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + } else + return insert_unique(__v).first; + } +} + +template +typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc> + ::insert_equal(iterator __position, const _Val& __v) +{ + if (__position._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_equal(__v); + } else if (__position._M_node == _M_header) {// end() + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_equal(__v); + } else { + iterator __before = __position; + --__before; + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) + && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + } else + return insert_equal(__v); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template + template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(_II __first, _II __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template + template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(_II __first, _II __last) { + for ( ; __first != __last; ++__first) + insert_unique(*__first); +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); +} + +template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(iterator __position) +{ + _Link_type __y = + (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, + _M_header->_M_parent, + _M_header->_M_left, + _M_header->_M_right); + destroy_node(__y); + --_M_node_count; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) +{ + pair __p = equal_range(__x); + size_type __n = 0; + distance(__p.first, __p.second, __n); + erase(__p.first, __p.second); + return __n; +} + +template +typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type +_Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc> + ::_M_copy(_Link_type __x, _Link_type __p) +{ + // structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + __STL_TRY { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + __STL_UNWIND(_M_erase(__top)); + + return __top; +} + +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::_M_erase(_Link_type __x) +{ + // erase without rebalancing + while (__x != 0) { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + destroy_node(__x); + __x = __y; + } +} + +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(iterator __first, iterator __last) +{ + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) erase(__first++); +} + +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(const _Key* __first, const _Key* __last) +{ + while (__first != __last) erase(*__first++); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) +{ + _Link_type __y = _M_header; // Last node which is not less than __k. + _Link_type __x = _M_root(); // Current node. + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + iterator __j = iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) { + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + } + const_iterator __j = const_iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::count(const _Key& __k) const +{ + pair __p = equal_range(__k); + size_type __n = 0; + distance(__p.first, __p.second, __n); + return __n; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::lower_bound(const _Key& __k) +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::lower_bound(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::upper_bound(const _Key& __k) +{ + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::upper_bound(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); +} + +template +inline +pair::iterator, + typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator> +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::equal_range(const _Key& __k) +{ + return pair(lower_bound(__k), upper_bound(__k)); +} + +template +inline +pair::const_iterator, + typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator> +_Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc> + ::equal_range(const _Key& __k) const +{ + return pair(lower_bound(__k), + upper_bound(__k)); +} + +inline int +__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) +{ + if (__node == 0) + return 0; + else { + int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0; + if (__node == __root) + return __bc; + else + return __bc + __black_count(__node->_M_parent, __root); + } +} + +template +bool _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const +{ + if (_M_node_count == 0 || begin() == end()) + return _M_node_count == 0 && begin() == end() && + _M_header->_M_left == _M_header && _M_header->_M_right == _M_header; + + int __len = __black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) { + _Link_type __x = (_Link_type) __it._M_node; + _Link_type __L = _S_left(__x); + _Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_rb_tree_red) + if ((__L && __L->_M_color == _S_rb_tree_red) || + (__R && __R->_M_color == _S_rb_tree_red)) + return false; + + if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) + return false; + if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) + return false; + + if (!__L && !__R && __black_count(__x, _M_root()) != __len) + return false; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + + return true; +} + +// Class rb_tree is not part of the C++ standard. It is provided for +// compatibility with the HP STL. + +template +struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> +{ + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) {} + + ~rb_tree() {} +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_TREE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_uninitialized.h b/darkice/tags/darkice-0_2/stl/stl_uninitialized.h new file mode 100644 index 0000000..d367fbe --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_uninitialized.h @@ -0,0 +1,279 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#define __SGI_STL_INTERNAL_UNINITIALIZED_H + +__STL_BEGIN_NAMESPACE + +// uninitialized_copy + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template +inline _ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __true_type) +{ + return copy(__first, __last, __result); +} + +template +_ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __false_type) +{ + _ForwardIter __cur = __result; + __STL_TRY { + for ( ; __first != __last; ++__first, ++__cur) + _Construct(&*__cur, *__first); + return __cur; + } + __STL_UNWIND(_Destroy(__result, __cur)); +} + + +template +inline _ForwardIter +__uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, _Tp*) +{ + typedef typename __type_traits<_Tp>::is_POD_type _Is_POD; + return __uninitialized_copy_aux(__first, __last, __result, _Is_POD()); +} + +template +inline _ForwardIter + uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result) +{ + return __uninitialized_copy(__first, __last, __result, + __VALUE_TYPE(__result)); +} + +inline char* uninitialized_copy(const char* __first, const char* __last, + char* __result) { + memmove(__result, __first, __last - __first); + return __result + (__last - __first); +} + +inline wchar_t* +uninitialized_copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) +{ + memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); +} + +// uninitialized_copy_n (not part of the C++ standard) + +template +pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result, + input_iterator_tag) +{ + _ForwardIter __cur = __result; + __STL_TRY { + for ( ; __count > 0 ; --__count, ++__first, ++__cur) + _Construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); + } + __STL_UNWIND(_Destroy(__result, __cur)); +} + +template +inline pair<_RandomAccessIter, _ForwardIter> +__uninitialized_copy_n(_RandomAccessIter __first, _Size __count, + _ForwardIter __result, + random_access_iterator_tag) { + _RandomAccessIter __last = __first + __count; + return pair<_RandomAccessIter, _ForwardIter>( + __last, + uninitialized_copy(__first, __last, __result)); +} + +template +inline pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template +inline pair<_InputIter, _ForwardIter> +uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template +inline void +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __true_type) +{ + fill(__first, __last, __x); +} + +template +void +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __false_type) +{ + _ForwardIter __cur = __first; + __STL_TRY { + for ( ; __cur != __last; ++__cur) + _Construct(&*__cur, __x); + } + __STL_UNWIND(_Destroy(__first, __cur)); +} + +template +inline void __uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + __uninitialized_fill_aux(__first, __last, __x, _Is_POD()); + +} + +template +inline void uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, + const _Tp& __x) +{ + __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first)); +} + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template +inline _ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __true_type) +{ + return fill_n(__first, __n, __x); +} + +template +_ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __false_type) +{ + _ForwardIter __cur = __first; + __STL_TRY { + for ( ; __n > 0; --__n, ++__cur) + _Construct(&*__cur, __x); + return __cur; + } + __STL_UNWIND(_Destroy(__first, __cur)); +} + +template +inline _ForwardIter +__uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); +} + +template +inline _ForwardIter +uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) +{ + return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first)); +} + +// Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, +// __uninitialized_fill_copy. + +// __uninitialized_copy_copy +// Copies [first1, last1) into [result, result + (last1 - first1)), and +// copies [first2, last2) into +// [result, result + (last1 - first1) + (last2 - first2)). + +template +inline _ForwardIter +__uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _ForwardIter __result) +{ + _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result); + __STL_TRY { + return uninitialized_copy(__first2, __last2, __mid); + } + __STL_UNWIND(_Destroy(__result, __mid)); +} + +// __uninitialized_fill_copy +// Fills [result, mid) with x, and copies [first, last) into +// [mid, mid + (last - first)). +template +inline _ForwardIter +__uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid, + const _Tp& __x, + _InputIter __first, _InputIter __last) +{ + uninitialized_fill(__result, __mid, __x); + __STL_TRY { + return uninitialized_copy(__first, __last, __mid); + } + __STL_UNWIND(_Destroy(__result, __mid)); +} + +// __uninitialized_copy_fill +// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and +// fills [first2 + (last1 - first1), last2) with x. +template +inline void +__uninitialized_copy_fill(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + const _Tp& __x) +{ + _ForwardIter __mid2 = uninitialized_copy(__first1, __last1, __first2); + __STL_TRY { + uninitialized_fill(__mid2, __last2, __x); + } + __STL_UNWIND(_Destroy(__first2, __mid2)); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_UNINITIALIZED_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/stl_vector.h b/darkice/tags/darkice-0_2/stl/stl_vector.h new file mode 100644 index 0000000..883fff9 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/stl_vector.h @@ -0,0 +1,869 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_VECTOR_H +#define __SGI_STL_INTERNAL_VECTOR_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// The vector base class serves two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Vector_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Vector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + allocator_type _M_data_allocator; + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator.allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { if (__p) _M_data_allocator.deallocate(__p, __n); } +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Vector_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_alloc_base(const allocator_type&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type; + _Tp* _M_allocate(size_t __n) + { return _Alloc_type::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _Alloc_type::deallocate(__p, __n);} +}; + +template +struct _Vector_base + : public _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Vector_base(const allocator_type& __a) : _Base(__a) {} + _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Vector_base { +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_base(const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} + _Vector_base(size_t __n, const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef simple_alloc<_Tp, _Alloc> _M_data_allocator; + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _M_data_allocator::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +class vector : protected _Vector_base<_Tp, _Alloc> +{ + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + +private: + typedef _Vector_base<_Tp, _Alloc> _Base; +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_HAS_NAMESPACES */ + +protected: + void _M_insert_aux(iterator __position, const _Tp& __x); + void _M_insert_aux(iterator __position); + +public: + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + reverse_iterator rend() + { return reverse_iterator(begin()); } + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + size_type size() const + { return size_type(end() - begin()); } + size_type max_size() const + { return size_type(-1) / sizeof(_Tp); } + size_type capacity() const + { return size_type(_M_end_of_storage - begin()); } + bool empty() const + { return begin() == end(); } + + reference operator[](size_type __n) { return *(begin() + __n); } + const_reference operator[](size_type __n) const { return *(begin() + __n); } + +#ifdef __STL_THROW_RANGE_ERRORS + void _M_range_check(size_type __n) const { + if (__n >= this->size()) + __stl_throw_range_error("vector"); + } + + reference at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + const_reference at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } +#endif /* __STL_THROW_RANGE_ERRORS */ + + explicit vector(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + vector(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } + + explicit vector(size_type __n) + : _Base(__n, allocator_type()) + { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); } + + vector(const vector<_Tp, _Alloc>& __x) + : _Base(__x.size(), __x.get_allocator()) + { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } + +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_aux(__first, __last, _Integral()); + } + + template + void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) { + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_fill_n(_M_start, __n, __value); + } + + template + void _M_initialize_aux(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); + } + +#else + vector(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__last - __first, __a) + { _M_finish = uninitialized_copy(__first, __last, _M_start); } +#endif /* __STL_MEMBER_TEMPLATES */ + + ~vector() { destroy(_M_start, _M_finish); } + + vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x); + void reserve(size_type __n) { + if (capacity() < __n) { + const size_type __old_size = size(); + iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_finish = __tmp + __old_size; + _M_end_of_storage = _M_start + __n; + } + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } + void _M_fill_assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(end() - 1); } + const_reference back() const { return *(end() - 1); } + + void push_back(const _Tp& __x) { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, __x); + ++_M_finish; + } + else + _M_insert_aux(end(), __x); + } + void push_back() { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish); + ++_M_finish; + } + else + _M_insert_aux(end()); + } + void swap(vector<_Tp, _Alloc>& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); + } + + iterator insert(iterator __position, const _Tp& __x) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish, __x); + ++_M_finish; + } + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + iterator insert(iterator __position) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish); + ++_M_finish; + } + else + _M_insert_aux(__position); + return begin() + __n; + } +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) + { _M_fill_insert(__pos, (size_type) __n, (_Tp) __val); } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, + const_iterator __first, const_iterator __last); +#endif /* __STL_MEMBER_TEMPLATES */ + + void insert (iterator __pos, size_type __n, const _Tp& __x) + { _M_fill_insert(__pos, __n, __x); } + + void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x); + + void pop_back() { + --_M_finish; + destroy(_M_finish); + } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, _M_finish, __position); + --_M_finish; + destroy(_M_finish); + return __position; + } + iterator erase(iterator __first, iterator __last) { + iterator __i = copy(__last, _M_finish, __first); + destroy(__i, _M_finish); + _M_finish = _M_finish - (__last - __first); + return __first; + } + + void resize(size_type __new_size, const _Tp& __x) { + if (__new_size < size()) + erase(begin() + __new_size, end()); + else + insert(end(), __new_size - size(), __x); + } + void resize(size_type __new_size) { resize(__new_size, _Tp()); } + void clear() { erase(begin(), end()); } + +protected: + +#ifdef __STL_MEMBER_TEMPLATES + template + iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first, + _ForwardIterator __last) +{ + iterator __result = _M_allocate(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __result); + return __result; + } + __STL_UNWIND(_M_deallocate(__result, __n)); + } +#else /* __STL_MEMBER_TEMPLATES */ + iterator _M_allocate_and_copy(size_type __n, const_iterator __first, + const_iterator __last) + { + iterator __result = _M_allocate(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __result); + return __result; + } + __STL_UNWIND(_M_deallocate(__result, __n)); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + +#ifdef __STL_MEMBER_TEMPLATES + template + void _M_range_initialize(_InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + // This function is only called by the constructor. + template + void _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_copy(__first, __last, _M_start); + } + + template + void _M_range_insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_range_insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template +inline bool +operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline bool +operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) +{ + __x.swap(__y); +} + +template +inline bool +operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool +operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return __y < __x; +} + +template +inline bool +operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool +operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +vector<_Tp,_Alloc>& +vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x) +{ + if (&__x != this) { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) { + iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_start + __xlen; + } + else if (size() >= __xlen) { + iterator __i = copy(__x.begin(), __x.end(), begin()); + destroy(__i, _M_finish); + } + else { + copy(__x.begin(), __x.begin() + size(), _M_start); + uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish); + } + _M_finish = _M_start + __xlen; + } + return *this; +} + +template +void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val) +{ + if (__n > capacity()) { + vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) { + fill(begin(), end(), __val); + _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val); + } + else + erase(fill_n(begin(), __n, __val), end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +template template +void +vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + + if (__len > capacity()) { + iterator __tmp = _M_allocate_and_copy(__len, __first, __last); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_finish = _M_start + __len; + } + else if (size() >= __len) { + iterator __new_finish = copy(__first, __last, _M_start); + destroy(__new_finish, _M_finish); + _M_finish = __new_finish; + } + else { + _ForwardIter __mid = __first; + advance(__mid, size()); + copy(__first, __mid, _M_start); + _M_finish = uninitialized_copy(__mid, __last, _M_finish); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + _Tp __x_copy = __x; + copy_backward(__position, _M_finish - 2, _M_finish - 1); + *__position = __x_copy; + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish, __x); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(begin(), end()); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } +} + +template +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + copy_backward(__position, _M_finish - 2, _M_finish - 1); + *__position = _Tp(); + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(begin(), end()); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } +} + +template +void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n, + const _Tp& __x) +{ + if (__n != 0) { + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + _Tp __x_copy = __x; + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + fill(__position, __position + __n, __x_copy); + } + else { + uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + fill(__position, __old_finish, __x_copy); + } + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_fill_n(__new_finish, __n, __x); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +vector<_Tp, _Alloc>::_M_range_insert(iterator __pos, + _InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; + } +} + +template template +void +vector<_Tp, _Alloc>::_M_range_insert(iterator __position, + _ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) +{ + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + copy(__first, __last, __position); + } + else { + _ForwardIterator __mid = __first; + advance(__mid, __elems_after); + uninitialized_copy(__mid, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + copy(__first, __mid, __position); + } + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +vector<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, + const_iterator __last) +{ + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + copy(__first, __last, __position); + } + else { + uninitialized_copy(__first + __elems_after, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + copy(__first, __first + __elems_after, __position); + } + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/string b/darkice/tags/darkice-0_2/stl/string new file mode 100644 index 0000000..1ca6521 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/string @@ -0,0 +1,2413 @@ +/* + * Copyright (c) 1997-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_STRING +#define __SGI_STL_STRING + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __STL_USE_NEW_IOSTREAMS +#include +#else /* __STL_USE_NEW_IOSTREAMS */ +#include +#endif /* __STL_USE_NEW_IOSTREAMS */ + +// Standard C++ string class. This class has performance +// characteristics very much like vector<>, meaning, for example, that +// it does not perform reference-count or copy-on-write, and that +// concatenation of two strings is an O(N) operation. + +// There are three reasons why basic_string is not identical to +// vector. First, basic_string always stores a null character at the +// end; this makes it possible for c_str to be a fast operation. +// Second, the C++ standard requires basic_string to copy elements +// using char_traits<>::assign, char_traits<>::copy, and +// char_traits<>::move. This means that all of vector<>'s low-level +// operations must be rewritten. Third, basic_string<> has a lot of +// extra functions in its interface that are convenient but, strictly +// speaking, redundant. + +// Additionally, the C++ standard imposes a major restriction: according +// to the standard, the character type _CharT must be a POD type. This +// implementation weakens that restriction, and allows _CharT to be a +// a user-defined non-POD type. However, _CharT must still have a +// default constructor. + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// A helper class to use a char_traits as a function object. + +template +struct _Not_within_traits + : public unary_function +{ + typedef const typename _Traits::char_type* _Pointer; + const _Pointer _M_first; + const _Pointer _M_last; + + _Not_within_traits(_Pointer __f, _Pointer __l) + : _M_first(__f), _M_last(__l) {} + + bool operator()(const typename _Traits::char_type& __x) const { + return find_if(_M_first, _M_last, + bind1st(_Eq_traits<_Traits>(), __x)) == _M_last; + } +}; + +// ------------------------------------------------------------ +// Class _String_base. + +// _String_base is a helper class that makes it it easier to write an +// exception-safe version of basic_string. The constructor allocates, +// but does not initialize, a block of memory. The destructor +// deallocates, but does not destroy elements within, a block of +// memory. The destructor assumes that _M_start either is null, or else +// points to a block of memory that was allocated using _String_base's +// allocator and whose size is _M_end_of_storage - _M_start. + +// Additionally, _String_base encapsulates the difference between +// old SGI-style allocators and standard-conforming allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// General base class. +template +class _String_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _String_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator.allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) { + if (__p) + _M_data_allocator.deallocate(__p, __n); + } + +protected: + allocator_type _M_data_allocator; + + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; +}; + +// Specialization for instanceless allocators. +template +class _String_alloc_base<_Tp,_Alloc,true> { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _String_alloc_base(const allocator_type&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} + +protected: + typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Alloc_type; + _Tp* _M_allocate(size_t __n) + { return _Alloc_type::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _Alloc_type::deallocate(__p, __n); } + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; +}; + +template +class _String_base + : public _String_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +protected: + typedef _String_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + void _M_allocate_block(size_t __n) { + if (__n <= max_size()) { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + else + _M_throw_length_error(); + } + + void _M_deallocate_block() + { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } + + size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; } + + _String_base(const allocator_type& __a) : _Base(__a) { } + + _String_base(const allocator_type& __a, size_t __n) : _Base(__a) + { _M_allocate_block(__n); } + + ~_String_base() { _M_deallocate_block(); } + + void _M_throw_length_error() const; + void _M_throw_out_of_range() const; +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template class _String_base { +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + +protected: + typedef simple_alloc<_Tp, _Alloc> _Alloc_type; + + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + // Precondition: 0 < __n <= max_size(). + + _Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) { + if (__p) + _Alloc_type::deallocate(__p, __n); + } + + void _M_allocate_block(size_t __n) { + if (__n <= max_size()) { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + else + _M_throw_length_error(); + } + + void _M_deallocate_block() + { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } + + size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; } + + _String_base(const allocator_type&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) { } + + _String_base(const allocator_type&, size_t __n) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + { _M_allocate_block(__n); } + + ~_String_base() { _M_deallocate_block(); } + + void _M_throw_length_error() const; + void _M_throw_out_of_range() const; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +// Helper functions for exception handling. +template +void _String_base<_Tp,_Alloc>::_M_throw_length_error() const { + __STL_THROW(length_error("basic_string")); +} + +template +void _String_base<_Tp, _Alloc>::_M_throw_out_of_range() const { + __STL_THROW(out_of_range("basic_string")); +} + + +// ------------------------------------------------------------ +// Class basic_string. + +// Class invariants: +// (1) [start, finish) is a valid range. +// (2) Each iterator in [start, finish) points to a valid object +// of type value_type. +// (3) *finish is a valid object of type value_type; in particular, +// it is value_type(). +// (4) [finish + 1, end_of_storage) is a valid range. +// (5) Each iterator in [finish + 1, end_of_storage) points to +// unininitialized memory. + +// Note one important consequence: a string of length n must manage +// a block of memory whose size is at least n + 1. + + +template +class basic_string : private _String_base<_CharT,_Alloc> { +public: + typedef _CharT value_type; + typedef _Traits traits_type; + + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef const value_type* const_iterator; + typedef value_type* iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator + const_reverse_iterator; + typedef reverse_iterator + reverse_iterator; +#endif /* __STL_PARTIAL_SPECIALIZATION */ + + static const size_type npos; + + typedef _String_base<_CharT,_Alloc> _Base; + +public: // Constructor, destructor, assignment. + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + + explicit basic_string(const allocator_type& __a = allocator_type()) + : _Base(__a, 8) { _M_terminate_string(); } + + struct _Reserve_t {}; + basic_string(_Reserve_t, size_t __n, + const allocator_type& __a = allocator_type()) + : _Base(__a, __n + 1) { _M_terminate_string(); } + + basic_string(const basic_string& __s) : _Base(__s.get_allocator()) + { _M_range_initialize(__s.begin(), __s.end()); } + + basic_string(const basic_string& __s, size_type __pos, size_type __n = npos, + const allocator_type& __a = allocator_type()) + : _Base(__a) { + if (__pos > __s.size()) + _M_throw_out_of_range(); + else + _M_range_initialize(__s.begin() + __pos, + __s.begin() + __pos + min(__n, __s.size() - __pos)); + } + + basic_string(const _CharT* __s, size_type __n, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { _M_range_initialize(__s, __s + __n); } + + basic_string(const _CharT* __s, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { _M_range_initialize(__s, __s + _Traits::length(__s)); } + + basic_string(size_type __n, _CharT __c, + const allocator_type& __a = allocator_type()) + : _Base(__a, __n + 1) + { + _M_finish = uninitialized_fill_n(_M_start, __n, __c); + _M_terminate_string(); + } + + // Check to see if _InputIterator is an integer type. If so, then + // it can't be an iterator. +#ifdef __STL_MEMBER_TEMPLATES + template + basic_string(_InputIterator __f, _InputIterator __l, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__f, __l, _Integral()); + } +#else /* __STL_MEMBER_TEMPLATES */ + basic_string(const _CharT* __f, const _CharT* __l, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_range_initialize(__f, __l); + } +#endif + + ~basic_string() { destroy(_M_start, _M_finish + 1); } + + basic_string& operator=(const basic_string& __s) { + if (&__s != this) + assign(__s.begin(), __s.end()); + return *this; + } + + basic_string& operator=(const _CharT* __s) + { return assign(__s, __s + _Traits::length(__s)); } + + basic_string& operator=(_CharT __c) + { return assign(static_cast(1), __c); } + +protected: // Protected members inherited from base. +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_allocate_block; + using _Base::_M_deallocate_block; + using _Base::_M_throw_length_error; + using _Base::_M_throw_out_of_range; + + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_HAS_NAMESPACES */ + +private: // Helper functions used by constructors + // and elsewhere. + void _M_construct_null(_CharT* __p) { + construct(__p); +# ifdef __STL_DEFAULT_CONSTRUCTOR_BUG + __STL_TRY { + *__p = (_CharT) 0; + } + __STL_UNWIND(destroy(__p)); +# endif + } + + static _CharT _M_null() { +# ifndef __STL_DEFAULT_CONSTRUCTOR_BUG + return _CharT(); +# else + return (_CharT) 0; +# endif + } + +private: + // Helper functions used by constructors. It is a severe error for + // any of them to be called anywhere except from within constructors. + + void _M_terminate_string() { + __STL_TRY { + _M_construct_null(_M_finish); + } + __STL_UNWIND(destroy(_M_start, _M_finish)); + } + +#ifdef __STL_MEMBER_TEMPLATES + + template + void _M_range_initialize(_InputIter __f, _InputIter __l, + input_iterator_tag) { + _M_allocate_block(8); + _M_construct_null(_M_finish); + __STL_TRY { + append(__f, __l); + } + __STL_UNWIND(destroy(_M_start, _M_finish + 1)); + } + + template + void _M_range_initialize(_ForwardIter __f, _ForwardIter __l, + forward_iterator_tag) { + difference_type __n = 0; + distance(__f, __l, __n); + _M_allocate_block(__n + 1); + _M_finish = uninitialized_copy(__f, __l, _M_start); + _M_terminate_string(); + } + + template + void _M_range_initialize(_InputIter __f, _InputIter __l) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + _M_range_initialize(__f, __l, _Category()); + } + + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_allocate_block(__n + 1); + _M_finish = uninitialized_fill_n(_M_start, __n, __x); + _M_terminate_string(); + } + + template + void _M_initialize_dispatch(_InputIter __f, _InputIter __l, __false_type) { + _M_range_initialize(__f, __l); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void _M_range_initialize(const _CharT* __f, const _CharT* __l) { + ptrdiff_t __n = __l - __f; + _M_allocate_block(__n + 1); + _M_finish = uninitialized_copy(__f, __l, _M_start); + _M_terminate_string(); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: // Iterators. + iterator begin() { return _M_start; } + iterator end() { return _M_finish; } + const_iterator begin() const { return _M_start; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(_M_finish); } + reverse_iterator rend() + { return reverse_iterator(_M_start); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(_M_finish); } + const_reverse_iterator rend() const + { return const_reverse_iterator(_M_start); } + +public: // Size, capacity, etc. + size_type size() const { return _M_finish - _M_start; } + size_type length() const { return size(); } + + size_t max_size() const { return _Base::max_size(); } + + + void resize(size_type __n, _CharT __c) { + if (__n <= size()) + erase(begin() + __n, end()); + else + append(__n - size(), __c); + } + + void resize(size_type __n) { resize(__n, _M_null()); } + + void reserve(size_type = 0); + + size_type capacity() const { return (_M_end_of_storage - _M_start) - 1; } + + void clear() { + if (!empty()) { + _Traits::assign(*_M_start, _M_null()); + destroy(_M_start+1, _M_finish+1); + _M_finish = _M_start; + } + } + + bool empty() const { return _M_start == _M_finish; } + +public: // Element access. + + const_reference operator[](size_type __n) const + { return *(_M_start + __n); } + reference operator[](size_type __n) + { return *(_M_start + __n); } + + const_reference at(size_type __n) const { + if (__n >= size()) + _M_throw_out_of_range(); + return *(_M_start + __n); + } + + reference at(size_type __n) { + if (__n >= size()) + _M_throw_out_of_range(); + return *(_M_start + __n); + } + +public: // Append, operator+=, push_back. + + basic_string& operator+=(const basic_string& __s) { return append(__s); } + basic_string& operator+=(const _CharT* __s) { return append(__s); } + basic_string& operator+=(_CharT __c) { push_back(__c); return *this; } + + basic_string& append(const basic_string& __s) + { return append(__s.begin(), __s.end()); } + + basic_string& append(const basic_string& __s, + size_type __pos, size_type __n) + { + if (__pos > __s.size()) + _M_throw_out_of_range(); + return append(__s.begin() + __pos, + __s.begin() + __pos + min(__n, __s.size() - __pos)); + } + + basic_string& append(const _CharT* __s, size_type __n) + { return append(__s, __s+__n); } + + basic_string& append(const _CharT* __s) + { return append(__s, __s + _Traits::length(__s)); } + + basic_string& append(size_type __n, _CharT __c); + +#ifdef __STL_MEMBER_TEMPLATES + + // Check to see if _InputIterator is an integer type. If so, then + // it can't be an iterator. + template + basic_string& append(_InputIter __first, _InputIter __last) { + typedef typename _Is_integer<_InputIter>::_Integral _Integral; + return _M_append_dispatch(__first, __last, _Integral()); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + basic_string& append(const _CharT* __first, const _CharT* __last); + +#endif /* __STL_MEMBER_TEMPLATES */ + + void push_back(_CharT __c) { + if (_M_finish + 1 == _M_end_of_storage) + reserve(size() + max(size(), static_cast(1))); + _M_construct_null(_M_finish + 1); + _Traits::assign(*_M_finish, __c); + ++_M_finish; + } + + void pop_back() { + _Traits::assign(*(_M_finish - 1), _M_null()); + destroy(_M_finish); + --_M_finish; + } + +private: // Helper functions for append. + +#ifdef __STL_MEMBER_TEMPLATES + + template + basic_string& append(_InputIter __f, _InputIter __l, input_iterator_tag); + + template + basic_string& append(_ForwardIter __f, _ForwardIter __l, + forward_iterator_tag); + + template + basic_string& _M_append_dispatch(_Integer __n, _Integer __x, __true_type) { + return append((size_type) __n, (_CharT) __x); + } + + template + basic_string& _M_append_dispatch(_InputIter __f, _InputIter __l, + __false_type) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + return append(__f, __l, _Category()); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: // Assign + + basic_string& assign(const basic_string& __s) + { return assign(__s.begin(), __s.end()); } + + basic_string& assign(const basic_string& __s, + size_type __pos, size_type __n) { + if (__pos > __s.size()) + _M_throw_out_of_range(); + return assign(__s.begin() + __pos, + __s.begin() + __pos + min(__n, __s.size() - __pos)); + } + + basic_string& assign(const _CharT* __s, size_type __n) + { return assign(__s, __s + __n); } + + basic_string& assign(const _CharT* __s) + { return assign(__s, __s + _Traits::length(__s)); } + + basic_string& assign(size_type __n, _CharT __c); + +#ifdef __STL_MEMBER_TEMPLATES + + // Check to see if _InputIterator is an integer type. If so, then + // it can't be an iterator. + template + basic_string& assign(_InputIter __first, _InputIter __last) { + typedef typename _Is_integer<_InputIter>::_Integral _Integral; + return _M_assign_dispatch(__first, __last, _Integral()); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + basic_string& assign(const _CharT* __f, const _CharT* __l); + +private: // Helper functions for assign. + +#ifdef __STL_MEMBER_TEMPLATES + + template + basic_string& _M_assign_dispatch(_Integer __n, _Integer __x, __true_type) { + return assign((size_type) __n, (_CharT) __x); + } + + template + basic_string& _M_assign_dispatch(_InputIter __f, _InputIter __l, + __false_type); + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: // Insert + + basic_string& insert(size_type __pos, const basic_string& __s) { + if (__pos > size()) + _M_throw_out_of_range(); + if (size() > max_size() - __s.size()) + _M_throw_length_error(); + insert(_M_start + __pos, __s.begin(), __s.end()); + return *this; + } + + basic_string& insert(size_type __pos, const basic_string& __s, + size_type __beg, size_type __n) { + if (__pos > size() || __beg > __s.size()) + _M_throw_out_of_range(); + size_type __len = min(__n, __s.size() - __beg); + if (size() > max_size() - __len) + _M_throw_length_error(); + insert(_M_start + __pos, + __s.begin() + __beg, __s.begin() + __beg + __len); + return *this; + } + + basic_string& insert(size_type __pos, const _CharT* __s, size_type __n) { + if (__pos > size()) + _M_throw_out_of_range(); + if (size() > max_size() - __n) + _M_throw_length_error(); + insert(_M_start + __pos, __s, __s + __n); + return *this; + } + + basic_string& insert(size_type __pos, const _CharT* __s) { + if (__pos > size()) + _M_throw_out_of_range(); + size_type __len = _Traits::length(__s); + if (size() > max_size() - __len) + _M_throw_length_error(); + insert(_M_start + __pos, __s, __s + __len); + return *this; + } + + basic_string& insert(size_type __pos, size_type __n, _CharT __c) { + if (__pos > size()) + _M_throw_out_of_range(); + if (size() > max_size() - __n) + _M_throw_length_error(); + insert(_M_start + __pos, __n, __c); + return *this; + } + + iterator insert(iterator __p, _CharT __c) { + if (__p == _M_finish) { + push_back(__c); + return _M_finish - 1; + } + else + return _M_insert_aux(__p, __c); + } + + void insert(iterator __p, size_t __n, _CharT __c); + +#ifdef __STL_MEMBER_TEMPLATES + + // Check to see if _InputIterator is an integer type. If so, then + // it can't be an iterator. + template + void insert(iterator __p, _InputIter __first, _InputIter __last) { + typedef typename _Is_integer<_InputIter>::_Integral _Integral; + _M_insert_dispatch(__p, __first, __last, _Integral()); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert(iterator __p, const _CharT* __first, const _CharT* __last); + +#endif /* __STL_MEMBER_TEMPLATES */ + +private: // Helper functions for insert. + +#ifdef __STL_MEMBER_TEMPLATES + + template + void insert(iterator __p, _InputIter, _InputIter, input_iterator_tag); + + template + void insert(iterator __p, _ForwardIter, _ForwardIter, forward_iterator_tag); + + + template + void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x, + __true_type) { + insert(__p, (size_type) __n, (_CharT) __x); + } + + template + void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last, + __false_type) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + insert(__p, __first, __last, _Category()); + } + + template + void + _M_copy(_InputIterator __first, _InputIterator __last, iterator __result) { + for ( ; __first != __last; ++__first, ++__result) + _Traits::assign(*__result, *__first); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator _M_insert_aux(iterator, _CharT); + + void + _M_copy(const _CharT* __first, const _CharT* __last, _CharT* __result) { + _Traits::copy(__result, __first, __last - __first); + } + +public: // Erase. + + basic_string& erase(size_type __pos = 0, size_type __n = npos) { + if (__pos > size()) + _M_throw_out_of_range(); + erase(_M_start + __pos, _M_start + __pos + min(__n, size() - __pos)); + return *this; + } + + iterator erase(iterator __position) { + // The move includes the terminating null. + _Traits::move(__position, __position + 1, _M_finish - __position); + destroy(_M_finish); + --_M_finish; + return __position; + } + + iterator erase(iterator __first, iterator __last) { + if (__first != __last) { + // The move includes the terminating null. + _Traits::move(__first, __last, (_M_finish - __last) + 1); + const iterator __new_finish = _M_finish - (__last - __first); + destroy(__new_finish + 1, _M_finish + 1); + _M_finish = __new_finish; + } + return __first; + } + +public: // Replace. (Conceptually equivalent + // to erase followed by insert.) + basic_string& replace(size_type __pos, size_type __n, + const basic_string& __s) { + if (__pos > size()) + _M_throw_out_of_range(); + const size_type __len = min(__n, size() - __pos); + if (size() - __len >= max_size() - __s.size()) + _M_throw_length_error(); + return replace(_M_start + __pos, _M_start + __pos + __len, + __s.begin(), __s.end()); + } + + basic_string& replace(size_type __pos1, size_type __n1, + const basic_string& __s, + size_type __pos2, size_type __n2) { + if (__pos1 > size() || __pos2 > __s.size()) + _M_throw_out_of_range(); + const size_type __len1 = min(__n1, size() - __pos1); + const size_type __len2 = min(__n2, __s.size() - __pos2); + if (size() - __len1 >= max_size() - __len2) + _M_throw_length_error(); + return replace(_M_start + __pos1, _M_start + __pos1 + __len1, + __s._M_start + __pos2, __s._M_start + __pos2 + __len2); + } + + basic_string& replace(size_type __pos, size_type __n1, + const _CharT* __s, size_type __n2) { + if (__pos > size()) + _M_throw_out_of_range(); + const size_type __len = min(__n1, size() - __pos); + if (__n2 > max_size() || size() - __len >= max_size() - __n2) + _M_throw_length_error(); + return replace(_M_start + __pos, _M_start + __pos + __len, + __s, __s + __n2); + } + + basic_string& replace(size_type __pos, size_type __n1, + const _CharT* __s) { + if (__pos > size()) + _M_throw_out_of_range(); + const size_type __len = min(__n1, size() - __pos); + const size_type __n2 = _Traits::length(__s); + if (__n2 > max_size() || size() - __len >= max_size() - __n2) + _M_throw_length_error(); + return replace(_M_start + __pos, _M_start + __pos + __len, + __s, __s + _Traits::length(__s)); + } + + basic_string& replace(size_type __pos, size_type __n1, + size_type __n2, _CharT __c) { + if (__pos > size()) + _M_throw_out_of_range(); + const size_type __len = min(__n1, size() - __pos); + if (__n2 > max_size() || size() - __len >= max_size() - __n2) + _M_throw_length_error(); + return replace(_M_start + __pos, _M_start + __pos + __len, __n2, __c); + } + + basic_string& replace(iterator __first, iterator __last, + const basic_string& __s) + { return replace(__first, __last, __s.begin(), __s.end()); } + + basic_string& replace(iterator __first, iterator __last, + const _CharT* __s, size_type __n) + { return replace(__first, __last, __s, __s + __n); } + + basic_string& replace(iterator __first, iterator __last, + const _CharT* __s) { + return replace(__first, __last, __s, __s + _Traits::length(__s)); + } + + basic_string& replace(iterator __first, iterator __last, + size_type __n, _CharT __c); + + // Check to see if _InputIterator is an integer type. If so, then + // it can't be an iterator. +#ifdef __STL_MEMBER_TEMPLATES + template + basic_string& replace(iterator __first, iterator __last, + _InputIter __f, _InputIter __l) { + typedef typename _Is_integer<_InputIter>::_Integral _Integral; + return _M_replace_dispatch(__first, __last, __f, __l, _Integral()); + } +#else /* __STL_MEMBER_TEMPLATES */ + basic_string& replace(iterator __first, iterator __last, + const _CharT* __f, const _CharT* __l); +#endif /* __STL_MEMBER_TEMPLATES */ + +private: // Helper functions for replace. + +#ifdef __STL_MEMBER_TEMPLATES + + template + basic_string& _M_replace_dispatch(iterator __first, iterator __last, + _Integer __n, _Integer __x, + __true_type) { + return replace(__first, __last, (size_type) __n, (_CharT) __x); + } + + template + basic_string& _M_replace_dispatch(iterator __first, iterator __last, + _InputIter __f, _InputIter __l, + __false_type) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + return replace(__first, __last, __f, __l, _Category()); + } + + template + basic_string& replace(iterator __first, iterator __last, + _InputIter __f, _InputIter __l, input_iterator_tag); + + template + basic_string& replace(iterator __first, iterator __last, + _ForwardIter __f, _ForwardIter __l, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: // Other modifier member functions. + + size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { + if (__pos > size()) + _M_throw_out_of_range(); + const size_type __len = min(__n, size() - __pos); + _Traits::copy(__s, _M_start + __pos, __len); + return __len; + } + + void swap(basic_string& __s) { + __STD::swap(_M_start, __s._M_start); + __STD::swap(_M_finish, __s._M_finish); + __STD::swap(_M_end_of_storage, __s._M_end_of_storage); + } + +public: // Conversion to C string. + + const _CharT* c_str() const { return _M_start; } + const _CharT* data() const { return _M_start; } + +public: // find. + + size_type find(const basic_string& __s, size_type __pos = 0) const + { return find(__s.begin(), __pos, __s.size()); } + + size_type find(const _CharT* __s, size_type __pos = 0) const + { return find(__s, __pos, _Traits::length(__s)); } + + size_type find(const _CharT* __s, size_type __pos, size_type __n) const; + size_type find(_CharT __c, size_type __pos = 0) const; + +public: // rfind. + + size_type rfind(const basic_string& __s, size_type __pos = npos) const + { return rfind(__s.begin(), __pos, __s.size()); } + + size_type rfind(const _CharT* __s, size_type __pos = npos) const + { return rfind(__s, __pos, _Traits::length(__s)); } + + size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const; + size_type rfind(_CharT __c, size_type __pos = npos) const; + +public: // find_first_of + + size_type find_first_of(const basic_string& __s, size_type __pos = 0) const + { return find_first_of(__s.begin(), __pos, __s.size()); } + + size_type find_first_of(const _CharT* __s, size_type __pos = 0) const + { return find_first_of(__s, __pos, _Traits::length(__s)); } + + size_type find_first_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + size_type find_first_of(_CharT __c, size_type __pos = 0) const + { return find(__c, __pos); } + +public: // find_last_of + + size_type find_last_of(const basic_string& __s, + size_type __pos = npos) const + { return find_last_of(__s.begin(), __pos, __s.size()); } + + size_type find_last_of(const _CharT* __s, size_type __pos = npos) const + { return find_last_of(__s, __pos, _Traits::length(__s)); } + + size_type find_last_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + size_type find_last_of(_CharT __c, size_type __pos = npos) const { + return rfind(__c, __pos); + } + +public: // find_first_not_of + + size_type find_first_not_of(const basic_string& __s, + size_type __pos = 0) const + { return find_first_not_of(__s.begin(), __pos, __s.size()); } + + size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { return find_first_not_of(__s, __pos, _Traits::length(__s)); } + + size_type find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; + +public: // find_last_not_of + + size_type find_last_not_of(const basic_string& __s, + size_type __pos = npos) const + { return find_last_not_of(__s.begin(), __pos, __s.size()); } + + size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { return find_last_not_of(__s, __pos, _Traits::length(__s)); } + + size_type find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + size_type find_last_not_of(_CharT __c, size_type __pos = npos) const; + +public: // Substring. + + basic_string substr(size_type __pos = 0, size_type __n = npos) const { + if (__pos > size()) + _M_throw_out_of_range(); + return basic_string(_M_start + __pos, + _M_start + __pos + min(__n, size() - __pos)); + } + +public: // Compare + + int compare(const basic_string& __s) const + { return _M_compare(_M_start, _M_finish, __s._M_start, __s._M_finish); } + + int compare(size_type __pos1, size_type __n1, + const basic_string& __s) const { + if (__pos1 > size()) + _M_throw_out_of_range(); + return _M_compare(_M_start + __pos1, + _M_start + __pos1 + min(__n1, size() - __pos1), + __s._M_start, __s._M_finish); + } + + int compare(size_type __pos1, size_type __n1, + const basic_string& __s, + size_type __pos2, size_type __n2) const { + if (__pos1 > size() || __pos2 > __s.size()) + _M_throw_out_of_range(); + return _M_compare(_M_start + __pos1, + _M_start + __pos1 + min(__n1, size() - __pos1), + __s._M_start + __pos2, + __s._M_start + __pos2 + min(__n2, size() - __pos2)); + } + + int compare(const _CharT* __s) const { + return _M_compare(_M_start, _M_finish, __s, __s + _Traits::length(__s)); + } + + int compare(size_type __pos1, size_type __n1, const _CharT* __s) const { + if (__pos1 > size()) + _M_throw_out_of_range(); + return _M_compare(_M_start + __pos1, + _M_start + __pos1 + min(__n1, size() - __pos1), + __s, __s + _Traits::length(__s)); + } + + int compare(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2) const { + if (__pos1 > size()) + _M_throw_out_of_range(); + return _M_compare(_M_start + __pos1, + _M_start + __pos1 + min(__n1, size() - __pos1), + __s, __s + __n2); + } + +public: // Helper function for compare. + static int _M_compare(const _CharT* __f1, const _CharT* __l1, + const _CharT* __f2, const _CharT* __l2) { + const ptrdiff_t __n1 = __l1 - __f1; + const ptrdiff_t __n2 = __l2 - __f2; + const int cmp = _Traits::compare(__f1, __f2, min(__n1, __n2)); + return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0)); + } +}; + + + +// ------------------------------------------------------------ +// Non-inline declarations. + +template +const basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc>::npos + = (basic_string<_CharT,_Traits,_Alloc>::size_type) -1; + +// Change the string's capacity so that it is large enough to hold +// at least __res_arg elements, plus the terminating null. Note that, +// if __res_arg < capacity(), this member function may actually decrease +// the string's capacity. +template +void basic_string<_CharT,_Traits,_Alloc>::reserve(size_type __res_arg) { + if (__res_arg > max_size()) + _M_throw_length_error(); + + size_type __n = max(__res_arg, size()) + 1; + pointer __new_start = _M_allocate(__n); + pointer __new_finish = __new_start; + + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start); + _M_construct_null(__new_finish); + } + __STL_UNWIND((destroy(__new_start, __new_finish), + _M_deallocate(__new_start, __n))); + + destroy(_M_start, _M_finish + 1); + _M_deallocate_block(); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __n; +} + +template +basic_string<_CharT,_Traits,_Alloc>& +basic_string<_CharT,_Traits,_Alloc>::append(size_type __n, _CharT __c) { + if (__n > max_size() || size() > max_size() - __n) + _M_throw_length_error(); + if (size() + __n > capacity()) + reserve(size() + max(size(), __n)); + if (__n > 0) { + uninitialized_fill_n(_M_finish + 1, __n - 1, __c); + __STL_TRY { + _M_construct_null(_M_finish + __n); + } + __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n)); + _Traits::assign(*_M_finish, __c); + _M_finish += __n; + } + return *this; +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +basic_string<_Tp, _Traits, _Alloc>& +basic_string<_Tp, _Traits, _Alloc>::append(_InputIterator __first, + _InputIterator __last, + input_iterator_tag) { + for ( ; __first != __last ; ++__first) + push_back(*__first); + return *this; +} + +template +template +basic_string<_Tp, _Traits, _Alloc>& +basic_string<_Tp, _Traits, _Alloc>::append(_ForwardIter __first, + _ForwardIter __last, + forward_iterator_tag) { + if (__first != __last) { + const size_type __old_size = size(); + difference_type __n = 0; + distance(__first, __last, __n); + if (static_cast(__n) > max_size() || + __old_size > max_size() - static_cast(__n)) + _M_throw_length_error(); + if (__old_size + static_cast(__n) > capacity()) { + const size_type __len = __old_size + + max(__old_size, static_cast(__n)) + 1; + pointer __new_start = _M_allocate(__len); + pointer __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + _M_construct_null(__new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish + 1); + _M_deallocate_block(); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + else { + _ForwardIter __f1 = __first; + ++__f1; + uninitialized_copy(__f1, __last, _M_finish + 1); + __STL_TRY { + _M_construct_null(_M_finish + __n); + } + __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n)); + _Traits::assign(*_M_finish, *__first); + _M_finish += __n; + } + } + return *this; +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +basic_string<_Tp, _Traits, _Alloc>& +basic_string<_Tp, _Traits, _Alloc>::append(const _Tp* __first, + const _Tp* __last) +{ + if (__first != __last) { + const size_type __old_size = size(); + ptrdiff_t __n = __last - __first; + if (__n > max_size() || __old_size > max_size() - __n) + _M_throw_length_error(); + if (__old_size + __n > capacity()) { + const size_type __len = __old_size + max(__old_size, (size_t) __n) + 1; + pointer __new_start = _M_allocate(__len); + pointer __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + _M_construct_null(__new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish + 1); + _M_deallocate_block(); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + else { + const _Tp* __f1 = __first; + ++__f1; + uninitialized_copy(__f1, __last, _M_finish + 1); + __STL_TRY { + _M_construct_null(_M_finish + __n); + } + __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n)); + _Traits::assign(*_M_finish, *__first); + _M_finish += __n; + } + } + return *this; +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +basic_string<_CharT,_Traits,_Alloc>& +basic_string<_CharT,_Traits,_Alloc>::assign(size_type __n, _CharT __c) { + if (__n <= size()) { + _Traits::assign(_M_start, __n, __c); + erase(_M_start + __n, _M_finish); + } + else { + _Traits::assign(_M_start, size(), __c); + append(__n - size(), __c); + } + return *this; +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc> + ::_M_assign_dispatch(_InputIter __f, _InputIter __l, __false_type) +{ + pointer __cur = _M_start; + while (__f != __l && __cur != _M_finish) { + _Traits::assign(*__cur, *__f); + ++__f; + ++__cur; + } + if (__f == __l) + erase(__cur, _M_finish); + else + append(__f, __l); + return *this; +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +basic_string<_CharT,_Traits,_Alloc>& +basic_string<_CharT,_Traits,_Alloc>::assign(const _CharT* __f, + const _CharT* __l) +{ + const ptrdiff_t __n = __l - __f; + if (static_cast(__n) <= size()) { + _Traits::copy(_M_start, __f, __n); + erase(_M_start + __n, _M_finish); + } + else { + _Traits::copy(_M_start, __f, size()); + append(__f + size(), __l); + } + return *this; +} + +template +basic_string<_CharT,_Traits,_Alloc>::iterator +basic_string<_CharT,_Traits,_Alloc> + ::_M_insert_aux(basic_string<_CharT,_Traits,_Alloc>::iterator __p, + _CharT __c) +{ + iterator __new_pos = __p; + if (_M_finish + 1 < _M_end_of_storage) { + _M_construct_null(_M_finish + 1); + _Traits::move(__p + 1, __p, _M_finish - __p); + _Traits::assign(*__p, __c); + ++_M_finish; + } + else { + const size_type __old_len = size(); + const size_type __len = __old_len + + max(__old_len, static_cast(1)) + 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_pos = uninitialized_copy(_M_start, __p, __new_start); + construct(__new_pos, __c); + __new_finish = __new_pos + 1; + __new_finish = uninitialized_copy(__p, _M_finish, __new_finish); + _M_construct_null(__new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish + 1); + _M_deallocate_block(); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + return __new_pos; +} + +template +void basic_string<_CharT,_Traits,_Alloc> + ::insert(basic_string<_CharT,_Traits,_Alloc>::iterator __position, + size_t __n, _CharT __c) +{ + if (__n != 0) { + if (size_type(_M_end_of_storage - _M_finish) >= __n + 1) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after >= __n) { + uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1, + _M_finish + 1); + _M_finish += __n; + _Traits::move(__position + __n, + __position, (__elems_after - __n) + 1); + _Traits::assign(__position, __n, __c); + } + else { + uninitialized_fill_n(_M_finish + 1, __n - __elems_after - 1, __c); + _M_finish += __n - __elems_after; + __STL_TRY { + uninitialized_copy(__position, __old_finish + 1, _M_finish); + _M_finish += __elems_after; + } + __STL_UNWIND((destroy(__old_finish + 1, _M_finish), + _M_finish = __old_finish)); + _Traits::assign(__position, __elems_after + 1, __c); + } + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n) + 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_fill_n(__new_finish, __n, __c); + __new_finish = uninitialized_copy(__position, _M_finish, + __new_finish); + _M_construct_null(__new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish + 1); + _M_deallocate_block(); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void basic_string<_Tp, _Traits, _Alloc>::insert(iterator __p, + _InputIter __first, + _InputIter __last, + input_iterator_tag) +{ + for ( ; __first != __last; ++__first) { + __p = insert(__p, *__first); + ++__p; + } +} + +template +template +void +basic_string<_CharT,_Traits,_Alloc>::insert(iterator __position, + _ForwardIter __first, + _ForwardIter __last, + forward_iterator_tag) +{ + if (__first != __last) { + difference_type __n = 0; + distance(__first, __last, __n); + if (_M_end_of_storage - _M_finish >= __n + 1) { + const difference_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after >= __n) { + uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1, + _M_finish + 1); + _M_finish += __n; + _Traits::move(__position + __n, + __position, (__elems_after - __n) + 1); + _M_copy(__first, __last, __position); + } + else { + _ForwardIter __mid = __first; + advance(__mid, __elems_after + 1); + uninitialized_copy(__mid, __last, _M_finish + 1); + _M_finish += __n - __elems_after; + __STL_TRY { + uninitialized_copy(__position, __old_finish + 1, _M_finish); + _M_finish += __elems_after; + } + __STL_UNWIND((destroy(__old_finish + 1, _M_finish), + _M_finish = __old_finish)); + _M_copy(__first, __mid, __position); + } + } + else { + const size_type __old_size = size(); + const size_type __len + = __old_size + max(__old_size, static_cast(__n)) + 1; + pointer __new_start = _M_allocate(__len); + pointer __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + _M_construct_null(__new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish + 1); + _M_deallocate_block(); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +basic_string<_CharT,_Traits,_Alloc>::insert(iterator __position, + const _CharT* __first, + const _CharT* __last) +{ + if (__first != __last) { + const ptrdiff_t __n = __last - __first; + if (_M_end_of_storage - _M_finish >= __n + 1) { + const ptrdiff_t __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after >= __n) { + uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1, + _M_finish + 1); + _M_finish += __n; + _Traits::move(__position + __n, + __position, (__elems_after - __n) + 1); + _M_copy(__first, __last, __position); + } + else { + const _CharT* __mid = __first; + advance(__mid, __elems_after + 1); + uninitialized_copy(__mid, __last, _M_finish + 1); + _M_finish += __n - __elems_after; + __STL_TRY { + uninitialized_copy(__position, __old_finish + 1, _M_finish); + _M_finish += __elems_after; + } + __STL_UNWIND((destroy(__old_finish + 1, _M_finish), + _M_finish = __old_finish)); + _M_copy(__first, __mid, __position); + } + } + else { + const size_type __old_size = size(); + const size_type __len + = __old_size + max(__old_size, static_cast(__n)) + 1; + pointer __new_start = _M_allocate(__len); + pointer __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + _M_construct_null(__new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish + 1); + _M_deallocate_block(); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +basic_string<_CharT,_Traits,_Alloc>& +basic_string<_CharT,_Traits,_Alloc> + ::replace(iterator __first, iterator __last, size_type __n, _CharT __c) +{ + const size_type __len = static_cast(__last - __first); + if (__len >= __n) { + _Traits::assign(__first, __n, __c); + erase(__first + __n, __last); + } + else { + _Traits::assign(__first, __len, __c); + insert(__last, __n - __len, __c); + } + return *this; +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +basic_string<_CharT,_Traits,_Alloc>& +basic_string<_CharT,_Traits,_Alloc> + ::replace(iterator __first, iterator __last, _InputIter __f, _InputIter __l, + input_iterator_tag) +{ + for ( ; __first != __last && __f != __l; ++__first, ++__f) + _Traits::assign(*__first, *__f); + + if (__f == __l) + erase(__first, __last); + else + insert(__last, __f, __l); + return *this; +} + +template +template +basic_string<_CharT,_Traits,_Alloc>& +basic_string<_CharT,_Traits,_Alloc> + ::replace(iterator __first, iterator __last, + _ForwardIter __f, _ForwardIter __l, + forward_iterator_tag) +{ + difference_type __n = 0; + distance(__f, __l, __n); + const difference_type __len = __last - __first; + if (__len >= __n) { + _M_copy(__f, __l, __first); + erase(__first + __n, __last); + } + else { + _ForwardIter __m = __f; + advance(__m, __len); + _M_copy(__f, __m, __first); + insert(__last, __m, __l); + } + return *this; +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +basic_string<_CharT,_Traits,_Alloc>& +basic_string<_CharT,_Traits,_Alloc> + ::replace(iterator __first, iterator __last, + const _CharT* __f, const _CharT* __l) +{ + const ptrdiff_t __n = __l - __f; + const difference_type __len = __last - __first; + if (__len >= __n) { + _M_copy(__f, __l, __first); + erase(__first + __n, __last); + } + else { + const _CharT* __m = __f + __len; + _M_copy(__f, __m, __first); + insert(__last, __m, __l); + } + return *this; +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::find(const _CharT* __s, size_type __pos, size_type __n) const +{ + if (__pos + __n > size()) + return npos; + else { + const const_iterator __result = + search(_M_start + __pos, _M_finish, + __s, __s + __n, _Eq_traits<_Traits>()); + return __result != _M_finish ? __result - begin() : npos; + } +} + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::find(_CharT __c, size_type __pos) const +{ + if (__pos >= size()) + return npos; + else { + const const_iterator __result = + find_if(_M_start + __pos, _M_finish, + bind2nd(_Eq_traits<_Traits>(), __c)); + return __result != _M_finish ? __result - begin() : npos; + } +} + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::rfind(const _CharT* __s, size_type __pos, size_type __n) const +{ + const size_t __len = size(); + + if (__n > __len) + return npos; + else if (__n == 0) + return min(__len, __pos); + else { + const const_iterator __last = begin() + min(__len - __n, __pos) + __n; + const const_iterator __result = find_end(begin(), __last, + __s, __s + __n, + _Eq_traits<_Traits>()); + return __result != __last ? __result - begin() : npos; + } +} + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::rfind(_CharT __c, size_type __pos) const +{ + const size_type __len = size(); + + if (__len < 1) + return npos; + else { + const const_iterator __last = begin() + min(__len - 1, __pos) + 1; + const_reverse_iterator __rresult = + find_if(const_reverse_iterator(__last), rend(), + bind2nd(_Eq_traits<_Traits>(), __c)); + return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos; + } +} + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::find_first_of(const _CharT* __s, size_type __pos, size_type __n) const +{ + if (__pos >= size()) + return npos; + else { + const_iterator __result = __STD::find_first_of(begin() + __pos, end(), + __s, __s + __n, + _Eq_traits<_Traits>()); + return __result != _M_finish ? __result - begin() : npos; + } +} + + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::find_last_of(const _CharT* __s, size_type __pos, size_type __n) const +{ + const size_type __len = size(); + + if (__len < 1) + return npos; + else { + const const_iterator __last = _M_start + min(__len - 1, __pos) + 1; + const const_reverse_iterator __rresult = + __STD::find_first_of(const_reverse_iterator(__last), rend(), + __s, __s + __n, + _Eq_traits<_Traits>()); + return __rresult != rend() ? (__rresult.base() - 1) - _M_start : npos; + } +} + + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const +{ + if (__pos > size()) + return npos; + else { + const_iterator __result = find_if(_M_start + __pos, _M_finish, + _Not_within_traits<_Traits>(__s, __s + __n)); + return __result != _M_finish ? __result - _M_start : npos; + } +} + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::find_first_not_of(_CharT __c, size_type __pos) const +{ + if (__pos > size()) + return npos; + else { + const_iterator __result + = find_if(begin() + __pos, end(), + not1(bind2nd(_Eq_traits<_Traits>(), __c))); + return __result != _M_finish ? __result - begin() : npos; + } +} + +template +basic_string<_CharT,_Traits,_Alloc>::size_type +basic_string<_CharT,_Traits,_Alloc> + ::find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const +{ + + const size_type __len = size(); + + if (__len < 1) + return npos; + else { + const const_iterator __last = begin() + min(__len - 1, __pos) + 1; + const const_reverse_iterator __rresult = + find_if(const_reverse_iterator(__last), rend(), + _Not_within_traits<_Traits>(__s, __s + __n)); + return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos; + } +} + +template +basic_string<_Tp, _Traits, _Alloc>::size_type +basic_string<_Tp, _Traits, _Alloc> + ::find_last_not_of(_Tp __c, size_type __pos) const +{ + const size_type __len = size(); + + if (__len < 1) + return npos; + else { + const const_iterator __last = begin() + min(__len - 1, __pos) + 1; + const_reverse_iterator __rresult = + find_if(const_reverse_iterator(__last), rend(), + not1(bind2nd(_Eq_traits<_Traits>(), __c))); + return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos; + } +} + +// ------------------------------------------------------------ +// Non-member functions. + +// Operator+ + +template +inline basic_string<_CharT,_Traits,_Alloc> +operator+(const basic_string<_CharT,_Traits,_Alloc>& __x, + const basic_string<_CharT,_Traits,_Alloc>& __y) +{ + typedef basic_string<_CharT,_Traits,_Alloc> _Str; + typedef typename _Str::_Reserve_t _Reserve_t; + _Reserve_t __reserve; + _Str __result(__reserve, __x.size() + __y.size(), __x.get_allocator()); + __result.append(__x); + __result.append(__y); + return __result; +} + +template +inline basic_string<_CharT,_Traits,_Alloc> +operator+(const _CharT* __s, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + typedef basic_string<_CharT,_Traits,_Alloc> _Str; + typedef typename _Str::_Reserve_t _Reserve_t; + _Reserve_t __reserve; + const size_t __n = _Traits::length(__s); + _Str __result(__reserve, __n + __y.size()); + __result.append(__s, __s + __n); + __result.append(__y); + return __result; +} + +template +inline basic_string<_CharT,_Traits,_Alloc> +operator+(_CharT __c, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + typedef basic_string<_CharT,_Traits,_Alloc> _Str; + typedef typename _Str::_Reserve_t _Reserve_t; + _Reserve_t __reserve; + _Str __result(__reserve, 1 + __y.size()); + __result.push_back(__c); + __result.append(__y); + return __result; +} + +template +inline basic_string<_CharT,_Traits,_Alloc> +operator+(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT* __s) { + typedef basic_string<_CharT,_Traits,_Alloc> _Str; + typedef typename _Str::_Reserve_t _Reserve_t; + _Reserve_t __reserve; + const size_t __n = _Traits::length(__s); + _Str __result(__reserve, __x.size() + __n, __x.get_allocator()); + __result.append(__x); + __result.append(__s, __s + __n); + return __result; +} + +template +inline basic_string<_CharT,_Traits,_Alloc> +operator+(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT __c) { + typedef basic_string<_CharT,_Traits,_Alloc> _Str; + typedef typename _Str::_Reserve_t _Reserve_t; + _Reserve_t __reserve; + _Str __result(__reserve, __x.size() + 1, __x.get_allocator()); + __result.append(__x); + __result.push_back(__c); + return __result; +} + +// Operator== and operator!= + +template +inline bool +operator==(const basic_string<_CharT,_Traits,_Alloc>& __x, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return __x.size() == __y.size() && + _Traits::compare(__x.data(), __y.data(), __x.size()) == 0; +} + +template +inline bool +operator==(const _CharT* __s, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + size_t __n = _Traits::length(__s); + return __n == __y.size() && _Traits::compare(__s, __y.data(), __n) == 0; +} + +template +inline bool +operator==(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT* __s) { + size_t __n = _Traits::length(__s); + return __x.size() == __n && _Traits::compare(__x.data(), __s, __n) == 0; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool +operator!=(const _CharT* __s, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return !(__s == __y); +} + +template +inline bool +operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT* __s) { + return !(__x == __s); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Operator< (and also >, <=, and >=). + +template +inline bool +operator<(const basic_string<_CharT,_Traits,_Alloc>& __x, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return basic_string<_CharT,_Traits,_Alloc> + ::_M_compare(__x.begin(), __x.end(), __y.begin(), __y.end()) < 0; +} + +template +inline bool +operator<(const _CharT* __s, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + size_t __n = _Traits::length(__s); + return basic_string<_CharT,_Traits,_Alloc> + ::_M_compare(__s, __s + __n, __y.begin(), __y.end()) < 0; +} + +template +inline bool +operator<(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT* __s) { + size_t __n = _Traits::length(__s); + return basic_string<_CharT,_Traits,_Alloc> + ::_M_compare(__x.begin(), __x.end(), __s, __s + __n) < 0; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline bool +operator>(const basic_string<_CharT,_Traits,_Alloc>& __x, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool +operator>(const _CharT* __s, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return __y < __s; +} + +template +inline bool +operator>(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT* __s) { + return __s < __x; +} + +template +inline bool +operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool +operator<=(const _CharT* __s, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return !(__y < __s); +} + +template +inline bool +operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT* __s) { + return !(__s < __x); +} + +template +inline bool +operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline bool +operator>=(const _CharT* __s, + const basic_string<_CharT,_Traits,_Alloc>& __y) { + return !(__s < __y); +} + +template +inline bool +operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x, + const _CharT* __s) { + return !(__x < __s); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Swap. + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(basic_string<_CharT,_Traits,_Alloc>& __x, + basic_string<_CharT,_Traits,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// I/O. + +#ifndef __STL_USE_NEW_IOSTREAMS +__STL_END_NAMESPACE +#include +__STL_BEGIN_NAMESPACE +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#ifdef __STL_USE_NEW_IOSTREAMS + +template +inline bool +__sgi_string_fill(basic_ostream<_CharT, _Traits>& __os, + basic_streambuf<_CharT, _Traits>* __buf, + size_t __n) +{ + _CharT __f = __os.fill(); + size_t __i; + bool __ok = true; + + for (__i = 0; __i < __n; __i++) + __ok = __ok && !_Traits::eq_int_type(__buf->sputc(__f), _Traits::eof()); + return __ok; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT,_Traits,_Alloc>& __s) +{ + typename basic_ostream<_CharT, _Traits>::sentry __sentry(__os); + bool __ok = false; + + if (__sentry) { + __ok = true; + size_t __n = __s.size(); + size_t __pad_len = 0; + const bool __left = (__os.flags() & ios::left) != 0; + const size_t __w = __os.width(0); + basic_streambuf<_CharT, _Traits>* __buf = __os.rdbuf(); + + if (__w != 0 && __n < __w) + __pad_len = __w - __n; + + if (!__left) + __ok = __sgi_string_fill(__os, __buf, __pad_len); + + __ok = __ok && + __buf->sputn(__s.data(), streamsize(__n)) == streamsize(__n); + + if (__left) + __ok = __ok && __sgi_string_fill(__os, __buf, __pad_len); + } + + if (!__ok) + __os.setstate(ios_base::failbit); + + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT,_Traits,_Alloc>& __s) +{ + typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); + + if (__sentry) { + basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); + const ctype<_CharT>& __ctype = use_facet >(__is.getloc()); + + __s.clear(); + size_t __n = __is.width(0); + if (__n == 0) + __n = static_cast(-1); + else + __s.reserve(__n); + + + while (__n-- > 0) { + typename _Traits::int_type __c1 = __buf->sbumpc(); + if (_Traits::eq_int_type(__c1, _Traits::eof())) { + __is.setstate(ios_base::eofbit); + break; + } + else { + _CharT __c = _Traits::to_char_type(__c1); + + if (__ctype.is(ctype<_CharT>::space, __c)) { + if (_Traits::eq_int_type(__buf->sputbackc(__c), _Traits::eof())) + __is.setstate(ios_base::failbit); + break; + } + else + __s.push_back(__c); + } + } + + // If we have read no characters, then set failbit. + if (__s.size() == 0) + __is.setstate(ios_base::failbit); + } + else + __is.setstate(ios_base::failbit); + + return __is; +} + +template +basic_istream<_CharT, _Traits>& +getline(istream& __is, + basic_string<_CharT,_Traits,_Alloc>& __s, + _CharT __delim) +{ + size_t __nread = 0; + typename basic_istream<_CharT, _Traits>::sentry __sentry(__is, true); + if (__sentry) { + basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); + __s.clear(); + + int __c1; + while (__nread < __s.max_size()) { + int __c1 = __buf->sbumpc(); + if (_Traits::eq_int_type(__c1, _Traits::eof())) { + __is.setstate(ios_base::eofbit); + break; + } + else { + ++__nread; + _CharT __c = _Traits::to_char_type(__c1); + if (!_Traits::eq(__c, __delim)) + __s.push_back(__c); + else + break; // Character is extracted but not appended. + } + } + } + if (__nread == 0 || __nread >= __s.max_size()) + __is.setstate(ios_base::failbit); + + return __is; +} + +template +inline basic_istream<_CharT, _Traits>& +getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT,_Traits,_Alloc>& __s) +{ + return getline(__is, __s, '\n'); +} + +#else /* __STL_USE_NEW_IOSTREAMS */ + +inline void __sgi_string_fill(ostream& __os, streambuf* __buf, size_t __n) +{ + char __f = __os.fill(); + size_t __i; + + for (__i = 0; __i < __n; __i++) __buf->sputc(__f); +} + +template +ostream& operator<<(ostream& __os, + const basic_string<_CharT,_Traits,_Alloc>& __s) +{ + streambuf* __buf = __os.rdbuf(); + if (__buf) { + size_t __n = __s.size(); + size_t __pad_len = 0; + const bool __left = (__os.flags() & ios::left) != 0; + const size_t __w = __os.width(); + + if (__w > 0) { + __n = min(__w, __n); + __pad_len = __w - __n; + } + + if (!__left) + __sgi_string_fill(__os, __buf, __pad_len); + + const size_t __nwritten = __buf->sputn(__s.data(), __n); + + if (__left) + __sgi_string_fill(__os, __buf, __pad_len); + + if (__nwritten != __n) + __os.clear(__os.rdstate() | ios::failbit); + + __os.width(0); + } + else + __os.clear(__os.rdstate() | ios::badbit); + + return __os; +} + +template +istream& operator>>(istream& __is, basic_string<_CharT,_Traits,_Alloc>& __s) +{ + if (!__is) + return __is; + + streambuf* __buf = __is.rdbuf(); + if (__buf) { + +#ifdef __USLC__ +/* Jochen Schlick '1999 - operator >> modified. Work-around to get the + * output buffer flushed (necessary when using + * "cout" (without endl or flushing) followed by + * "cin >>" ...) + */ + if (__is.flags() & ios::skipws) { + _CharT __c; + do + __is.get(__c); + while (__is && isspace(__c)); + if (__is) + __is.putback(__c); + } +#else + if (__is.flags() & ios::skipws) { + int __c; + do { + __c = __buf->sbumpc(); + } + while (__c != EOF && isspace((unsigned char)__c)); + + if (__c == EOF) { + __is.clear(__is.rdstate() | ios::eofbit | ios::failbit); + } + else { + if (__buf->sputbackc(__c) == EOF) + __is.clear(__is.rdstate() | ios::failbit); + } + } +#endif + + // If we arrive at end of file (or fail for some other reason) while + // still discarding whitespace, then we don't try to read the string. + if (__is) { + __s.clear(); + + size_t __n = __is.width(); + if (__n == 0) + __n = static_cast(-1); + else + __s.reserve(__n); + + while (__n-- > 0) { + int __c1 = __buf->sbumpc(); + if (__c1 == EOF) { + __is.clear(__is.rdstate() | ios::eofbit); + break; + } + else { + _CharT __c = _Traits::to_char_type(__c1); + + if (isspace((unsigned char) __c)) { + if (__buf->sputbackc(__c) == EOF) + __is.clear(__is.rdstate() | ios::failbit); + break; + } + else + __s.push_back(__c); + } + } + + // If we have read no characters, then set failbit. + if (__s.size() == 0) + __is.clear(__is.rdstate() | ios::failbit); + } + + __is.width(0); + } + else // We have no streambuf. + __is.clear(__is.rdstate() | ios::badbit); + + return __is; +} + +template +istream& getline(istream& __is, + basic_string<_CharT,_Traits,_Alloc>& __s, + _CharT __delim) +{ + streambuf* __buf = __is.rdbuf(); + if (__buf) { + size_t __nread = 0; + if (__is) { + __s.clear(); + + while (__nread < __s.max_size()) { + int __c1 = __buf->sbumpc(); + if (__c1 == EOF) { + __is.clear(__is.rdstate() | ios::eofbit); + break; + } + else { + ++__nread; + _CharT __c = _Traits::to_char_type(__c1); + if (!_Traits::eq(__c, __delim)) + __s.push_back(__c); + else + break; // Character is extracted but not appended. + } + } + } + + if (__nread == 0 || __nread >= __s.max_size()) + __is.clear(__is.rdstate() | ios::failbit); + } + else + __is.clear(__is.rdstate() | ios::badbit); + + return __is; +} + +template +inline istream& +getline(istream& __is, basic_string<_CharT,_Traits,_Alloc>& __s) +{ + return getline(__is, __s, '\n'); +} + +#endif /* __STL_USE_NEW_IOSTREAMS */ + +template +void _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s, + _CharT* __buf, + size_t __n) +{ + if (__n > 0) { + __n = min(__n - 1, __s.size()); + copy(__s.begin(), __s.begin() + __n, __buf); + _Traits::assign(__buf[__n], + basic_string<_CharT,_Traits,_Alloc>::_M_null()); + } +} + +inline const char* __get_c_string(const string& __s) { return __s.c_str(); } + +// ------------------------------------------------------------ +// Typedefs + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#include + +__STL_BEGIN_NAMESPACE + +template +size_t __stl_string_hash(const basic_string<_CharT,_Traits,_Alloc>& __s) { + unsigned long __h = 0; + for (basic_string<_CharT,_Traits,_Alloc>::const_iterator __i = __s.begin(); + __i != __s.end(); + ++__i) + __h = 5*__h + *__i; + return size_t(__h); +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +struct hash > { + size_t operator()(const basic_string<_CharT,_Traits,_Alloc>& __s) const + { return __stl_string_hash(__s); } +}; + +#else + +__STL_TEMPLATE_NULL struct hash { + size_t operator()(const string& __s) const + { return __stl_string_hash(__s); } +}; + +__STL_TEMPLATE_NULL struct hash { + size_t operator()(const wstring& __s) const + { return __stl_string_hash(__s); } +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_STRING */ + + +// Local Variables: +// mode:C++ +// End: + diff --git a/darkice/tags/darkice-0_2/stl/tempbuf.h b/darkice/tags/darkice-0_2/stl/tempbuf.h new file mode 100644 index 0000000..aa4f289 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/tempbuf.h @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_TEMPBUF_H +#define __SGI_STL_TEMPBUF_H + +#ifndef __SGI_STL_PAIR_H +#include +#endif +#include /* XXX should use */ +#include /* XXX should use */ +#include /* XXX should use */ +#ifndef __TYPE_TRAITS_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_TEMPBUF_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::get_temporary_buffer; +using __STD::return_temporary_buffer; +using __STD::temporary_buffer; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/tree.h b/darkice/tags/darkice-0_2/stl/tree.h new file mode 100644 index 0000000..77c57cb --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/tree.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + */ + +#ifndef __SGI_STL_TREE_H +#define __SGI_STL_TREE_H + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::rb_tree; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_TREE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/type_traits.h b/darkice/tags/darkice-0_2/stl/type_traits.h new file mode 100644 index 0000000..b6a7dfc --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/type_traits.h @@ -0,0 +1,373 @@ +/* + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __TYPE_TRAITS_H +#define __TYPE_TRAITS_H + +#ifndef __STL_CONFIG_H +#include +#endif + +/* +This header file provides a framework for allowing compile time dispatch +based on type attributes. This is useful when writing template code. +For example, when making a copy of an array of an unknown type, it helps +to know if the type has a trivial copy constructor or not, to help decide +if a memcpy can be used. + +The class template __type_traits provides a series of typedefs each of +which is either __true_type or __false_type. The argument to +__type_traits can be any type. The typedefs within this template will +attain their correct values by one of these means: + 1. The general instantiation contain conservative values which work + for all types. + 2. Specializations may be declared to make distinctions between types. + 3. Some compilers (such as the Silicon Graphics N32 and N64 compilers) + will automatically provide the appropriate specializations for all + types. + +EXAMPLE: + +//Copy an array of elements which have non-trivial copy constructors +template void copy(T* source, T* destination, int n, __false_type); +//Copy an array of elements which have trivial copy constructors. Use memcpy. +template void copy(T* source, T* destination, int n, __true_type); + +//Copy an array of any type by using the most efficient copy mechanism +template inline void copy(T* source,T* destination,int n) { + copy(source, destination, n, + typename __type_traits::has_trivial_copy_constructor()); +} +*/ + + +struct __true_type { +}; + +struct __false_type { +}; + +template +struct __type_traits { + typedef __true_type this_dummy_member_must_be_first; + /* Do not remove this member. It informs a compiler which + automatically specializes __type_traits that this + __type_traits template is special. It just makes sure that + things work if an implementation is using a template + called __type_traits for something unrelated. */ + + /* The following restrictions should be observed for the sake of + compilers which automatically produce type specific specializations + of this class: + - You may reorder the members below if you wish + - You may remove any of the members below if you wish + - You must not rename members without making the corresponding + name change in the compiler + - Members you add will be treated like regular members unless + you add the appropriate support in the compiler. */ + + + typedef __false_type has_trivial_default_constructor; + typedef __false_type has_trivial_copy_constructor; + typedef __false_type has_trivial_assignment_operator; + typedef __false_type has_trivial_destructor; + typedef __false_type is_POD_type; +}; + + + +// Provide some specializations. This is harmless for compilers that +// have built-in __types_traits support, and essential for compilers +// that don't. + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_HAS_WCHAR_T */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_LONG_LONG */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +struct __type_traits<_Tp*> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + +// The following could be written in terms of numeric_limits. +// We're doing it separately to reduce the number of dependencies. + +template struct _Is_integer { + typedef __false_type _Integral; +}; + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_HAS_WCHAR_T */ + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_LONG_LONG */ + +#endif /* __TYPE_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/utility b/darkice/tags/darkice-0_2/stl/utility new file mode 100644 index 0000000..df8c224 --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/utility @@ -0,0 +1,38 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_UTILITY +#define __SGI_STL_UTILITY + +#include +#include +#include + +#endif /* __SGI_STL_UTILITY */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/valarray b/darkice/tags/darkice-0_2/stl/valarray new file mode 100644 index 0000000..814197d --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/valarray @@ -0,0 +1,1773 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_VALARRAY +#define __SGI_STL_VALARRAY + +#include +#include +#include +#include +#include +#include + + +__STL_BEGIN_NAMESPACE + +class slice; +class gslice; + +template class valarray; +template class slice_array; +template class gslice_array; +template class mask_array; +template class indirect_array; + +//---------------------------------------------------------------------- +// class valarray + +// Base class to handle memory allocation and deallocation. We can't just +// use vector<>, because vector would be unsuitable as an internal +// representation for valarray. + +template +struct _Valarray_base +{ + _Tp* _M_first; + size_t _M_size; + + _Valarray_base() : _M_first(0), _M_size(0) {} + _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); } + ~_Valarray_base() { _M_deallocate(); } + + void _M_allocate(size_t __n) { + if (__n != 0) { + _M_first = static_cast<_Tp*>(malloc(__n * sizeof(_Tp))); + _M_size = __n; +# if !defined(__STL_NO_BAD_ALLOC) && defined(__STL_USE_EXCEPTIONS) + if (_M_first == 0) { + _M_size = 0; + throw std::bad_alloc(); + } +# endif + } + else { + _M_first = 0; + _M_size = 0; + } + } + + void _M_deallocate() { + free(_M_first); + _M_first = 0; + _M_size = 0; + } +}; + +template +class valarray : private _Valarray_base<_Tp> +{ + friend class gslice; + +public: + typedef _Tp value_type; + + // Basic constructors + valarray() : _Valarray_base<_Tp>() {} + valarray(size_t __n) : _Valarray_base<_Tp>(__n) + { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); } + valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n) + { uninitialized_fill_n(this->_M_first, this->_M_size, __x); } + valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n) + { uninitialized_copy(__p, __p + __n, this->_M_first); } + valarray(const valarray& __x) : _Valarray_base<_Tp>(__x._M_size) { + uninitialized_copy(__x._M_first, __x._M_first + __x._M_size, + this->_M_first); + } + + // Constructors from auxiliary array types + valarray(const slice_array<_Tp>&); + valarray(const gslice_array<_Tp>&); + valarray(const mask_array<_Tp>&); + valarray(const indirect_array<_Tp>&); + + // Destructor + ~valarray() { destroy(this->_M_first, this->_M_first + this->_M_size); } + + // Extension: constructor that doesn't initialize valarray elements to a + // specific value. This is faster for types such as int and double. +private: + void _M_initialize(__true_type) {} + void _M_initialize(__false_type) + { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); } + +public: + struct _NoInit {}; + valarray(size_t __n, _NoInit) : _Valarray_base<_Tp>(__n) { + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Is_Trivial; + _M_initialize(_Is_Trivial()); + } + +public: // Assignment + // Basic assignment. Note that 'x = y' is undefined if x.size() != y.size() + valarray& operator=(const valarray& __x) { + if (this != &__x) + copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first); + return *this; + } + + // Scalar assignment + valarray& operator=(const value_type& __x) { + fill_n(this->_M_first, this->_M_size, __x); + return *this; + } + + // Assignment of auxiliary array types + valarray& operator=(const slice_array<_Tp>&); + valarray& operator=(const gslice_array<_Tp>&); + valarray& operator=(const mask_array<_Tp>&); + valarray& operator=(const indirect_array<_Tp>&); + +public: // Element access + value_type operator[](size_t __n) const { return this->_M_first[__n]; } + value_type& operator[](size_t __n) { return this->_M_first[__n]; } + size_t size() const { return this->_M_size; } + +public: // Subsetting operations with auxiliary type + valarray operator[](slice) const; + slice_array<_Tp> operator[](slice); + valarray operator[](gslice) const; + gslice_array<_Tp> operator[](gslice); + valarray operator[](const valarray&) const; + mask_array<_Tp> operator[](const valarray&); + valarray operator[](const valarray&) const; + indirect_array<_Tp> operator[](const valarray&); + +public: // Unary operators. + valarray operator+() const { return *this; } + + valarray operator-() const { + valarray __tmp(this->size(), _NoInit()); + for (size_t __i = 0; __i < this->size(); ++__i) + __tmp[__i] = -(*this)[__i]; + return __tmp; + } + + valarray operator~() const { + valarray __tmp(this->size(), _NoInit()); + for (size_t __i = 0; __i < this->size(); ++__i) + __tmp[__i] = ~(*this)[__i]; + return __tmp; + } + + valarray operator!() const { + valarray __tmp(this->size(), valarray::_NoInit()); + for (size_t __i = 0; __i < this->size(); ++__i) + __tmp[__i] = !(*this)[__i]; + return __tmp; + } + +public: // Scalar computed assignment. + valarray& operator*= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] *= __x; + return *this; + } + + valarray& operator/= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] /= __x; + return *this; + } + + valarray& operator%= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] %= __x; + return *this; + } + + valarray& operator+= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] += __x; + return *this; + } + + valarray& operator-= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] -= __x; + return *this; + } + + valarray& operator^= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] ^= __x; + return *this; + } + + valarray& operator&= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] &= __x; + return *this; + } + + valarray& operator|= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] |= __x; + return *this; + } + + valarray& operator<<= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] <<= __x; + return *this; + } + + valarray& operator>>= (const value_type& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] >>= __x; + return *this; + } + +public: // Array computed assignment. + valarray& operator*= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] *= __x[__i]; + return *this; + } + + valarray& operator/= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] /= __x[__i]; + return *this; + } + + valarray& operator%= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] %= __x[__i]; + return *this; + } + + valarray& operator+= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] += __x[__i]; + return *this; + } + + valarray& operator-= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] -= __x[__i]; + return *this; + } + + valarray& operator^= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] ^= __x[__i]; + return *this; + } + + valarray& operator&= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] &= __x[__i]; + return *this; + } + + valarray& operator|= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] |= __x[__i]; + return *this; + } + + valarray& operator<<= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] <<= __x[__i]; + return *this; + } + + valarray& operator>>= (const valarray& __x) { + for (size_t __i = 0; __i < this->size(); ++__i) + (*this)[__i] >>= __x[__i]; + return *this; + } + +public: // Other member functions. + + // The result is undefined for zero-length arrays + value_type sum() const { + return accumulate(this->_M_first + 1, this->_M_first + this->_M_size, + (*this)[0]); + } + + // The result is undefined for zero-length arrays + value_type min() const { + return *min_element(this->_M_first + 0, this->_M_first + this->_M_size); + } + + value_type max() const { + return *max_element(this->_M_first + 0, this->_M_first + this->_M_size); + } + + valarray shift(int __n) const; + valarray cshift(int __n) const; + + valarray apply(value_type __f(value_type)) const { + valarray __tmp(this->size()); + transform(this->_M_first, this->_M_first + this->_M_size, __tmp._M_first, + __f); + return __tmp; + } + valarray apply(value_type __f(const value_type&)) const { + valarray __tmp(this->size()); + transform(this->_M_first, this->_M_first + this->_M_size, __tmp._M_first, + __f); + return __tmp; + } + + void resize(size_t __n, value_type __x = value_type()) { + destroy(this->_M_first, this->_M_first + this->_M_size); + this->_Valarray_base<_Tp>::_M_deallocate(); + this->_Valarray_base<_Tp>::_M_allocate(__n); + uninitialized_fill_n(this->_M_first, this->_M_size, __x); + } +}; + +//---------------------------------------------------------------------- +// valarray non-member functions. + +// Binary arithmetic operations between two arrays. Behavior is +// undefined if the two arrays do not have the same length. + +template +inline valarray<_Tp> operator*(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] * __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator/(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] / __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator%(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] % __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator+(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] + __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator-(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] - __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator^(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] ^ __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator&(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] & __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator|(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] | __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator<<(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] << __y[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator>>(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] >> __y[__i]; + return __tmp; +} + +// Binary arithmetic operations between an array and a scalar. + +template +inline valarray<_Tp> operator*(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] * __c; + return __tmp; +} + +template +inline valarray<_Tp> operator*(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c * __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator/(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] / __c; + return __tmp; +} + +template +inline valarray<_Tp> operator/(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c / __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator%(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] % __c; + return __tmp; +} + +template +inline valarray<_Tp> operator%(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c % __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator+(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] + __c; + return __tmp; +} + +template +inline valarray<_Tp> operator+(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c + __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator-(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] - __c; + return __tmp; +} + +template +inline valarray<_Tp> operator-(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c - __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator^(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] ^ __c; + return __tmp; +} + +template +inline valarray<_Tp> operator^(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c ^ __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator&(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] & __c; + return __tmp; +} + +template +inline valarray<_Tp> operator&(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c & __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator|(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] | __c; + return __tmp; +} + +template +inline valarray<_Tp> operator|(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c | __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator<<(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] << __c; + return __tmp; +} + +template +inline valarray<_Tp> operator<<(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c << __x[__i]; + return __tmp; +} + +template +inline valarray<_Tp> operator>>(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] >> __c; + return __tmp; +} + +template +inline valarray<_Tp> operator>>(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c >> __x[__i]; + return __tmp; +} + +// Binary logical operations between two arrays. Behavior is undefined +// if the two arrays have different lengths. Note that operator== does +// not do what you might at first expect. + +template +inline valarray operator==(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] == __y[__i]; + return __tmp; +} + +template +inline valarray operator<(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] < __y[__i]; + return __tmp; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline valarray operator!=(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] != __y[__i]; + return __tmp; +} + +template +inline valarray operator>(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] > __y[__i]; + return __tmp; +} + +template +inline valarray operator<=(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] <= __y[__i]; + return __tmp; +} + +template +inline valarray operator>=(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] >= __y[__i]; + return __tmp; +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline valarray operator&&(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] && __y[__i]; + return __tmp; +} + +template +inline valarray operator||(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] || __y[__i]; + return __tmp; +} + +// Logical operations between an array and a scalar. + +template +inline valarray operator==(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] == __c; + return __tmp; +} + +template +inline valarray operator==(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c == __x[__i]; + return __tmp; +} + +template +inline valarray operator!=(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] != __c; + return __tmp; +} + +template +inline valarray operator!=(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c != __x[__i]; + return __tmp; +} + +template +inline valarray operator<(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] < __c; + return __tmp; +} + +template +inline valarray operator<(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c < __x[__i]; + return __tmp; +} + +template +inline valarray operator>(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] > __c; + return __tmp; +} + +template +inline valarray operator>(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c > __x[__i]; + return __tmp; +} + +template +inline valarray operator<=(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] <= __c; + return __tmp; +} + +template +inline valarray operator<=(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c <= __x[__i]; + return __tmp; +} + +template +inline valarray operator>=(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] >= __c; + return __tmp; +} + +template +inline valarray operator>=(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c >= __x[__i]; + return __tmp; +} + +template +inline valarray operator&&(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] && __c; + return __tmp; +} + +template +inline valarray operator&&(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c && __x[__i]; + return __tmp; +} + +template +inline valarray operator||(const valarray<_Tp>& __x, const _Tp& __c) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __x[__i] || __c; + return __tmp; +} + +template +inline valarray operator||(const _Tp& __c, const valarray<_Tp>& __x) +{ + valarray __tmp(__x.size(), valarray::_NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = __c || __x[__i]; + return __tmp; +} + +// valarray "transcendentals" (the list includes abs and sqrt, which, +// of course, are not transcendental). + +template +inline valarray<_Tp> abs(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = abs(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> acos(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = acos(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> asin(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = asin(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> atan(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = atan(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> atan2(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = atan2(__x[__i], __y[__i]); + return __tmp; +} + +template +inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = atan2(__x[__i], __c); + return __tmp; +} + +template +inline valarray<_Tp> atan2(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = atan2(__c, __x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> cos(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = cos(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> cosh(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = cosh(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> exp(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = exp(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> log(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = log(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> log10(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = log10(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> pow(const valarray<_Tp>& __x, + const valarray<_Tp>& __y) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = pow(__x[__i], __y[__i]); + return __tmp; +} + +template +inline valarray<_Tp> pow(const valarray<_Tp>& __x, const _Tp& __c) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = pow(__x[__i], __c); + return __tmp; +} + +template +inline valarray<_Tp> pow(const _Tp& __c, const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = pow(__c, __x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> sin(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = sin(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> sinh(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = sinh(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> sqrt(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = sqrt(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> tan(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = tan(__x[__i]); + return __tmp; +} + +template +inline valarray<_Tp> tanh(const valarray<_Tp>& __x) { + typedef typename valarray<_Tp>::_NoInit _NoInit; + valarray<_Tp> __tmp(__x.size(), _NoInit()); + for (size_t __i = 0; __i < __x.size(); ++__i) + __tmp[__i] = tanh(__x[__i]); + return __tmp; +} + +//---------------------------------------------------------------------- +// slice and slice_array + +class slice { +public: + slice() : _M_start(0), _M_length(0), _M_stride(0) {} + slice(size_t __start, size_t __length, size_t __stride) + : _M_start(__start), _M_length(__length), _M_stride(__stride) + {} + + size_t start() const { return _M_start; } + size_t size() const { return _M_length; } + size_t stride() const { return _M_stride; } + + +private: + size_t _M_start; + size_t _M_length; + size_t _M_stride; +}; + +template +class slice_array { + friend class valarray<_Tp>; +public: + typedef _Tp value_type; + + void operator=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] = __x[__i]; + } + + void operator*=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] *= __x[__i]; + } + + void operator/=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] /= __x[__i]; + } + + void operator%=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] %= __x[__i]; + } + + void operator+=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] += __x[__i]; + } + + void operator-=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] -= __x[__i]; + } + + void operator^=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] ^= __x[__i]; + } + + void operator&=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] &= __x[__i]; + } + + void operator|=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] |= __x[__i]; + } + + void operator<<=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] <<= __x[__i]; + } + + void operator>>=(const valarray& __x) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] >>= __x[__i]; + } + + void operator=(const value_type& __c) const { + size_t __index = _M_slice.start(); + for (size_t __i = 0; + __i < _M_slice.size(); + ++__i, __index += _M_slice.stride()) + _M_array[__index] = __c; + } + + ~slice_array() {} + +private: + slice_array(const slice& __slice, valarray<_Tp>& __array) + : _M_slice(__slice), _M_array(__array) + {} + + slice _M_slice; + valarray<_Tp>& _M_array; + +private: // Disable assignment and default constructor + slice_array(); +}; + +// valarray member functions dealing with slice and slice_array + +template +inline valarray<_Tp>::valarray(const slice_array<_Tp>& __x) + : _Valarray_base<_Tp>(__x._M_slice.size()) +{ + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Is_Trivial; + _M_initialize(_Is_Trivial()); + *this = __x; +} + +// Behavior is undefined if __x and *this have different sizes +template +valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __x) +{ + size_t __index = __x._M_slice.start(); + for (size_t __i = 0; + __i < __x._M_slice.size(); + ++__i, __index += __x._M_slice.stride()) + (*this)[__i] = __x._M_array[__index]; + return *this; +} + +template +valarray<_Tp> valarray<_Tp>::operator[](slice __slice) const { + valarray<_Tp> __tmp(__slice.size(), _NoInit()); + size_t __index = __slice.start(); + for (size_t __i = 0; + __i < __slice.size(); + ++__i, __index += __slice.stride()) + __tmp[__i] = (*this)[__index]; + return __tmp; +} + +template +inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice) { + return slice_array<_Tp>(__slice, *this); +} + +//---------------------------------------------------------------------- +// gslice and gslice_array + +struct _Gslice_Iter; + +class gslice { + friend struct _Gslice_Iter; +public: + gslice() : _M_start(0), _M_lengths(0), _M_strides(0) {} + gslice(size_t __start, + const valarray& __lengths, const valarray& __strides) + : _M_start(__start), _M_lengths(__lengths), _M_strides(__strides) + {} + + size_t start() const { return _M_start; } + valarray size() const { return _M_lengths; } + valarray stride() const { return _M_strides; } + + // Extension: check for an empty gslice. + bool _M_empty() const { return _M_lengths.size() == 0; } + + // Extension: number of indices this gslice represents. (For a degenerate + // gslice, they're not necessarily all distinct.) + size_t _M_size() const { + return !this->_M_empty() + ? accumulate(_M_lengths._M_first + 1, + _M_lengths._M_first + _M_lengths._M_size, + _M_lengths[0], + multiplies()) + : 0; + } + +private: + size_t _M_start; + valarray _M_lengths; + valarray _M_strides; +}; + +// This is not an STL iterator. It is constructed from a gslice, and it +// steps through the gslice indices in sequence. See 23.3.6 of the C++ +// standard, paragraphs 2-3, for an explanation of the sequence. At +// each step we get two things: the ordinal (i.e. number of steps taken), +// and the one-dimensional index. + +struct _Gslice_Iter { + _Gslice_Iter(const gslice& __gslice) + : _M_step(0), _M_1d_idx(__gslice.start()), + _M_indices(size_t(0), __gslice._M_lengths.size()), + _M_gslice(__gslice) + {} + + bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; } + + bool _M_incr() { + size_t __dim = _M_indices.size() - 1; + ++_M_step; + while (true) { + _M_1d_idx += _M_gslice._M_strides[__dim]; + if (++_M_indices[__dim] != _M_gslice._M_lengths[__dim]) + return true; + else if (__dim != 0) { + _M_1d_idx -= + _M_gslice._M_strides[__dim] * _M_gslice._M_lengths[__dim]; + _M_indices[__dim] = 0; + --__dim; + } + else + return false; + } + } + + size_t _M_step; + size_t _M_1d_idx; + + valarray _M_indices; + const gslice& _M_gslice; +}; + +template +class gslice_array { + friend class valarray<_Tp>; +public: + typedef _Tp value_type; + + void operator= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] = __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator*= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] *= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator/= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] /= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator%= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] %= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator+= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] += __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator-= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] -= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator^= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] ^= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator&= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] &= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator|= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] |= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator<<= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] <<= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator>>= (const valarray& __x) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] >>= __x[__i._M_step]; while(__i._M_incr()); + } + } + + void operator= (const value_type& __c) const { + if (!_M_gslice._M_empty()) { + _Gslice_Iter __i(_M_gslice); + do _M_array[__i._M_1d_idx] = __c; while(__i._M_incr()); + } + } + + ~gslice_array() {} + +private: + gslice_array(gslice __gslice, valarray<_Tp>& __array) + : _M_gslice(__gslice), _M_array(__array) + {} + + gslice _M_gslice; + valarray& _M_array; + +private: // Disable assignment + void operator=(const gslice_array&); +}; + +// valarray member functions dealing with gslice and gslice_array. Note +// that it is illegal (behavior is undefined) to construct a gslice_array +// from a degenerate gslice. + +template +inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __x) + : _Valarray_base<_Tp>(__x._M_gslice._M_size()) +{ + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Is_Trivial; + _M_initialize(_Is_Trivial()); + *this = __x; +} + +// Behavior is undefined if __x and *this have different sizes, or if +// __x was constructed from a degenerate gslice. +template +valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __x) +{ + if (this->size() != 0) { + _Gslice_Iter __i(__x._M_gslice); + do + (*this)[__i._M_step] = __x._M_array[__i._M_1d_idx]; + while(__i._M_incr()); + } + return *this; +} + +template +inline gslice_array<_Tp> valarray<_Tp>::operator[](gslice __slice) { + return gslice_array<_Tp>(__slice, *this); +} + +template +valarray<_Tp> valarray<_Tp>::operator[](gslice __slice) const +{ + valarray __tmp(__slice._M_size(), _NoInit()); + if (__tmp.size() != 0) { + _Gslice_Iter __i(__slice); + do __tmp[__i._M_step] = (*this)[__i._M_1d_idx]; while(__i._M_incr()); + } + return __tmp; +} + +//---------------------------------------------------------------------- +// mask_array + +template +class mask_array { + friend class valarray<_Tp>; +public: + typedef _Tp value_type; + + void operator=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] = __x[__idx++]; + } + + void operator*=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] *= __x[__idx++]; + } + + void operator/=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] /= __x[__idx++]; + } + + void operator%=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] %= __x[__idx++]; + } + + void operator+=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] += __x[__idx++]; + } + + void operator-=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] -= __x[__idx++]; + } + + void operator^=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++]; + } + + void operator&=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] &= __x[__idx++]; + } + + void operator|=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] |= __x[__idx++]; + } + + void operator<<=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++]; + } + + void operator>>=(const valarray& __x) const { + size_t __idx = 0; + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++]; + } + + void operator=(const value_type& __c) const { + for (size_t __i = 0; __i < _M_array.size(); ++__i) + if (_M_mask[__i]) _M_array[__i] = __c; + } + + ~mask_array() {} + + // Extension: number of true values in the mask + size_t _M_num_true() const { + size_t __result = 0; + for (size_t __i = 0; __i < _M_mask.size(); ++__i) + if (_M_mask[__i]) ++__result; + return __result; + } + +private: + mask_array(const valarray& __mask, valarray<_Tp>& __array) + : _M_mask(__mask), _M_array(__array) + {} + + valarray _M_mask; + valarray<_Tp>& _M_array; + +private: // Disable assignment + void operator=(const mask_array&); +}; + +// valarray member functions dealing with mask_array + +template +inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x) + : _Valarray_base<_Tp>(__x._M_num_true()) +{ + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Is_Trivial; + _M_initialize(_Is_Trivial()); + *this = __x; +} + +// Behavior is undefined if __x._M_num_true() != this->size() +template +inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __x) { + size_t __idx = 0; + for (size_t __i = 0; __i < __x._M_array.size(); ++__i) + if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i]; + return *this; +} + +template +inline mask_array<_Tp> valarray<_Tp>::operator[](const valarray& __mask) +{ + return mask_array<_Tp>(__mask, *this); +} + +template +valarray<_Tp> valarray<_Tp>::operator[](const valarray& __mask) const +{ + size_t __size = 0; + { + for (size_t __i = 0; __i < __mask.size(); ++__i) + if (__mask[__i]) ++__size; + } + + valarray __tmp(__size, _NoInit()); + size_t __idx = 0; + { + for (size_t __i = 0; __i < __mask.size(); ++__i) + if (__mask[__i]) __tmp[__idx++] = (*this)[__i]; + } + + return __tmp; +} + +//---------------------------------------------------------------------- +// indirect_array + +template +class indirect_array { + friend class valarray<_Tp>; +public: + typedef _Tp value_type; + + void operator=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] = __x[__i]; + } + + void operator*=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] *= __x[__i]; + } + + void operator/=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] /= __x[__i]; + } + + void operator%=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] %= __x[__i]; + } + + void operator+=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] += __x[__i]; + } + + void operator-=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] -= __x[__i]; + } + + void operator^=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] ^= __x[__i]; + } + + void operator&=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] &= __x[__i]; + } + + void operator|=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] |= __x[__i]; + } + + void operator<<=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] <<= __x[__i]; + } + + void operator>>=(const valarray& __x) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] >>= __x[__i]; + } + + void operator=(const value_type& __c) const { + for (size_t __i = 0; __i < _M_addr.size(); ++__i) + _M_array[_M_addr[__i]] = __c; + } + + ~indirect_array() {} + +private: + indirect_array(const valarray& __addr, valarray<_Tp>& __array) + : _M_addr(__addr), _M_array(__array) + {} + + valarray _M_addr; + valarray<_Tp>& _M_array; + +private: // Disable assignment + void operator=(const indirect_array&); +}; + +// valarray member functions dealing with indirect_array + +template +inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x) + : _Valarray_base<_Tp>(__x._M_addr.size()) +{ + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Is_Trivial; + _M_initialize(_Is_Trivial()); + *this = __x; +} + +template +valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __x) { + for (size_t __i = 0; __i < __x._M_addr.size(); ++__i) + (*this)[__i] = __x._M_array[__x._M_addr[__i]]; + return *this; +} + +template +inline indirect_array<_Tp> +valarray<_Tp>::operator[](const valarray& __addr) +{ + return indirect_array<_Tp>(__addr, *this); +} + +template +valarray<_Tp> +valarray<_Tp>::operator[](const valarray& __addr) const +{ + valarray<_Tp> __tmp(__addr.size(), _NoInit()); + for (size_t __i = 0; __i < __addr.size(); ++__i) + __tmp[__i] = (*this)[__addr[__i]]; + return __tmp; +} + +//---------------------------------------------------------------------- +// Other valarray noninline member functions + +// Shift and cshift + +template +valarray<_Tp> valarray<_Tp>::shift(int __n) const +{ + valarray<_Tp> __tmp(this->size()); + + if (__n >= 0) { + if (__n < this->size()) + copy(this->_M_first + __n, this->_M_first + this->size(), + __tmp._M_first); + } + else { + if (-__n < this->size()) + copy(this->_M_first, this->_M_first + this->size() + __n, + __tmp._M_first - __n); + } + return __tmp; +} + +template +valarray<_Tp> valarray<_Tp>::cshift(int __m) const +{ + valarray<_Tp> __tmp(this->size()); + + // Reduce __m to an equivalent number in the range [0, size()). We + // have to be careful with negative numbers, since the sign of a % b + // is unspecified when a < 0. + long __n = __m; + if (this->size() < numeric_limits::max()) + __n %= long(this->size()); + if (__n < 0) + __n += this->size(); + + copy(this->_M_first, this->_M_first + __n, + __tmp._M_first + (this->size() - __n)); + copy(this->_M_first + __n, this->_M_first + this->size(), + __tmp._M_first); + + return __tmp; +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_VALARRAY */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/vector b/darkice/tags/darkice-0_2/stl/vector new file mode 100644 index 0000000..272f60f --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/vector @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_VECTOR +#define __SGI_STL_VECTOR + +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_VECTOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/stl/vector.h b/darkice/tags/darkice-0_2/stl/vector.h new file mode 100644 index 0000000..f48d4fd --- /dev/null +++ b/darkice/tags/darkice-0_2/stl/vector.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_VECTOR_H +#define __SGI_STL_VECTOR_H + +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::vector; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/darkice/tags/darkice-0_2/update-conf b/darkice/tags/darkice-0_2/update-conf new file mode 100755 index 0000000..6d775f1 --- /dev/null +++ b/darkice/tags/darkice-0_2/update-conf @@ -0,0 +1,7 @@ +#!/bin/sh +# +# Update the automake / autoconf configuration +# + +automake && aclocal && autoconf && ./configure +