/* * @file u_config_ccs5_preinclude.hpp * * @since 30-08-2012 * @author Krzysztof Czaiński */ // Workaround for CCS5's indexer, which defines @p __TI_COMPILER_VERSION to be empty: // Workaround for CCS5's indexer, which defines @p __FILE__ and __LINE__ to be empty: ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// // Boost config.hpp configuration header file ------------------------------// // (C) Copyright John Maddock 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/config for most recent version. // Boost config.hpp policy and rationale documentation has been moved to // http://www.boost.org/libs/config // // CAUTION: This file is intended to be completely stable - // DO NOT MODIFY THIS FILE! // // if we don't have a user config, then use the default location: // include it first: // boost/config/user.hpp ---------------------------------------------------// // (C) Copyright John Maddock 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // Do not check in modified versions of this file, // This file may be customized by the end user, but not by boost. // // Use this file to define a site and compiler specific // configuration policy: // // define this to locate a compiler config file: // #define BOOST_COMPILER_CONFIG // define this to locate a stdlib config file: // #define BOOST_STDLIB_CONFIG // define this to locate a platform config file: // #define BOOST_PLATFORM_CONFIG // define this to disable compiler config, // use if your compiler config has nothing to set: // #define BOOST_NO_COMPILER_CONFIG // define this to disable stdlib config, // use if your stdlib config has nothing to set: // #define BOOST_NO_STDLIB_CONFIG // define this to disable platform config, // use if your platform config has nothing to set: // #define BOOST_NO_PLATFORM_CONFIG // define this to disable all config options, // excluding the user config. Use if your // setup is fully ISO compliant, and has no // useful extensions, or for autoconf generated // setups: // #define BOOST_NO_CONFIG // define this to make the config "optimistic" // about unknown compiler versions. Normally // unknown compiler versions are assumed to have // all the defects of the last known version, however // setting this flag, causes the config to assume // that unknown compiler versions are fully conformant // with the standard: // #define BOOST_STRICT_CONFIG // define this to cause the config to halt compilation // with an #error if it encounters anything unknown -- // either an unknown compiler version or an unknown // compiler/platform/library: // #define BOOST_ASSERT_CONFIG // define if you want to disable threading support, even // when available: // #define BOOST_DISABLE_THREADS // define when you want to disable Win32 specific features // even when available: // #define BOOST_DISABLE_WIN32 // BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any // prefix/suffix headers that normally control things like struct // packing and alignment. // #define BOOST_DISABLE_ABI_HEADERS // BOOST_ABI_PREFIX: A prefix header to include in place of whatever // boost.config would normally select, any replacement should set up // struct packing and alignment options as required. // #define BOOST_ABI_PREFIX my-header-name // BOOST_ABI_SUFFIX: A suffix header to include in place of whatever // boost.config would normally select, any replacement should undo // the effects of the prefix header. // #define BOOST_ABI_SUFFIX my-header-name // BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, // to be linked as dll's rather than static libraries on Microsoft Windows // (this macro is used to turn on __declspec(dllimport) modifiers, so that // the compiler knows which symbols to look for in a dll rather than in a // static library). Note that there may be some libraries that can only // be statically linked (Boost.Test for example) and others which may only // be dynamically linked (Boost.Threads for example), in these cases this // macro has no effect. // #define BOOST_ALL_DYN_LINK // BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll // rather than a static library on Microsoft Windows: replace the WHATEVER // part of the macro name with the name of the library that you want to // dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or // BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) // modifiers, so that the compiler knows which symbols to look for in a dll // rather than in a static library). // Note that there may be some libraries that can only be statically linked // (Boost.Test for example) and others which may only be dynamically linked // (Boost.Threads for example), in these cases this macro is unsupported. // #define BOOST_WHATEVER_DYN_LINK // BOOST_ALL_NO_LIB: Tells the config system not to automatically select // which libraries to link against. // Normally if a compiler supports #pragma lib, then the correct library // build variant will be automatically selected and linked against, // simply by the act of including one of that library's headers. // This macro turns that feature off. // #define BOOST_ALL_NO_LIB // BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically // select which library to link against for library "whatever", // replace WHATEVER in the macro name with the name of the library; // for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. // Normally if a compiler supports #pragma lib, then the correct library // build variant will be automatically selected and linked against, simply // by the act of including one of that library's headers. This macro turns // that feature off. // #define BOOST_WHATEVER_NO_LIB // if we don't have a compiler config set, try and find one: // Boost compiler configuration selection header file // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Martin Wille 2003. // (C) Copyright Guillaume Melquiond 2003. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/ for most recent version. // locate which compiler we are using and define // BOOST_COMPILER_CONFIG as needed: // Texas Instruments compiler, it has to appear before __GNUC__, because it defines __GNUC__=3 // if we have a compiler config, include it now: //--------------------------------------------------------------------------- // String that names the compiler being used //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TI uses the EDG compiler front end to parse C/C++ code. The name // __EDG_VERSION__ is pre-defined by TI compilers, but only in the latest // releases. 303 is what is most commonly used by TI compilers that // do not predefine __EDG_VERSION__. Inherit all the other settings for the // EDG front end from the Boost file already here. //--------------------------------------------------------------------------- // (C) Copyright John Maddock 2001 - 2002. // (C) Copyright Jens Maurer 2001. // (C) Copyright David Abrahams 2002. // (C) Copyright Aleksey Gurtovoy 2002. // (C) Copyright Markus Schoepflin 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // // Options common to all edg based compilers. // // This is included from within the individual compiler mini-configs. // See also kai.hpp which checks a Kai-specific symbol for EH // // C++0x features // // See above for BOOST_NO_LONG_LONG // // No support for initializer lists //--------------------------------------------------------------------------- // BOOST_NO_STD_TYPEINFO, if inherited from common_edg.hpp, must be undefed. //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Our library implementation only supplies the C standard locale. No // other locales are available. //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Workaronud for chrono //--------------------------------------------------------------------------- // if we don't have a std library config set, try and find one: // Boost compiler configuration selection header file // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001 - 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: // First include to determine if some version of STLport is in use as the std lib // (do not rely on this header being included since users can short-circuit this header // if they know whose std lib they are using.) // cstddef standard header /* yvals.h values header for conforming compilers on various systems */ /*****************************************************************************/ /* stdarg.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ namespace std { typedef char *va_list; } /*****************************************************************************/ /* VA_END - Reclaim resources used by varargs handling. */ /* */ /* No action needed */ /*****************************************************************************/ /*****************************************************************************/ /* VA_START - Set up the va_list pointer. */ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* COFF ABI convention: */ /* - va_list is kept aligned to 4 bytes. */ /* - va_list pointer points one word beyond the start of the last argument. */ /*---------------------------------------------------------------------------*/ /*****************************************************************************/ /* VA_ARG - Return the next argument, adjust va_list pointer */ /* */ /* Some arguments passed by value are turned into pass-by-reference by */ /* making a temporary object and passing a pointer to this temporary. For */ /* such an argument (indicated by __va_argref(_type)) the actual argument */ /* passed is a pointer, so it must be dealt with specially. */ /* */ /* When an argument is larger than the maximum alignment (8 bytes for double */ /* or long long), we only align to 8 bytes. */ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* What happens on every va_arg(_ap, _type) call is: */ /* 1) Align the value of _ap (the va_list pointer) appropriately for _type */ /* (the requested type). */ /* 2) Increment _ap appropriately for _type. */ /* 3) Return the value desired by dereferencing _ap. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* The big- and little-endian variants are different only because we are */ /* trying to support the case of the user asking for "char" or "short", */ /* which is actually undefined behavior (See ISO/IEC 9899:1999 7.15.1.1), */ /* but we are trying to be friendly. */ /*---------------------------------------------------------------------------*/ using std::va_list; /* You can predefine (on the compile command line, for example): _ALT_NS=1 -- to use namespace _Dinkum_std for C++ _ALT_NS=2 -- to use namespace _Dinkum_std for C++ and C _C_AS_CPP -- to compile C library as C++ _C_IN_NS -- to define C names in std/_Dinkum_std instead of global namespace _C99 -- to turn ON C99 library support _ABRCPP -- to turn ON Abridged C++ dialect (implies _ECPP) _ECPP -- to turn ON Embedded C++ dialect _NO_EX -- to turn OFF use of try/throw _NO_MT -- to turn OFF thread synchronization _NO_NS -- to turn OFF use of namespace declarations _STL_DB (or _STLP_DEBUG) -- to turn ON iterator/range debugging __NO_LONG_LONG -- to define _Longlong as long, not long long You can change (in this header): _ADDED_C_LIB -- from 1 to 0 to omit declarations for C extensions _COMPILER_TLS -- from 0 to 1 if _TLS_QUAL is not nil _EXFAIL -- from 1 to any nonzero value for EXIT_FAILURE _FILE_OP_LOCKS -- from 0 to 1 for file atomic locks _GLOBAL_LOCALE -- from 0 to 1 for shared locales instead of per-thread _HAS_IMMUTABLE_SETS -- from 1 to 0 to permit alterable set elements _HAS_STRICT_CONFORMANCE -- from 0 to 1 to disable nonconforming extensions _HAS_TRADITIONAL_IOSTREAMS -- from 1 to 0 to omit old iostreams functions _HAS_TRADITIONAL_ITERATORS -- from 0 to 1 for vector/string pointer iterators _HAS_TRADITIONAL_POS_TYPE -- from 0 to 1 for streampos same as streamoff _HAS_TRADITIONAL_STL -- from 1 to 0 to omit old STL functions _IOSTREAM_OP_LOCKS -- from 0 to 1 for iostream atomic locks _TLS_QUAL -- from nil to compiler TLS qualifier, such as __declspec(thread) _USE_EXISTING_SYSTEM_NAMES -- from 1 to 0 to disable mappings (_Open to open) Include directories needed to compile with Dinkum C: C -- include/c C99 -- include/c (define _C99) Embedded C++ -- include/c include/embedded (define _ECPP) Abridged C++ -- include/c include/embedded include (define _ABRCPP) Standard C++ -- include/c include Standard C++ with export -- include/c include/export include (--export --template_dir=lib/export) Include directories needed to compile with native C: C -- none C99 -- N/A Embedded C++ -- include/embedded (define _ECPP) Abridged C++ -- include/embedded include (define _ABRCPP) Standard C++ -- include Standard C++ with export -- include/export include (--export --template_dir=lib/export) */ /* targets with "native" mode libraries don't support C9X */ /* DETERMINE MACHINE TYPE */ /* DETERMINE _Ptrdifft AND _Sizet FROM MACHINE TYPE */ typedef long _Int32t; typedef unsigned long _Uint32t; typedef int _Ptrdifft; typedef unsigned _Sizet; /* EXCEPTION CONTROL */ /* NAMING PROPERTIES */ /* #define _STD_LINKAGE defines C names as extern "C++" */ /* #define _STD_USING defines C names in namespace std or _Dinkum_std */ /* THREAD AND LOCALE CONTROL */ /* THREAD-LOCAL STORAGE */ /* NAMESPACE CONTROL */ namespace std {} namespace std { typedef bool _Bool; } /* VC++ COMPILER PARAMETERS */ /* defined(__NO_LONG_LONG) && !defined (_MSC_VER) && ! TI 32 bit processor*/ /* MAKE MINGW LOOK LIKE WIN32 HEREAFTER */ namespace std { /* FLOATING-POINT PROPERTIES */ /* INTEGER PROPERTIES */ typedef long long _Longlong; typedef unsigned long long _ULonglong; /* wchar_t AND wint_t PROPERTIES */ typedef wchar_t _Wchart; typedef wchar_t _Wintt; /* POINTER PROPERTIES */ /* signal PROPERTIES */ /* stdarg PROPERTIES */ typedef ::std:: va_list _Va_list; /* stdlib PROPERTIES */ extern "C" { void _Atexit(void (*)(void)); } /* stdio PROPERTIES */ typedef char _Sysch_t; /* STORAGE ALIGNMENT PROPERTIES */ /* time PROPERTIES */ } /* MULTITHREAD PROPERTIES */ /* LOCK MACROS */ namespace std { extern "C++" { // in case of _C_AS_CPP // CLASS _Lockit class _Lockit { // lock while object in existence -- MUST NEST public: explicit _Lockit() { // do nothing } explicit _Lockit(int) { // do nothing } ~_Lockit() { // do nothing } private: _Lockit(const _Lockit&); // not defined _Lockit& operator=(const _Lockit&); // not defined }; class _Mutex { // lock under program control public: void _Lock() { // do nothing } void _Unlock() { // do nothing } }; } // extern "C++" } /* MISCELLANEOUS MACROS */ /*****************************************************************************/ /* linkage.h v7.3.6 */ /* */ /* Copyright (c) 1998-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*--------------------------------------------------------------------------*/ /* Define _CODE_ACCESS ==> how to call RTS functions */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* Define _DATA_ACCESS ==> how to access RTS global or static data */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* Define _DATA_ACCESS_NEAR ==> some C6000 RTS data must always be near */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* Define _IDECL ==> how inline functions are declared */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* If compiling with non-TI compiler (e.g. GCC), nullify any TI-specific */ /* language extensions. */ /*--------------------------------------------------------------------------*/ /*****************************************************************************/ /* _lock.h v7.3.6 */ /* */ /* Copyright (c) 2000-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ extern "C" namespace std { void _nop(); extern far void ( *_lock)(); extern far void (*_unlock)(); void _register_lock (void ( *lock)()); void _register_unlock(void (*unlock)()); } /* extern "C" namespace std */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ /*****************************************************************************/ /* stddef.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ extern "C" namespace std { typedef int ptrdiff_t; typedef unsigned size_t; } /* extern "C" namespace std */ /*-----------------------------------------------------------------------*/ /* Define _win_t, for compiling GCC libraries with the TI compiler. */ /* GCC's library (newlib) expects wint_t to be defined here, in stddef.h,*/ /* which is arguably incorrect, but we go along for compatibility. */ /* This is outside the _STDDEF guard in case this file has already */ /* been included without __need_wint_t. */ /*-----------------------------------------------------------------------*/ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // If our std lib was not some version of STLport, then include as it is about // the smallest of the std lib headers that includes real C++ stuff. (Some std libs do not // include their C++-related macros in so this additional include makes sure // we get those definitions) // (again do not rely on this header being included since users can short-circuit this // header if they know whose std lib they are using.) // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // The aim of this header is just to include but to do // so in a way that does not result in recursive inclusion of // the Boost TR1 components if boost/tr1/tr1/utility is in the // include search path. We have to do this to avoid circular // dependencies: // // utility standard header // iosfwd standard header // cstdio standard header /*****************************************************************************/ /* STDIO.H v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* stdarg.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* Attributes are only available in relaxed ANSI mode. */ /*---------------------------------------------------------------------------*/ //---------------------------------------------------------------------------- // IS RECOMMENDED OVER . IS PROVIDED FOR // COMPATIBILITY WITH C AND THIS USAGE IS DEPRECATED IN C++ //---------------------------------------------------------------------------- extern "C" namespace std { /****************************************************************************/ /* TYPES THAT ANSI REQUIRES TO BE DEFINED */ /****************************************************************************/ typedef struct { int fd; /* File descriptor */ unsigned char* buf; /* Pointer to start of buffer */ unsigned char* pos; /* Position in buffer */ unsigned char* bufend; /* Pointer to end of buffer */ unsigned char* buff_stop; /* Pointer to last read char in buffer */ unsigned int flags; /* File status flags (see below) */ } FILE; typedef int fpos_t; /****************************************************************************/ /* DEVICE AND STREAM RELATED MACROS */ /****************************************************************************/ /****************************************************************************/ /* MACROS THAT DEFINE AND USE FILE STATUS FLAGS */ /****************************************************************************/ /****************************************************************************/ /* MACROS THAT ANSI REQUIRES TO BE DEFINED */ /****************************************************************************/ /******** END OF ANSI MACROS ************************************************/ /****************************************************************************/ /* DEVICE AND STREAM RELATED DATA STRUCTURES AND MACROS */ /****************************************************************************/ extern far FILE _ftable[20]; extern far char _tmpnams[20][16]; /****************************************************************************/ /* FUNCTION DEFINITIONS - ANSI */ /****************************************************************************/ /****************************************************************************/ /* OPERATIONS ON FILES */ /****************************************************************************/ extern int remove(const char *_file); extern int rename(const char *_old, const char *_new); extern FILE *tmpfile(void); extern char *tmpnam(char *_s); /****************************************************************************/ /* FILE ACCESS FUNCTIONS */ /****************************************************************************/ extern int fclose(FILE *_fp); extern FILE *fopen(const char *_fname, const char *_mode); extern FILE *freopen(const char *_fname, const char *_mode, register FILE *_fp); extern void setbuf(register FILE *_fp, char *_buf); extern int setvbuf(register FILE *_fp, register char *_buf, register int _type, register size_t _size); extern int fflush(register FILE *_fp); /****************************************************************************/ /* FORMATTED INPUT/OUTPUT FUNCTIONS */ /****************************************************************************/ extern int fprintf(FILE *_fp, const char *_format, ...) __attribute__((__format__ (__printf__, 2, 3))); extern int fscanf(FILE *_fp, const char *_fmt, ...) __attribute__((__format__ (__scanf__, 2, 3))); extern int printf(const char *_format, ...) __attribute__((__format__ (__printf__, 1, 2))); extern int scanf(const char *_fmt, ...) __attribute__((__format__ (__scanf__, 1, 2))); extern int sprintf(char *_string, const char *_format, ...) __attribute__((__format__ (__printf__, 2, 3))); extern int snprintf(char *_string, size_t _n, const char *_format, ...) __attribute__((__format__ (__printf__, 3, 4))); extern int sscanf(const char *_str, const char *_fmt, ...) __attribute__((__format__ (__scanf__, 2, 3))); extern int vfprintf(FILE *_fp, const char *_format, va_list _ap) __attribute__((__format__ (__printf__, 2, 0))); extern int vprintf(const char *_format, va_list _ap) __attribute__((__format__ (__printf__, 1, 0))); extern int vsprintf(char *_string, const char *_format, va_list _ap) __attribute__((__format__ (__printf__, 2, 0))); extern int vsnprintf(char *_string, size_t _n, const char *_format, va_list _ap) __attribute__((__format__ (__printf__, 3, 0))); /****************************************************************************/ /* CHARACTER INPUT/OUTPUT FUNCTIONS */ /****************************************************************************/ extern int fgetc(register FILE *_fp); extern char *fgets(char *_ptr, register int _size, register FILE *_fp); extern int fputc(int _c, register FILE *_fp); extern int fputs(const char *_ptr, register FILE *_fp); extern int getc(FILE *_p); extern int getchar(void); extern char *gets(char *_ptr); extern int putc(int _x, FILE *_fp); extern int putchar(int _x); extern int puts(const char *_ptr); extern int ungetc(int _c, register FILE *_fp); /****************************************************************************/ /* DIRECT INPUT/OUTPUT FUNCTIONS */ /****************************************************************************/ extern size_t fread(void *_ptr, size_t _size, size_t _count, FILE *_fp); extern size_t fwrite(const void *_ptr, size_t _size, size_t _count, register FILE *_fp); /****************************************************************************/ /* FILE POSITIONING FUNCTIONS */ /****************************************************************************/ extern int fgetpos(FILE *_fp, fpos_t *_pos); extern int fseek(register FILE *_fp, long _offset, int _ptrname); extern int fsetpos(FILE *_fp, const fpos_t *_pos); extern long ftell(FILE *_fp); extern void rewind(register FILE *_fp); /****************************************************************************/ /* ERROR-HANDLING FUNCTIONS */ /****************************************************************************/ extern void clearerr(FILE *_fp); extern int feof(FILE *_fp); extern int ferror(FILE *_fp); extern void perror(const char *_s); } /* extern "C" namespace std */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // cstring standard header /*****************************************************************************/ /* string.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ //---------------------------------------------------------------------------- // IS RECOMMENDED OVER . IS PROVIDED FOR // COMPATIBILITY WITH C AND THIS USAGE IS DEPRECATED IN C++ //---------------------------------------------------------------------------- extern "C" namespace std { extern "C" size_t strlen(const char *_string); extern "C" char *strcpy(char *_dest, const char *_src); extern "C" char *strncpy(char *_to, const char *_from, size_t _n); extern "C" char *strcat(char *_string1, const char *_string2); extern "C" char *strncat(char *_to, const char *_from, size_t _n); extern "C" char *strchr(const char *_string, int _c); extern "C" char *strrchr(const char *_string, int _c); extern "C" int strcmp(const char *_string1, const char *_string2); extern "C" int strncmp(const char *_string1, const char *_string2, size_t _n); int strcoll(const char *_string1, const char *_string2); size_t strxfrm(char *_to, const char *_from, size_t _n); char *strpbrk(const char *_string, const char *_chs); size_t strspn(const char *_string, const char *_chs); size_t strcspn(const char *_string, const char *_chs); char *strstr(const char *_string1, const char *_string2); char *strtok(char *_str1, const char *_str2); char *strerror(int _errno); void *memmove(void *_s1, const void *_s2, size_t _n); void *memcpy(void *_s1, const void *_s2, size_t _n); extern "C" int memcmp(const void *_cs, const void *_ct, size_t _n); extern "C" void *memchr(const void *_cs, int _c, size_t _n); void *memset(void *_mem, int _ch, size_t _n); } /* extern "C" namespace std */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // cwchar standard header /*****************************************************************************/ /* wchar.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* minimal support for C++ library implementation */ /* provided by Dinkumware */ /*---------------------------------------------------------------------------*/ /* wchar.h minimal header for C++ */ /*****************************************************************************/ /* stddef.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*-----------------------------------------------------------------------*/ /* Define _win_t, for compiling GCC libraries with the TI compiler. */ /* GCC's library (newlib) expects wint_t to be defined here, in stddef.h,*/ /* which is arguably incorrect, but we go along for compatibility. */ /* This is outside the _STDDEF guard in case this file has already */ /* been included without __need_wint_t. */ /*-----------------------------------------------------------------------*/ /*****************************************************************************/ /* STDIO.H v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ namespace std { /* MACROS */ /* TYPE DEFINITIONS */ typedef int _Mbstatet; typedef _Mbstatet mbstate_t; struct tm; typedef int wint_t; extern "C" { /* FUNCTIONS */ wint_t btowc(int); wint_t fgetwc(FILE *); wint_t fputwc(wchar_t, FILE *); size_t mbrtowc(wchar_t *, const char *, size_t, mbstate_t *); wint_t ungetwc(wint_t, FILE *); size_t wcslen(const wchar_t *); size_t wcrtomb(char *, wchar_t, mbstate_t *); int wctob(wint_t); int wmemcmp(const wchar_t *, const wchar_t *, size_t); wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t); wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); wchar_t *wmemset(wchar_t *, wchar_t, size_t); int fwide(FILE *str, int mode); wchar_t *wmemchr(const wchar_t *, wchar_t, size_t); } /* inlines/macros */ } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ typedef std::mbstate_t _Mbstatet; /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // xstddef standard header namespace std { // EXCEPTION MACROS // typename KEYWORD /* #define _TEMPLATE template<> */ /* #define _TEMPLATE_MEMBER template */ // BITMASK MACROS // MISCELLANEOUS MACROS // TYPE DEFINITIONS enum _Uninitialized { // tag for suppressing initialization _Noinit}; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // STREAM POSITIONING TYPES (from ) typedef long streamoff; typedef int streamsize; extern far fpos_t _Fpz; extern const far streamoff _BADOFF; // TEMPLATE CLASS fpos (from ) template class fpos { // store arbitrary file position typedef fpos<_Statetype> _Myt; public: fpos(streamoff _Off = 0) : _Myoff(_Off), _Fpos(_Fpz), _Mystate(_Stz) { // construct with stream offset } fpos(_Statetype _State, fpos_t _Fileposition) : _Myoff(0), _Fpos(_Fileposition), _Mystate(_State) { // construct with conversion state and C file position } _Statetype state() const { // return conversion state return (_Mystate); } void state(_Statetype _State) { // set conversion state _Mystate = _State; } fpos_t seekpos() const { // return C file position return (_Fpos); } operator streamoff() const { // return offset return (_Myoff + ((long)(_Fpos))); } streamoff operator-(const _Myt& _Right) const { // return difference of file positions as an offset return ((streamoff)*this - (streamoff)_Right); } _Myt& operator+=(streamoff _Off) { // add offset _Myoff += _Off; return (*this); } _Myt& operator-=(streamoff _Off) { // subtract offset _Myoff -= _Off; return (*this); } _Myt operator+(streamoff _Off) const { // return this + offset _Myt _Tmp = *this; return (_Tmp += _Off); } _Myt operator-(streamoff _Off) const { // return this - offset _Myt _Tmp = *this; return (_Tmp -= _Off); } bool operator==(const _Myt& _Right) const { // test for file position equality return ((streamoff)*this == (streamoff)_Right); } bool operator==(streamoff _Right) const { // test for file position equality with streamoff return ((streamoff)*this == _Right); } bool operator!=(const _Myt& _Right) const { // test for file position inequality return (!(*this == _Right)); } private: static far _Statetype _Stz; // initial conversion state streamoff _Myoff; // stream offset fpos_t _Fpos; // C file position _Statetype _Mystate; // current conversion state }; // STATIC fpos::_Stz OBJECT template _Statetype fpos<_Statetype>::_Stz; typedef fpos<_Mbstatet> streampos; typedef streampos wstreampos; // TEMPLATE STRUCT char_traits (FROM ) template struct char_traits { // properties of a string or stream element typedef _Elem char_type; typedef long int_type; typedef streampos pos_type; typedef streamoff off_type; typedef _Mbstatet state_type; static void assign(_Elem& _Left, const _Elem& _Right) { // assign an element _Left = _Right; } static bool eq(const _Elem& _Left, const _Elem& _Right) { // test for element equality return (_Left == _Right); } static bool lt(const _Elem& _Left, const _Elem& _Right) { // test if _Left precedes _Right return (_Left < _Right); } static int compare(const _Elem *_First1, const _Elem *_First2, size_t _Count) { // compare [_First1, _First1 + _Count) with [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); for (; 0 < _Count; --_Count, ++_First1, ++_First2) if (!eq(*_First1, *_First2)) return (lt(*_First1, *_First2) ? -1 : +1); return (0); } static size_t length(const _Elem *_First) { // find length of null-terminated sequence // _DEBUG_POINTER(_First); size_t _Count; for (_Count = 0; !eq(*_First, _Elem()); ++_First) ++_Count; return (_Count); } static _Elem *copy(_Elem *_First1, const _Elem *_First2, size_t _Count) { // copy [_First1, _First1 + _Count) to [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); _Elem *_Next = _First1; for (; 0 < _Count; --_Count, ++_Next, ++_First2) assign(*_Next, *_First2); return (_First1); } static const _Elem *find(const _Elem *_First, size_t _Count, const _Elem& _Ch) { // look for _Ch in [_First, _First + _Count) // _DEBUG_POINTER(_First); for (; 0 < _Count; --_Count, ++_First) if (eq(*_First, _Ch)) return (_First); return (0); } static _Elem *move(_Elem *_First1, const _Elem *_First2, size_t _Count) { // copy [_First1, _First1 + _Count) to [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); _Elem *_Next = _First1; if (_First2 < _Next && _Next < _First2 + _Count) for (_Next += _Count, _First2 += _Count; 0 < _Count; --_Count) assign(*--_Next, *--_First2); else for (; 0 < _Count; --_Count, ++_Next, ++_First2) assign(*_Next, *_First2); return (_First1); } static _Elem *assign(_Elem *_First, size_t _Count, _Elem _Ch) { // assign _Count * _Ch to [_First, ...) // _DEBUG_POINTER(_First); _Elem *_Next = _First; for (; 0 < _Count; --_Count, ++_Next) assign(*_Next, _Ch); return (_First); } static _Elem to_char_type(const int_type& _Meta) { // convert metacharacter to character return ((_Elem)_Meta); } static int_type to_int_type(const _Elem& _Ch) { // convert character to metacharacter return ((int_type)_Ch); } static bool eq_int_type(const int_type& _Left, const int_type& _Right) { // test for metacharacter equality return (_Left == _Right); } static int_type eof() { // return end-of-file metacharacter return ((int_type)(-1)); } static int_type not_eof(const int_type& _Meta) { // return anything but EOF return (_Meta != eof() ? (int_type)_Meta : (int_type)!eof()); } }; // STRUCT char_traits template<> struct char_traits { // properties of a string or stream wchar_t element typedef wchar_t _Elem; typedef _Elem char_type; // for overloads typedef wint_t int_type; typedef streampos pos_type; typedef streamoff off_type; typedef _Mbstatet state_type; static void assign(_Elem& _Left, const _Elem& _Right) { // assign an element _Left = _Right; } static bool eq(const _Elem& _Left, const _Elem& _Right) { // test for element equality return (_Left == _Right); } static bool lt(const _Elem& _Left, const _Elem& _Right) { // test if _Left precedes _Right return (_Left < _Right); } static int compare(const _Elem *_First1, const _Elem *_First2, size_t _Count) { // compare [_First1, _First1 + _Count) with [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); return (::std:: wmemcmp(_First1, _First2, _Count)); } static size_t length(const _Elem *_First) { // find length of null-terminated sequence // _DEBUG_POINTER(_First); return (::std:: wcslen(_First)); } static _Elem *copy(_Elem *_First1, const _Elem *_First2, size_t _Count) { // copy [_First1, _First1 + _Count) to [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); return ((_Elem *)::std:: wmemcpy(_First1, _First2, _Count)); } static const _Elem *find(const _Elem *_First, size_t _Count, const _Elem& _Ch) { // look for _Ch in [_First, _First + _Count) // _DEBUG_POINTER(_First); return ((const _Elem *)::std:: wmemchr(_First, _Ch, _Count)); } static _Elem *move(_Elem *_First1, const _Elem *_First2, size_t _Count) { // copy [_First1, _First1 + _Count) to [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); return ((_Elem *)::std:: wmemmove(_First1, _First2, _Count)); } static _Elem *assign(_Elem *_First, size_t _Count, _Elem _Ch) { // assign _Count * _Ch to [_First, ...) // _DEBUG_POINTER(_First); return ((_Elem *)::std:: wmemset(_First, _Ch, _Count)); } static _Elem to_char_type(const int_type& _Meta) { // convert metacharacter to character return (_Meta); } static int_type to_int_type(const _Elem& _Ch) { // convert character to metacharacter return (_Ch); } static bool eq_int_type(const int_type& _Left, const int_type& _Right) { // test for metacharacter equality return (_Left == _Right); } static int_type eof() { // return end-of-file metacharacter return (((wint_t)(-1))); } static int_type not_eof(const int_type& _Meta) { // return anything but EOF return (_Meta != eof() ? _Meta : !eof()); } }; // STRUCT char_traits (FROM ) template<> struct char_traits { // properties of a string or stream char element typedef char _Elem; typedef _Elem char_type; typedef int int_type; typedef streampos pos_type; typedef streamoff off_type; typedef _Mbstatet state_type; static void assign(_Elem& _Left, const _Elem& _Right) { // assign an element _Left = _Right; } static bool eq(const _Elem& _Left, const _Elem& _Right) { // test for element equality return (_Left == _Right); } static bool lt(const _Elem& _Left, const _Elem& _Right) { // test if _Left precedes _Right return (_Left < _Right); } static int compare(const _Elem *_First1, const _Elem *_First2, size_t _Count) { // compare [_First1, _First1 + _Count) with [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); return (::std:: memcmp(_First1, _First2, _Count)); } static size_t length(const _Elem *_First) { // find length of null-terminated string // _DEBUG_POINTER(_First); return (::std:: strlen(_First)); } static _Elem *copy(_Elem *_First1, const _Elem *_First2, size_t _Count) { // copy [_First1, _First1 + _Count) to [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); return ((_Elem *)::std:: memcpy(_First1, _First2, _Count)); } static const _Elem *find(const _Elem *_First, size_t _Count, const _Elem& _Ch) { // look for _Ch in [_First, _First + _Count) // _DEBUG_POINTER(_First); return ((const _Elem *)::std:: memchr(_First, _Ch, _Count)); } static _Elem *move(_Elem *_First1, const _Elem *_First2, size_t _Count) { // copy [_First1, _First1 + _Count) to [_First2, ...) // _DEBUG_POINTER(_First1); // _DEBUG_POINTER(_First2); return ((_Elem *)::std:: memmove(_First1, _First2, _Count)); } static _Elem *assign(_Elem *_First, size_t _Count, _Elem _Ch) { // assign _Count * _Ch to [_First, ...) // _DEBUG_POINTER(_First); return ((_Elem *)::std:: memset(_First, _Ch, _Count)); } static _Elem to_char_type(const int_type& _Meta) { // convert metacharacter to character return ((_Elem)_Meta); } static int_type to_int_type(const _Elem& _Ch) { // convert character to metacharacter return ((unsigned char)_Ch); } static bool eq_int_type(const int_type& _Left, const int_type& _Right) { // test for metacharacter equality return (_Left == _Right); } static int_type eof() { // return end-of-file metacharacter return ((-1)); } static int_type not_eof(const int_type& _Meta) { // return anything but EOF return (_Meta != eof() ? _Meta : !eof()); } }; // FORWARD REFERENCES template class allocator; class ios_base; template > class basic_ios; template > class istreambuf_iterator; template > class ostreambuf_iterator; template > class basic_streambuf; template > class basic_istream; template > class basic_ostream; template > class basic_iostream; template, class _Alloc = allocator<_Elem> > class basic_stringbuf; template, class _Alloc = allocator<_Elem> > class basic_istringstream; template, class _Alloc = allocator<_Elem> > class basic_ostringstream; template, class _Alloc = allocator<_Elem> > class basic_stringstream; template > class basic_filebuf; template > class basic_ifstream; template > class basic_ofstream; template > class basic_fstream; // char TYPEDEFS typedef basic_ios > ios; typedef basic_streambuf > streambuf; typedef basic_istream > istream; typedef basic_ostream > ostream; typedef basic_iostream > iostream; typedef basic_stringbuf, allocator > stringbuf; typedef basic_istringstream, allocator > istringstream; typedef basic_ostringstream, allocator > ostringstream; typedef basic_stringstream, allocator > stringstream; typedef basic_filebuf > filebuf; typedef basic_ifstream > ifstream; typedef basic_ofstream > ofstream; typedef basic_fstream > fstream; // wchat_t TYPEDEFS typedef basic_ios > wios; typedef basic_streambuf > wstreambuf; typedef basic_istream > wistream; typedef basic_ostream > wostream; typedef basic_iostream > wiostream; typedef basic_stringbuf, allocator > wstringbuf; typedef basic_istringstream, allocator > wistringstream; typedef basic_ostringstream, allocator > wostringstream; typedef basic_stringstream, allocator > wstringstream; typedef basic_filebuf > wfilebuf; typedef basic_ifstream > wifstream; typedef basic_ofstream > wofstream; typedef basic_fstream > wfstream; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // TEMPLATE FUNCTION swap (from ) template inline void swap(_Ty& _Left, _Ty& _Right) { // exchange values stored at _Left and _Right _Ty _Tmp = _Left; _Left = _Right, _Right = _Tmp; } // TEMPLATE STRUCT pair template struct pair { // store a pair of values typedef pair<_Ty1, _Ty2> _Myt; typedef _Ty1 first_type; typedef _Ty2 second_type; pair() : first(_Ty1()), second(_Ty2()) { // construct from defaults } pair(const _Ty1& _Val1, const _Ty2& _Val2) : first(_Val1), second(_Val2) { // construct from specified values } template pair(const pair<_Other1, _Other2>& _Right) : first(_Right.first), second(_Right.second) { // construct from compatible pair } void swap(_Myt& _Right) { // exchange contents with _Right ::std:: swap(first, _Right.first); ::std:: swap(second, _Right.second); } _Ty1 first; // the first stored value _Ty2 second; // the second stored value }; // pair TEMPLATE OPERATORS template inline void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right) { // swap _Left and _Right pairs _Left.swap(_Right); } template inline bool operator==(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test for pair equality return (_Left.first == _Right.first && _Left.second == _Right.second); } template inline bool operator!=(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test for pair inequality return (!(_Left == _Right)); } template inline bool operator<(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left < _Right for pairs return (_Left.first < _Right.first || !(_Right.first < _Left.first) && _Left.second < _Right.second); } template inline bool operator>(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left > _Right for pairs return (_Right < _Left); } template inline bool operator<=(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left <= _Right for pairs return (!(_Right < _Left)); } template inline bool operator>=(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left >= _Right for pairs return (!(_Left < _Right)); } template inline pair<_Ty1, _Ty2> make_pair(_Ty1 _Val1, _Ty2 _Val2) { // return pair composed from arguments return (pair<_Ty1, _Ty2>(_Val1, _Val2)); } // TEMPLATE OPERATORS namespace rel_ops { // nested namespace to hide relational operators from std template inline bool operator!=(const _Ty& _Left, const _Ty& _Right) { // test for inequality, in terms of equality return (!(_Left == _Right)); } template inline bool operator>(const _Ty& _Left, const _Ty& _Right) { // test if _Left > _Right, in terms of operator< return (_Right < _Left); } template inline bool operator<=(const _Ty& _Left, const _Ty& _Right) { // test if _Left <= _Right, in terms of operator< return (!(_Right < _Left)); } template inline bool operator>=(const _Ty& _Left, const _Ty& _Right) { // test if _Left >= _Right, in terms of operator< return (!(_Left < _Right)); } } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */ /* * This file is derived from software bearing the following * restrictions: * * 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. V4.02:1476 */ // Dinkumware Library (this has to appear after any possible replacement libraries): // if we have a std library config, include it now: // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001. // (C) Copyright Peter Dimov 2001. // (C) Copyright David Abrahams 2002. // (C) Copyright Guillaume Melquiond 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Dinkumware standard library config: // full dinkumware 3.06 and above // fully conforming provided the compiler supports it: // There's no numeric_limits support unless _LONGLONG is defined: // 3.06 appears to have (non-sgi versions of) & , // and no at all // // std extension namespace is stdext for vc7.1 and later, // the same applies to other compilers that sit on top // of vc7.1 (Intel and Comeau): // // typeinfo standard header for gcc/EDG // exception standard header namespace std { // FORWARD REFERENCES class exception; typedef void (*_Prhand)(const exception&); extern far _Prhand _Raise_handler; void _Throw(const exception&); // CLASS exception class exception { // base of all library exceptions, EDG version public: static _Prhand _Set_raise_handler(_Prhand _Pnew) { // register a handler for _Raise calls const _Prhand _Pold = _Raise_handler; _Raise_handler = _Pnew; return (_Pold); } explicit exception(const char *_Message = "unknown") throw () : _Ptr(_Message) { // construct from message string } exception(const exception& _Right) throw () : _Ptr(_Right._Ptr) { // construct by copying _Right } exception& operator=(const exception& _Right) throw () { // assign _Right _Ptr = _Right._Ptr; return (*this); } virtual ~exception() { // destroy the object } virtual const char *what() const { // return pointer to message string return (_Ptr); } protected: const char *_Ptr; // the message pointer }; // CLASS bad_exception class bad_exception : public exception { // base of all bad exceptions, EDG version public: bad_exception(const char *_Message = "bad exception") throw () : exception(_Message) { // construct from message string } virtual ~bad_exception() throw () { // destroy the object } }; // TYPES typedef void (*terminate_handler)(); typedef void (*unexpected_handler)(); // FUNCTION DECLARATIONS terminate_handler set_terminate(terminate_handler) throw (); unexpected_handler set_unexpected(unexpected_handler) throw (); bool uncaught_exception(); void terminate(); void unexpected(); } /* namespace std */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // CLASS bad_cast class bad_cast : public ::std:: exception { // base of all bad-cast exceptions public: bad_cast() throw () ; bad_cast(const bad_cast&) throw (); bad_cast& operator=(const bad_cast&) throw (); virtual ~bad_cast() throw (); virtual const char *what() const throw () ; }; // CLASS bad_typeid class bad_typeid : public ::std:: exception { // base of all bad-typeid exceptions public: bad_typeid() throw () ; bad_typeid(const bad_typeid&) throw (); bad_typeid& operator=(const bad_typeid&) throw (); virtual ~bad_typeid() throw (); virtual const char *what() const throw () ; }; } namespace std { #pragma define_type_info // CLASS type_info class type_info { // translator-supplied descriptor for a type public: virtual ~type_info(); // destroy the object bool before(const type_info&) const; // test if this precedes arg bool operator==(const type_info&) const; // test for equality bool operator!=(const type_info&) const; // test for inequality const char *name() const; // return name of type protected: // to shut up compiler type_info(const type_info&); // not defined private: type_info& operator=(const type_info&); // not defined }; } /* namespace std */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // C++0x headers implemented in 520 (as shipped by Microsoft) // // // C++0x headers not yet (fully) implemented: // // if we don't have a platform config set, try and find one: // Boost compiler configuration selection header file // (C) Copyright John Maddock 2001 - 2002. // (C) Copyright Jens Maurer 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. // Note that we define the headers to include using "header_name" not // in order to prevent macro expansion within the header // name (for example "linux" is a macro on linux systems). // if we have a platform config, include it now: // get config suffix code: // Boost config.hpp configuration header file ------------------------------// // Copyright (c) 2001-2003 John Maddock // Copyright (c) 2001 Darin Adler // Copyright (c) 2001 Peter Dimov // Copyright (c) 2002 Bill Kempf // Copyright (c) 2002 Jens Maurer // Copyright (c) 2002-2003 David Abrahams // Copyright (c) 2003 Gennaro Prota // Copyright (c) 2003 Eric Friedman // Copyright (c) 2010 Eric Jourdanneau, Joel Falcou // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/ for most recent version. // Boost config.hpp policy and rationale documentation has been moved to // http://www.boost.org/libs/config/ // // This file is intended to be stable, and relatively unchanging. // It should contain boilerplate code only - no compiler specific // code unless it is unavoidable - no changes unless unavoidable. // // ensure that visibility macros are always defined, thus symplifying use // // // look for long long by looking for the appropriate macros in . // Note that we use limits.h rather than climits for maximal portability, // remember that since these just declare a bunch of macros, there should be // no namespace issues from this. // // GCC 3.x will clean up all of those nasty macro definitions that // BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine // it under GCC 3.x. // // Assume any extensions are in namespace std:: unless stated otherwise: // // // If cv-qualified specializations are not allowed, then neither are cv-void ones: // // // If there is no numeric_limits template, then it can't have any compile time // constants either! // // // if there is no long long then there is no specialisation // for numeric_limits either: // // // Normalize BOOST_NO_STATIC_ASSERT and (depricated) BOOST_HAS_STATIC_ASSERT: // // // if there is no __int64 then there is no specialisation // for numeric_limits<__int64> either: // // // if member templates are supported then so is the // VC6 subset of member templates: // // // Without partial specialization, can't test for partial specialisation bugs: // // // Without partial specialization, we can't have array-type partial specialisations: // // // Without partial specialization, std::iterator_traits can't work: // // // Without partial specialization, partial // specialization with default args won't work either: // // // Without member template support, we can't have template constructors // in the standard library either: // // // Without member template support, we can't have a conforming // std::allocator template either: // // // without ADL support then using declarations will break ADL as well: // // // Without typeid support we have no dynamic RTTI either: // // // If we have a standard allocator, then we have a partial one as well: // // // We can't have a working std::use_facet if there is no std::locale: // // // We can't have a std::messages facet if there is no std::locale: // // // We can't have a working std::wstreambuf if there is no std::locale: // // // We can't have a if there is no : // // // We can't have a swprintf if there is no : // // // If Win32 support is turned off, then we must turn off // threading support also, unless there is some other // thread API enabled: // // // Turn on threading support if the compiler thinks that it's in // multithreaded mode. We put this here because there are only a // limited number of macros that identify this (if there's any missing // from here then add to the appropriate compiler section): // // // Turn threading support off if BOOST_DISABLE_THREADS is defined: // // // Turn threading support off if we don't recognise the threading API: // // // Turn threading detail macros off if we don't (want to) use threading // // // If the compiler claims to be C99 conformant, then it had better // have a : // // // Define BOOST_NO_SLIST and BOOST_NO_HASH if required. // Note that this is for backwards compatibility only. // // // Set BOOST_SLIST_HEADER if not set already: // // // Set BOOST_HASH_SET_HEADER if not set already: // // // Set BOOST_HASH_MAP_HEADER if not set already: // // // Set BOOST_HAS_RVALUE_REFS when BOOST_NO_RVALUE_REFERENCES is not defined // // // Set BOOST_HAS_VARIADIC_TMPL when BOOST_NO_VARIADIC_TEMPLATES is not defined // // // Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined // // BOOST_HAS_ABI_HEADERS // This macro gets set if we have headers that fix the ABI, // and prevent ODR violations when linking to external libraries: // BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// // Because std::size_t usage is so common, even in boost headers which do not // otherwise use the C library, the workaround is included here so // that ugly workaround code need not appear in many other boost headers. // NOTE WELL: This is a workaround for non-conforming compilers; // must still be #included in the usual places so that inclusion // works as expected with standard conforming compilers. The resulting // double inclusion of is harmless. // Workaround for the unfortunate min/max macros defined by some platform headers // BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// // BOOST_STATIC_CONSTANT workaround --------------------------------------- // // On compilers which don't allow in-class initialization of static integral // constant members, we must use enums as a workaround if we want the constants // to be available at compile-time. This macro gives us a convenient way to // declare such constants. // BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// // When the standard library does not have a conforming std::use_facet there // are various workarounds available, but they differ from library to library. // The same problem occurs with has_facet. // These macros provide a consistent way to access a locale's facets. // Usage: // replace // std::use_facet(loc); // with // BOOST_USE_FACET(Type, loc); // Note do not add a std:: prefix to the front of BOOST_USE_FACET! // Use for BOOST_HAS_FACET is analogous. // BOOST_NESTED_TEMPLATE workaround ------------------------------------------// // Member templates are supported by some compilers even though they can't use // the A::template member syntax, as a workaround replace: // // typedef typename A::template rebind binder; // // with: // // typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; // BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// // Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION // is defined, in which case it evaluates to return x; Use when you have a return // statement that can never be reached. // BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// // // Some compilers don't support the use of `typename' for dependent // types in deduced contexts, e.g. // // template void f(T, typename T::type); // ^^^^^^^^ // Replace these declarations with: // // template void f(T, BOOST_DEDUCED_TYPENAME T::type); // long long workaround ------------------------------------------// // On gcc (and maybe other compilers?) long long is alway supported // but it's use may generate either warnings (with -ansi), or errors // (with -pedantic -ansi) unless it's use is prefixed by __extension__ // namespace boost{ __extension__ typedef long long long_long_type; __extension__ typedef unsigned long long ulong_long_type; } // BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// // // Some compilers have problems with function templates whose template // parameters don't appear in the function parameter list (basically // they just link one instantiation of the template in the final // executable). These macros provide a uniform way to cope with the // problem with no effects on the calling syntax. // Example: // // #include // #include // #include // // template // void f() { std::cout << n << ' '; } // // template // void g() { std::cout << typeid(T).name() << ' '; } // // int main() { // f<1>(); // f<2>(); // // g(); // g(); // } // // With VC++ 6.0 the output is: // // 2 2 double double // // To fix it, write // // template // void f(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, n)) { ... } // // template // void g(BOOST_EXPLICIT_TEMPLATE_TYPE(T)) { ... } // // no workaround needed: expand to nothing // When BOOST_NO_STD_TYPEINFO is defined, we can just import // the global definition into std namespace: // ---------------------------------------------------------------------------// // // Helper macro BOOST_STRINGIZE: // Converts the parameter X to a string after macro replacement // on X has been performed. // // // Helper macro BOOST_JOIN: // The following piece of macro magic joins the two // arguments together, even when one of the arguments is // itself a macro (see 16.3.1 in C++ standard). The key // is that macro expansion of macro arguments does not // occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. // // // Helper macros BOOST_NOEXCEPT, BOOST_NOEXCEPT_IF, BOOST_NOEXCEPT_EXPR // These aid the transition to C++11 while still supporting C++03 compilers // // // Set some default values for compiler/library/platform names. // These are for debugging config setup only: // // // Set some default values GPU support // // // constexpr workarounds // // BOOST_FORCEINLINE ---------------------------------------------// // Macro to use in place of 'inline' to force a function to be inline // -------------------- Deprecated macros for 1.50 --------------------------- // These will go away in a future release // Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST instead of BOOST_NO_INITIALIZER_LISTS // Use BOOST_NO_CXX11_HDR_ARRAY instead of BOOST_NO_0X_HDR_ARRAY // Use BOOST_NO_CXX11_HDR_CHRONO instead of BOOST_NO_0X_HDR_CHRONO // Use BOOST_NO_CXX11_HDR_CODECVT instead of BOOST_NO_0X_HDR_CODECVT // Use BOOST_NO_CXX11_HDR_CONDITION_VARIABLE instead of BOOST_NO_0X_HDR_CONDITION_VARIABLE // Use BOOST_NO_CXX11_HDR_FORWARD_LIST instead of BOOST_NO_0X_HDR_FORWARD_LIST // Use BOOST_NO_CXX11_HDR_FUTURE instead of BOOST_NO_0X_HDR_FUTURE // Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST // instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS // Use BOOST_NO_CXX11_HDR_MUTEX instead of BOOST_NO_0X_HDR_MUTEX // Use BOOST_NO_CXX11_HDR_RANDOM instead of BOOST_NO_0X_HDR_RANDOM // Use BOOST_NO_CXX11_HDR_RATIO instead of BOOST_NO_0X_HDR_RATIO // Use BOOST_NO_CXX11_HDR_REGEX instead of BOOST_NO_0X_HDR_REGEX // Use BOOST_NO_CXX11_HDR_SYSTEM_ERROR instead of BOOST_NO_0X_HDR_SYSTEM_ERROR // Use BOOST_NO_CXX11_HDR_THREAD instead of BOOST_NO_0X_HDR_THREAD // Use BOOST_NO_CXX11_HDR_TUPLE instead of BOOST_NO_0X_HDR_TUPLE // Use BOOST_NO_CXX11_HDR_TYPE_TRAITS instead of BOOST_NO_0X_HDR_TYPE_TRAITS // Use BOOST_NO_CXX11_HDR_TYPEINDEX instead of BOOST_NO_0X_HDR_TYPEINDEX // Use BOOST_NO_CXX11_HDR_UNORDERED_MAP instead of BOOST_NO_0X_HDR_UNORDERED_MAP // Use BOOST_NO_CXX11_HDR_UNORDERED_SET instead of BOOST_NO_0X_HDR_UNORDERED_SET // ------------------ End of deprecated macros for 1.50 --------------------------- ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Standard predeclarations ////////////////////////////////////////////////////////////////////////////// /// @cond namespace boost{ namespace intrusive{ //Create namespace to avoid compilation errors }} namespace boost{ namespace container{ namespace container_detail{ namespace bi = boost::intrusive; }}} // memory standard header // xmemory internal header (from ) // cstdlib standard header /*****************************************************************************/ /* stdlib.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* Attributes are only available in relaxed ANSI mode. */ /*---------------------------------------------------------------------------*/ //---------------------------------------------------------------------------- // IS RECOMMENDED OVER . IS PROVIDED FOR // COMPATIBILITY WITH C AND THIS USAGE IS DEPRECATED IN C++ //---------------------------------------------------------------------------- extern "C" namespace std { typedef struct { int quot, rem; } div_t; typedef struct { long quot, rem; } ldiv_t; typedef struct { long long quot, rem; } lldiv_t; /*---------------------------------------------------------------*/ /* NOTE - Normally, abs, labs, and fabs are expanded inline, so */ /* no formal definition is really required. However, ANSI */ /* requires that they exist as separate functions, so */ /* they are supplied in the library. The prototype is */ /* here mainly for documentation. */ /*---------------------------------------------------------------*/ int abs(int _val); long labs(long _val); long long llabs(long long _val); int atoi(const char *_st); long atol(const char *_st); long long atoll(const char *_st); int ltoa(long val, char *buffer); extern "C" double atof(const char *_st); long strtol(const char *_st, char **_endptr, int _base); unsigned long strtoul(const char *_st, char **_endptr, int _base); long long strtoll(const char *_st, char **_endptr, int _base); unsigned long long strtoull(const char *_st, char **_endptr, int _base); double strtod(const char *_st, char **_endptr); long double strtold(const char *_st, char **_endptr); int rand(void); void srand(unsigned _seed); void *calloc(size_t _num, size_t _size) __attribute__((malloc)); void *malloc(size_t _size) __attribute__((malloc)); void *realloc(void *_ptr, size_t _size) __attribute__((malloc)); void free(void *_ptr); void *memalign(size_t _aln, size_t _size) __attribute__((malloc)); void abort(void); int atexit(void (*_func)(void)); void *bsearch(const void *_key, const void *_base, size_t _nmemb, size_t _size, int (*compar)(const void *,const void *)); void qsort(void *_base, size_t _nmemb, size_t _size, int (*_compar)(const void *, const void *)); void exit(int _status); div_t div(int _numer, int _denom); ldiv_t ldiv(long _numer, long _denom); lldiv_t lldiv(long long _numer, long long _denom); char *getenv(const char *_string); int system(const char *_name); int mblen(const char *, size_t); size_t mbstowcs(wchar_t *, const char *, size_t); int mbtowc(wchar_t *, const char *, size_t); size_t wcstombs(char *, const wchar_t *, size_t); int wctomb(char *, wchar_t); } /* extern "C" namespace std */ namespace std { /* long OVERLOADS */ inline long abs(long _Left) { // compute abs return (labs(_Left)); } inline ldiv_t div(long _Left, long _Right) { // compute quotient and remainder return (ldiv(_Left, _Right)); } } namespace std { /* long long OVERLOADS */ inline long long abs(long long _Left) { // compute abs return (llabs(_Left)); } inline lldiv_t div(long long _Left, long long _Right) { // compute quotient and remainder return (lldiv(_Left, _Right)); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // new standard header namespace std { // CLASS bad_alloc class bad_alloc : public ::std:: exception { // base of all bad allocation exceptions public: bad_alloc(const char *_Message = "bad allocation") throw () : exception(_Message) { // construct from message string } // virtual ~bad_alloc() _THROW0() // {} // destroy the object }; } namespace std { // SUPPORT TYPES typedef void (*new_handler)(); // handler for operator new failures struct nothrow_t { // placement new tag type to suppress exceptions }; extern const far nothrow_t nothrow; // constant for placement new tag // FUNCTION AND OBJECT DECLARATIONS new_handler set_new_handler(new_handler) throw (); // establish alternate new handler extern far new_handler _New_hand; // pointer to current new handler } // new AND delete DECLARATIONS (NB: NOT IN std) void operator delete(void *) throw (); // delete allocated storage void *operator new(::std:: size_t) throw (::std:: bad_alloc); // allocate or throw exception void *operator new(::std:: size_t, const ::std:: nothrow_t&) throw (); // allocate or return null pointer void *operator new (std::size_t, void *ptr) throw (); void operator delete[](void *) throw (); // delete allocated array void *operator new[](::std:: size_t) throw (::std:: bad_alloc); // allocate array or throw exception void *operator new[](::std:: size_t, const ::std:: nothrow_t&) throw (); // allocate array or return null pointer void *operator new[](std::size_t, void *ptr) throw (); void operator delete(void *, const ::std:: nothrow_t&) throw (); // delete if nothrow new fails -- REPLACEABLE void operator delete[](void *, const ::std:: nothrow_t&) throw (); // delete if nothrow array new fails -- REPLACEABLE void operator delete(void *, void *) throw (); // {} // delete if placement new fails void operator delete[](void *, void *) throw (); // {} // delete if placement array new fails /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // xutility internal header // climits standard header /*****************************************************************************/ /* limits.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* TMS320C6X machine limits */ /*****************************************************************************/ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // MACROS struct _Container_base { // base of all containers }; struct _Iterator_base { // base of all iterators }; // ITERATOR STUFF (from ) // ITERATOR TAGS struct input_iterator_tag { // identifying tag for input iterators }; struct output_iterator_tag { // identifying tag for output iterators }; struct forward_iterator_tag : public input_iterator_tag { // identifying tag for forward iterators }; struct bidirectional_iterator_tag : public forward_iterator_tag { // identifying tag for bidirectional iterators }; struct random_access_iterator_tag : public bidirectional_iterator_tag { // identifying tag for random-access iterators }; struct _Int_iterator_tag { // identifying tag for integer types, not an iterator }; // POINTER ITERATOR TAGS struct _Nonscalar_ptr_iterator_tag { // pointer to unknown type }; struct _Scalar_ptr_iterator_tag { // pointer to scalar type }; // TEMPLATE CLASS iterator template struct iterator : public _Iterator_base { // base type for all iterator classes typedef _Category iterator_category; typedef _Ty value_type; typedef _Diff difference_type; typedef _Diff distance_type; // retained typedef _Pointer pointer; typedef _Reference reference; }; template struct _Bidit : public iterator { // base for bidirectional iterators }; template struct _Ranit : public iterator { // base for random-access iterators }; struct _Outit : public iterator { // base for output iterators }; // TEMPLATE CLASS iterator_traits template struct iterator_traits { // get traits from iterator _Iter typedef typename _Iter::iterator_category iterator_category; typedef typename _Iter::value_type value_type; typedef typename _Iter::difference_type difference_type; typedef difference_type distance_type; // retained typedef typename _Iter::pointer pointer; typedef typename _Iter::reference reference; }; template struct iterator_traits<_Ty *> { // get traits from pointer typedef random_access_iterator_tag iterator_category; typedef _Ty value_type; typedef ptrdiff_t difference_type; typedef ptrdiff_t distance_type; // retained typedef _Ty *pointer; typedef _Ty& reference; }; template struct iterator_traits { // get traits from const pointer typedef random_access_iterator_tag iterator_category; typedef _Ty value_type; typedef ptrdiff_t difference_type; typedef ptrdiff_t distance_type; // retained typedef const _Ty *pointer; typedef const _Ty& reference; }; template<> struct iterator_traits<_Bool> { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; template<> struct iterator_traits { // get traits from integer type typedef _Int_iterator_tag iterator_category; }; // TEMPLATE FUNCTION _Iter_cat template inline typename iterator_traits<_Iter>::iterator_category _Iter_cat(const _Iter&) { // return category from iterator argument typename iterator_traits<_Iter>::iterator_category _Cat; return (_Cat); } // TEMPLATE FUNCTION _Ptr_cat template inline _Nonscalar_ptr_iterator_tag _Ptr_cat(_T1&, _T2&) { // return pointer category from arbitrary arguments _Nonscalar_ptr_iterator_tag _Cat; return (_Cat); } template inline _Scalar_ptr_iterator_tag _Ptr_cat(_Ty **, _Ty **) { // return pointer category from pointer to pointer arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } template inline _Scalar_ptr_iterator_tag _Ptr_cat(_Ty *const *, _Ty **) { // return pointer category from pointer to pointer arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } template inline _Scalar_ptr_iterator_tag _Ptr_cat(_Ty **, const _Ty **) { // return pointer category from pointer to pointer arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } template inline _Scalar_ptr_iterator_tag _Ptr_cat(_Ty *const *, const _Ty **) { // return pointer category from pointer to pointer arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } // INTEGER FUNCTION _Ptr_cat inline _Scalar_ptr_iterator_tag _Ptr_cat(_Bool *, _Bool *) { // return pointer category from pointer to bool arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const _Bool *, _Bool *) { // return pointer category from pointer to bool arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(char *, char *) { // return pointer category from pointer to char arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const char *, char *) { // return pointer category from pointer to char arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(signed char *, signed char *) { // return pointer category from pointer to signed char arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const signed char *, signed char *) { // return pointer category from pointer to signed char arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned char *, unsigned char *) { // return pointer category from pointer to unsigned char arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned char *, unsigned char *) { // return pointer category from pointer to unsigned char arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(wchar_t *, wchar_t *) { // return pointer category from pointer to wchar_t arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const wchar_t *, wchar_t *) { // return pointer category from pointer to wchar_t arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(short *, short *) { // return pointer category from pointer to short arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const short *, short *) { // return pointer category from pointer to short arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned short *, unsigned short *) { // return pointer category from pointer to unsigned short arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned short *, unsigned short *) { // return pointer category from pointer to unsigned short arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(int *, int *) { // return pointer category from pointer to int arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const int *, int *) { // return pointer category from pointer to int arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned int *, unsigned int *) { // return pointer category from pointer to unsigned int arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned int *, unsigned int *) { // return pointer category from pointer to unsigned int arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(long *, long *) { // return pointer category from pointer to long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const long *, long *) { // return pointer category from pointer to long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned long *, unsigned long *) { // return pointer category from pointer to unsigned long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned long *, unsigned long *) { // return pointer category from pointer to unsigned long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(float *, float *) { // return pointer category from pointer to float arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const float *, float *) { // return pointer category from pointer to float arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(double *, double *) { // return pointer category from pointer to double arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const double *, double *) { // return pointer category from pointer to double arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(long double *, long double *) { // return pointer category from pointer to long double arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const long double *, long double *) { // return pointer category from pointer to long double arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(long long *, long long *) { // return pointer category from pointer to long long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const long long *, long long *) { // return pointer category from pointer to long long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned long long *, unsigned long long *) { // return pointer category from pointer to ulong long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned long long *, unsigned long long *) { // return pointer category from pointer to ulong long arguments _Scalar_ptr_iterator_tag _Cat; return (_Cat); } // ITERATOR DEBUGGING MACROS // TEMPLATE FUNCTION _Val_type template inline typename iterator_traits<_Iter>::value_type *_Val_type(_Iter) { // return value type from arbitrary argument return (0); } // TEMPLATE FUNCTION advance template inline void advance(_InIt& _Where, _Diff _Off) { // increment iterator by offset, arbitrary iterators _Advance(_Where, _Off, _Iter_cat(_Where)); } template inline void _Advance(_InIt& _Where, _Diff _Off, input_iterator_tag) { // increment iterator by offset, input iterators for (; 0 < _Off; --_Off) ++_Where; } template inline void _Advance(_FI& _Where, _Diff _Off, forward_iterator_tag) { // increment iterator by offset, forward iterators for (; 0 < _Off; --_Off) ++_Where; } template inline void _Advance(_BI& _Where, _Diff _Off, bidirectional_iterator_tag) { // increment iterator by offset, bidirectional iterators for (; 0 < _Off; --_Off) ++_Where; for (; _Off < 0; ++_Off) --_Where; } template inline void _Advance(_RI& _Where, _Diff _Off, random_access_iterator_tag) { // increment iterator by offset, random-access iterators _Where += _Off; } // TEMPLATE FUNCTION _Dist_type template inline typename iterator_traits<_Iter>::difference_type *_Dist_type(_Iter) { // return distance type from arbitrary argument return (0); } // TEMPLATE FUNCTIONS distance and _Distance template inline void _Distance2(_InIt _First, _InIt _Last, _Diff& _Off, input_iterator_tag) { // add to _Off distance between input iterators for (; _First != _Last; ++_First) ++_Off; } template inline void _Distance2(_FwdIt _First, _FwdIt _Last, _Diff& _Off, forward_iterator_tag) { // add to _Off distance between forward iterators (redundant) for (; _First != _Last; ++_First) ++_Off; } template inline void _Distance2(_BidIt _First, _BidIt _Last, _Diff& _Off, bidirectional_iterator_tag) { // add to _Off distance between bidirectional iterators (redundant) for (; _First != _Last; ++_First) ++_Off; } template inline void _Distance2(_RanIt _First, _RanIt _Last, _Diff& _Off, random_access_iterator_tag) { // add to _Off distance between random-access iterators _Off += _Last - _First; } template inline typename iterator_traits<_InIt>::difference_type distance(_InIt _First, _InIt _Last) { // return distance between iterators typename iterator_traits<_InIt>::difference_type _Off = 0; _Distance2(_First, _Last, _Off, _Iter_cat(_First)); return (_Off); } template inline void _Distance(_InIt _First, _InIt _Last, _Diff& _Off) { // add to _Off distance between iterators _Distance2(_First, _Last, _Off, _Iter_cat(_First)); } // TEMPLATE CLASS reverse_iterator template class reverse_iterator : public iterator< typename iterator_traits<_RanIt>::iterator_category, typename iterator_traits<_RanIt>::value_type, typename iterator_traits<_RanIt>::difference_type, typename iterator_traits<_RanIt>::pointer, typename iterator_traits<_RanIt>::reference> { // wrap iterator to run it backwards public: typedef reverse_iterator<_RanIt> _Myt; typedef typename iterator_traits<_RanIt>::difference_type difference_type; typedef typename iterator_traits<_RanIt>::pointer pointer; typedef typename iterator_traits<_RanIt>::reference reference; typedef _RanIt iterator_type; reverse_iterator() { // construct with default wrapped iterator } explicit reverse_iterator(_RanIt _Right) : current(_Right) { // construct wrapped iterator from _Right } template reverse_iterator(const reverse_iterator<_Other>& _Right) : current(_Right.base()) { // initialize with compatible base } _RanIt base() const { // return wrapped iterator return (current); } reference operator*() const { // return designated value _RanIt _Tmp = current; return (*--_Tmp); } pointer operator->() const { // return pointer to class object return (&**this); } _Myt& operator++() { // preincrement --current; return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; --current; return (_Tmp); } _Myt& operator--() { // predecrement ++current; return (*this); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; ++current; return (_Tmp); } bool _Equal(const _Myt& _Right) const { // test for iterator equality return (current == _Right.current); } // N.B. functions valid for random-access iterators only beyond this point _Myt& operator+=(difference_type _Off) { // increment by integer current -= _Off; return (*this); } _Myt operator+(difference_type _Off) const { // return this + integer return (_Myt(current - _Off)); } _Myt& operator-=(difference_type _Off) { // decrement by integer current += _Off; return (*this); } _Myt operator-(difference_type _Off) const { // return this - integer return (_Myt(current + _Off)); } reference operator[](difference_type _Off) const { // subscript return (*(*this + _Off)); } bool _Less(const _Myt& _Right) const { // test if this < _Right return (_Right.current < current); } difference_type _Minus(const _Myt& _Right) const { // return difference of iterators return (_Right.current - current); } protected: _RanIt current; // the wrapped iterator }; // reverse_iterator TEMPLATE OPERATORS template inline reverse_iterator<_RanIt> operator+(_Diff _Off, const reverse_iterator<_RanIt>& _Right) { // return reverse_iterator + integer return (_Right + _Off); } template inline typename reverse_iterator<_RanIt>::difference_type operator-(const reverse_iterator<_RanIt>& _Left, const reverse_iterator<_RanIt>& _Right) { // return difference of reverse_iterators return (_Left._Minus(_Right)); } template inline bool operator==(const reverse_iterator<_RanIt>& _Left, const reverse_iterator<_RanIt>& _Right) { // test for reverse_iterator equality return (_Left._Equal(_Right)); } template inline bool operator!=(const reverse_iterator<_RanIt>& _Left, const reverse_iterator<_RanIt>& _Right) { // test for reverse_iterator inequality return (!(_Left == _Right)); } template inline bool operator<(const reverse_iterator<_RanIt>& _Left, const reverse_iterator<_RanIt>& _Right) { // test for reverse_iterator < reverse_iterator return (_Left._Less(_Right)); } template inline bool operator>(const reverse_iterator<_RanIt>& _Left, const reverse_iterator<_RanIt>& _Right) { // test for reverse_iterator > reverse_iterator return (_Right < _Left); } template inline bool operator<=(const reverse_iterator<_RanIt>& _Left, const reverse_iterator<_RanIt>& _Right) { // test for reverse_iterator <= reverse_iterator return (!(_Right < _Left)); } template inline bool operator>=(const reverse_iterator<_RanIt>& _Left, const reverse_iterator<_RanIt>& _Right) { // test for reverse_iterator >= reverse_iterator return (!(_Left < _Right)); } // TEMPLATE CLASS reverse_bidirectional_iterator (retained) template class reverse_bidirectional_iterator : public _Bidit<_Ty, _Diff, _Pointer, _Reference> { // wrap bidirectional iterator to run it backwards public: typedef reverse_bidirectional_iterator<_BidIt, _Ty, _Reference, _Pointer, _Diff> _Myt; typedef _BidIt iterator_type; reverse_bidirectional_iterator() { // construct with default wrapped iterator } explicit reverse_bidirectional_iterator(_BidIt _Right) : current(_Right) { // construct wrapped iterator from _Right } _BidIt base() const { // return wrapped iterator return (current); } _Reference operator*() const { // return designated value _BidIt _Tmp = current; return (*--_Tmp); } _Pointer operator->() const { // return pointer to class object _Reference _Tmp = **this; return (&_Tmp); } _Myt& operator++() { // preincrement --current; return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; --current; return (_Tmp); } _Myt& operator--() { // predecrement ++current; return (*this); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; ++current; return (_Tmp); } bool operator==(const _Myt& _Right) const { // test for iterator equality return (current == _Right.current); } bool operator!=(const _Myt& _Right) const { // test for iterator inequality return (!(*this == _Right)); } protected: _BidIt current; // the wrapped iterator }; // TEMPLATE CLASS _Revbidit template class _Revbidit : public iterator< typename iterator_traits<_BidIt>::iterator_category, typename iterator_traits<_BidIt>::value_type, typename iterator_traits<_BidIt>::difference_type, typename iterator_traits<_BidIt>::pointer, typename iterator_traits<_BidIt>::reference> { // wrap bidirectional iterator to run it backwards public: typedef _Revbidit<_BidIt, _BidIt2> _Myt; typedef typename iterator_traits<_BidIt>::difference_type _Diff; typedef typename iterator_traits<_BidIt>::pointer _Pointer; typedef typename iterator_traits<_BidIt>::reference _Reference; typedef _BidIt iterator_type; _Revbidit() { // construct with default wrapped iterator } explicit _Revbidit(_BidIt _Right) : current(_Right) { // construct wrapped iterator from _Right } _Revbidit(const _Revbidit<_BidIt2>& _Other) : current (_Other.base()) { // const converter or copy constructor } _BidIt base() const { // return wrapped iterator return (current); } _Reference operator*() const { // return designated value _BidIt _Tmp = current; return (*--_Tmp); } _Pointer operator->() const { // return pointer to class object _Reference _Tmp = **this; return (&_Tmp); } _Myt& operator++() { // preincrement --current; return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; --current; return (_Tmp); } _Myt& operator--() { // predecrement ++current; return (*this); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; ++current; return (_Tmp); } bool operator==(const _Myt& _Right) const { // test for iterator equality return (current == _Right.current); } bool operator!=(const _Myt& _Right) const { // test for iterator inequality return (!(*this == _Right)); } protected: _BidIt current; }; // TEMPLATE CLASS istreambuf_iterator template class istreambuf_iterator : public iterator { // wrap stream buffer as input iterator typedef istreambuf_iterator<_Elem, _Traits> _Myt; public: typedef _Elem char_type; typedef _Traits traits_type; typedef basic_streambuf<_Elem, _Traits> streambuf_type; typedef basic_istream<_Elem, _Traits> istream_type; typedef typename traits_type::int_type int_type; istreambuf_iterator(streambuf_type *_Sb = 0) throw () : _Strbuf(_Sb), _Got(_Sb == 0) { // construct from stream buffer _Sb } istreambuf_iterator(istream_type& _Istr) throw () : _Strbuf(_Istr.rdbuf()), _Got(_Istr.rdbuf() == 0) { // construct from stream buffer in istream _Istr } _Elem operator*() const { // return designated value if (!_Got) ((_Myt *)this)->_Peek(); return (_Val); } _Myt& operator++() { // preincrement _Inc(); return (*this); } _Myt operator++(int) { // postincrement if (!_Got) _Peek(); _Myt _Tmp = *this; ++*this; return (_Tmp); } bool equal(const _Myt& _Right) const { // test for equality if (!_Got) ((_Myt *)this)->_Peek(); if (!_Right._Got) ((_Myt *)&_Right)->_Peek(); return (_Strbuf == 0 && _Right._Strbuf == 0 || _Strbuf != 0 && _Right._Strbuf != 0); } private: void _Inc() { // skip to next input element if (_Strbuf == 0 || traits_type::eq_int_type(traits_type::eof(), _Strbuf->sbumpc())) _Strbuf = 0, _Got = true; else _Got = false; } _Elem _Peek() { // peek at next input element int_type _Meta; if (_Strbuf == 0 || traits_type::eq_int_type(traits_type::eof(), _Meta = _Strbuf->sgetc())) _Strbuf = 0; else _Val = traits_type::to_char_type(_Meta); _Got = true; return (_Val); } streambuf_type *_Strbuf; // the wrapped stream buffer bool _Got; // true if _Val is valid _Elem _Val; // next element to deliver }; // istreambuf_iterator TEMPLATE OPERATORS template inline bool operator==( const istreambuf_iterator<_Elem, _Traits>& _Left, const istreambuf_iterator<_Elem, _Traits>& _Right) { // test for istreambuf_iterator equality return (_Left.equal(_Right)); } template inline bool operator!=( const istreambuf_iterator<_Elem, _Traits>& _Left, const istreambuf_iterator<_Elem, _Traits>& _Right) { // test for istreambuf_iterator inequality return (!(_Left == _Right)); } // TEMPLATE CLASS ostreambuf_iterator template class ostreambuf_iterator : public _Outit { // wrap stream buffer as output iterator typedef ostreambuf_iterator<_Elem, _Traits> _Myt; public: typedef _Elem char_type; typedef _Traits traits_type; typedef basic_streambuf<_Elem, _Traits> streambuf_type; typedef basic_ostream<_Elem, _Traits> ostream_type; ostreambuf_iterator(streambuf_type *_Sb) throw () : _Failed(false), _Strbuf(_Sb) { // construct from stream buffer _Sb } ostreambuf_iterator(ostream_type& _Ostr) throw () : _Failed(false), _Strbuf(_Ostr.rdbuf()) { // construct from stream buffer in _Ostr } _Myt& operator=(_Elem _Right) { // store element and increment if (_Strbuf == 0 || traits_type::eq_int_type(_Traits::eof(), _Strbuf->sputc(_Right))) _Failed = true; return (*this); } _Myt& operator*() { // pretend to get designated element return (*this); } _Myt& operator++() { // pretend to preincrement return (*this); } _Myt& operator++(int) { // pretend to postincrement return (*this); } bool failed() const throw () { // return true if any stores failed return (_Failed); } private: bool _Failed; // true if any stores have failed streambuf_type *_Strbuf; // the wrapped stream buffer }; // ALGORITHM STUFF (from ) // TEMPLATE FUNCTION copy template inline _OutIt _Copy_opt(_InIt _First, _InIt _Last, _OutIt _Dest, _Nonscalar_ptr_iterator_tag) { // copy [_First, _Last) to [_Dest, ...), arbitrary iterators ; for (; _First != _Last; ++_Dest, ++_First) *_Dest = *_First; return (_Dest); } template inline _OutIt _Copy_opt(_InIt _First, _InIt _Last, _OutIt _Dest, _Scalar_ptr_iterator_tag) { // copy [_First, _Last) to [_Dest, ...), pointers to scalars ptrdiff_t _Off = _Last - _First; // NB: non-overlapping move return ((_OutIt)::std:: memmove(&*_Dest, &*_First, _Off * sizeof (*_First)) + _Off); } template inline _OutIt copy(_InIt _First, _InIt _Last, _OutIt _Dest) { // copy [_First, _Last) to [_Dest, ...) return (_Copy_opt(_First, _Last, _Dest, _Ptr_cat(_First, _Dest))); } // TEMPLATE FUNCTION copy_backward template inline _BidIt2 _Copy_backward_opt(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest, _Nonscalar_ptr_iterator_tag) { // copy [_First, _Last) backwards to [..., _Dest), arbitrary iterators ; while (_First != _Last) *--_Dest = *--_Last; return (_Dest); } template inline _OutIt _Copy_backward_opt(_InIt _First, _InIt _Last, _OutIt _Dest, _Scalar_ptr_iterator_tag) { // copy [_First, _Last) backwards to [..., _Dest), pointers to scalars ptrdiff_t _Off = _Last - _First; // NB: non-overlapping move return ((_OutIt)memmove(&*_Dest - _Off, &*_First, _Off * sizeof (*_First))); } template inline _BidIt2 copy_backward(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest) { // copy [_First, _Last) backwards to [..., _Dest) return (_Copy_backward_opt(_First, _Last, _Dest, _Ptr_cat(_First, _Dest))); } // TEMPLATE FUNCTION mismatch template inline pair<_InIt1, _InIt2> mismatch(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2) { // return [_First1, _Last1) and [_First2, _Last2) mismatch for (; _First1 != _Last1 && *_First1 == *_First2; ) ++_First1, ++_First2; return (pair<_InIt1, _InIt2>(_First1, _First2)); } // TEMPLATE FUNCTION mismatch WITH PRED template inline pair<_InIt1, _InIt2> mismatch(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Pr _Pred) { // return [_First1, _Last1) and [_First2, _Last2) mismatch using _Pred for (; _First1 != _Last1 && _Pred(*_First1, *_First2); ) ++_First1, ++_First2; return (pair<_InIt1, _InIt2>(_First1, _First2)); } // TEMPLATE FUNCTION equal template inline bool equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2) { // compare [_First1, _Last1) to [First2, ...) return (mismatch(_First1, _Last1, _First2).first == _Last1); } inline bool equal(const char *_First1, const char *_Last1, const char *_First2) { // compare [_First1, _Last1) to [First2, ...), for chars return (::std:: memcmp(_First1, _First2, _Last1 - _First1) == 0); } inline bool equal(const signed char *_First1, const signed char *_Last1, const signed char *_First2) { // compare [_First1, _Last1) to [First2, ...), for signed chars return (::std:: memcmp(_First1, _First2, _Last1 - _First1) == 0); } inline bool equal(const unsigned char *_First1, const unsigned char *_Last1, const unsigned char *_First2) { // compare [_First1, _Last1) to [First2, ...), for unsigned chars return (::std:: memcmp(_First1, _First2, _Last1 - _First1) == 0); } // TEMPLATE FUNCTION equal WITH PRED template inline bool equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Pr _Pred) { // compare [_First1, _Last1) to [First2, ...) using _Pred return (mismatch(_First1, _Last1, _First2, _Pred).first == _Last1); } // TEMPLATE FUNCTION fill template inline void fill(_FwdIt _First, _FwdIt _Last, const _Ty& _Val) { // copy _Val through [_First, _Last) ; for (; _First != _Last; ++_First) *_First = _Val; } inline void fill(char *_First, char *_Last, int _Val) { // copy char _Val through [_First, _Last) ; ::std:: memset(_First, _Val, _Last - _First); } inline void fill(signed char *_First, signed char *_Last, int _Val) { // copy signed char _Val through [_First, _Last) ; ::std:: memset(_First, _Val, _Last - _First); } inline void fill(unsigned char *_First, unsigned char *_Last, int _Val) { // copy unsigned char _Val through [_First, _Last) ; ::std:: memset(_First, _Val, _Last - _First); } // TEMPLATE FUNCTION fill_n template inline void fill_n(_OutIt _First, _Diff _Count, const _Ty& _Val) { // copy _Val _Count times through [_First, ...) for (; 0 < _Count; --_Count, ++_First) *_First = _Val; } inline void fill_n(char *_First, size_t _Count, int _Val) { // copy char _Val _Count times through [_First, ...) ::std:: memset(_First, _Val, _Count); } inline void fill_n(signed char *_First, size_t _Count, int _Val) { // copy signed char _Val _Count times through [_First, ...) ::std:: memset(_First, _Val, _Count); } inline void fill_n(unsigned char *_First, size_t _Count, int _Val) { // copy unsigned char _Val _Count times through [_First, ...) ::std:: memset(_First, _Val, _Count); } // TEMPLATE FUNCTION lexicographical_compare template inline bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2) { // order [_First1, _Last1) vs. [First2, Last2) ; ; for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2) if (((*_First1) < (*_First2))) return (true); else if (*_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) { // order [_First1, _Last1) vs. [First2, Last2), for unsigned char ; ; ptrdiff_t _Num1 = _Last1 - _First1; ptrdiff_t _Num2 = _Last2 - _First2; int _Ans = ::std:: memcmp(_First1, _First2, _Num1 < _Num2 ? _Num1 : _Num2); return (_Ans < 0 || _Ans == 0 && _Num1 < _Num2); } // TEMPLATE FUNCTION lexicographical_compare WITH PRED template inline bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _Pr _Pred) { // order [_First1, _Last1) vs. [First2, Last2) using _Pred ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2) if (_Pred(*_First1, *_First2)) return (true); else if (_Pred(*_First2, *_First1)) return (false); return (_First1 == _Last1 && _First2 != _Last2); } // TEMPLATE FUNCTION max template inline const _Ty& max(const _Ty& _Left, const _Ty& _Right) { // return larger of _Left and _Right return (((_Left) < (_Right)) ? _Right : _Left); } // TEMPLATE FUNCTION max WITH PRED template inline const _Ty& max(const _Ty& _Left, const _Ty& _Right, _Pr _Pred) { // return larger of _Left and _Right using _Pred return (_Pred(_Left, _Right) ? _Right : _Left); } // TEMPLATE FUNCTION min template inline const _Ty& min(const _Ty& _Left, const _Ty& _Right) { // return smaller of _Left and _Right return (((_Right) < (_Left)) ? _Right : _Left); } // TEMPLATE FUNCTION min WITH PRED template inline const _Ty& min(const _Ty& _Left, const _Ty& _Right, _Pr _Pred) { // return smaller of _Left and _Right using _Pred return (_Pred(_Right, _Left) ? _Right : _Left); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */ /* * This file is derived from software bearing the following * restrictions: * * 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. V4.02:1476 */ namespace std { // TEMPLATE FUNCTION _Allocate template inline _Ty *_Allocate(size_t _Count, _Ty *) { // allocate storage for _Count elements of type _Ty return ((_Ty *)::operator new(_Count * sizeof (_Ty))); } // TEMPLATE FUNCTION _Construct template inline void _Construct(_T1 *_Ptr, const _T2& _Val) { // construct object at _Ptr with value _Val void *_Vptr = _Ptr; new (_Vptr) _T1(_Val); } // TEMPLATE FUNCTION _Destroy template inline void _Destroy(_Ty *_Ptr) { // destroy object at _Ptr (_Ptr)->~_Ty(); } template<> inline void _Destroy(char *) { // destroy a char (do nothing) } template<> inline void _Destroy(wchar_t *) { // destroy a wchar_t (do nothing) } // TEMPLATE CLASS _Allocator_base template struct _Allocator_base { // base class for generic allocators typedef _Ty value_type; }; // TEMPLATE CLASS allocator template class allocator : public _Allocator_base<_Ty> { // generic allocator for objects of class _Ty public: typedef _Allocator_base<_Ty> _Mybase; typedef typename _Mybase::value_type value_type; typedef value_type *pointer; typedef value_type & reference; typedef const value_type *const_pointer; typedef const value_type & const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { // convert an allocator<_Ty> to an allocator <_Other> typedef allocator<_Other> other; }; pointer address(reference _Val) const { // return address of mutable _Val return (&_Val); } const_pointer address(const_reference _Val) const { // return address of nonmutable _Val return (&_Val); } allocator() throw () { // construct default allocator (do nothing) } allocator(const allocator<_Ty>&) throw () { // construct by copying (do nothing) } template allocator(const allocator<_Other>&) throw () { // construct from a related allocator (do nothing) } template allocator<_Ty>& operator=(const allocator<_Other>&) { // assign from a related allocator (do nothing) return (*this); } void deallocate(pointer _Ptr, size_type) { // deallocate object at _Ptr, ignore size ::operator delete(_Ptr); } pointer allocate(size_type _Count) { // allocate array of _Count elements return (_Allocate(_Count, (pointer)0)); } pointer allocate(size_type _Count, const void *) { // allocate array of _Count elements, ignore hint return (allocate(_Count)); } void construct(pointer _Ptr, const _Ty& _Val) { // construct object at _Ptr with value _Val _Construct(_Ptr, _Val); } void destroy(pointer _Ptr) { // destroy object at _Ptr _Destroy(_Ptr); } size_t max_size() const throw () { // estimate maximum array size size_t _Count = (size_t)(-1) / sizeof (_Ty); return (0 < _Count ? _Count : 1); } }; // allocator TEMPLATE OPERATORS template inline bool operator==(const allocator<_Ty>&, const allocator<_Other>&) throw () { // test for allocator equality (always true) return (true); } template inline bool operator!=(const allocator<_Ty>&, const allocator<_Other>&) throw () { // test for allocator inequality (always false) return (false); } // CLASS allocator template<> class allocator { // generic allocator for type void public: typedef void _Ty; typedef _Ty *pointer; typedef const _Ty *const_pointer; typedef _Ty value_type; template struct rebind { // convert an allocator to an allocator <_Other> typedef allocator<_Other> other; }; allocator() throw () { // construct default allocator (do nothing) } allocator(const allocator<_Ty>&) throw () { // construct by copying (do nothing) } template allocator(const allocator<_Other>&) throw () { // construct from related allocator (do nothing) } template allocator<_Ty>& operator=(const allocator<_Other>&) { // assign from a related allocator (do nothing) return (*this); } }; // TEMPLATE FUNCTION _Destroy_range template inline void _Destroy_range(_Ty *_First, _Ty *_Last, _Alloc& _Al) { // destroy [_First, _Last) _Destroy_range(_First, _Last, _Al, _Ptr_cat(_First, _Last)); } template inline void _Destroy_range(_Ty *_First, _Ty *_Last, _Alloc& _Al, _Nonscalar_ptr_iterator_tag) { // destroy [_First, _Last), arbitrary type for (; _First != _Last; ++_First) _Al.destroy(_First); } template inline void _Destroy_range(_Ty *_First, _Ty *_Last, _Alloc& _Al, _Scalar_ptr_iterator_tag) { // destroy [_First, _Last), scalar type (do nothing) } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */ /* * This file is derived from software bearing the following * restrictions: * * 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. V4.02:1476 */ namespace std { // TEMPLATE FUNCTION get_temporary_buffer template inline pair<_Ty *, ptrdiff_t> get_temporary_buffer(ptrdiff_t _Count) { // get raw temporary buffer of up to _Count elements _Ty *_Pbuf; for (_Pbuf = 0; 0 < _Count; _Count /= 2) if ((_Pbuf = (_Ty *)operator new( (size_t)_Count * sizeof (_Ty), nothrow)) != 0) break; return (pair<_Ty *, ptrdiff_t>(_Pbuf, _Count)); } // TEMPLATE FUNCTION return_temporary_buffer template inline void return_temporary_buffer(_Ty *_Pbuf) { // delete raw temporary buffer operator delete(_Pbuf); } // TEMPLATE FUNCTION uninitialized_copy template inline _FwdIt _Uninit_copy(_InIt _First, _InIt _Last, _FwdIt _Dest, _Nonscalar_ptr_iterator_tag) { // copy [_First, _Last) to raw _Dest, arbitrary type ; ; _FwdIt _Next = _Dest; try { for (; _First != _Last; ++_Dest, ++_First) _Construct(&*_Dest, *_First); } catch (...) { for (; _Next != _Dest; ++_Next) _Destroy(&*_Next); throw; } return (_Dest); } template inline _Ty2 *_Uninit_copy(_Ty1 *_First, _Ty1 *_Last, _Ty2 *_Dest, _Scalar_ptr_iterator_tag) { // copy [_First, _Last) to raw _Dest, scalar type ; ; size_t _Count = (size_t)(_Last - _First); return ((_Ty2 *)memmove(&*_Dest, &*_First, _Count * sizeof (*_First)) + _Count); // NB: non-overlapping move } template inline _FwdIt uninitialized_copy(_InIt _First, _InIt _Last, _FwdIt _Dest) { // copy [_First, _Last) to raw _Dest return (_Uninit_copy(_First, _Last, _Dest, _Ptr_cat(_First, _Dest))); } // TEMPLATE FUNCTION _Uninitialized_copy WITH ALLOCATOR template inline _FwdIt _Uninit_copy(_InIt _First, _InIt _Last, _FwdIt _Dest, _Alloc& _Al, _Nonscalar_ptr_iterator_tag) { // copy [_First, _Last) to raw _Dest, using _Al, arbitrary type ; ; _FwdIt _Next = _Dest; try { for (; _First != _Last; ++_Dest, ++_First) _Al.construct(_Dest, *_First); } catch (...) { for (; _Next != _Dest; ++_Next) _Al.destroy(_Next); throw; } return (_Dest); } template inline _FwdIt _Uninit_copy(_InIt _First, _InIt _Last, _FwdIt _Dest, _Alloc& _Al, _Scalar_ptr_iterator_tag) { // copy [_First, _Last) to raw _Dest, using _Al, scalar type return (_Uninit_copy(_First, _Last, _Dest, _Al, _Nonscalar_ptr_iterator_tag())); } template inline _Ty2 *_Uninit_copy(_Ty1 *_First, _Ty1 *_Last, _Ty2 *_Dest, allocator<_Ty2>&, _Scalar_ptr_iterator_tag) { // copy [_First, _Last) to raw _Dest, scalar type ; ; size_t _Count = (size_t)(_Last - _First); return ((_Ty2 *)memmove(&*_Dest, &*_First, _Count * sizeof (*_First)) + _Count); // NB: non-overlapping move } template inline _FwdIt _Uninitialized_copy(_InIt _First, _InIt _Last, _FwdIt _Dest, _Alloc& _Al) { // copy [_First, _Last) to raw _Dest, using _Al return (_Uninit_copy(_First, _Last, _Dest, _Al, _Ptr_cat(_First, _Dest))); } // TEMPLATE FUNCTION uninitialized_fill template inline void _Uninit_fill(_FwdIt _First, _FwdIt _Last, const _Tval& _Val, _Nonscalar_ptr_iterator_tag) { // copy _Val throughout raw [_First, _Last), arbitrary type ; _FwdIt _Next = _First; try { for (; _First != _Last; ++_First) _Construct(&*_First, _Val); } catch (...) { for (; _Next != _First; ++_Next) _Destroy(&*_Next); throw; } } template inline void _Uninit_fill(_Ty *_First, _Ty *_Last, const _Tval& _Val, _Scalar_ptr_iterator_tag) { // copy _Val throughout raw [_First, _Last), scalar type ::std:: fill(_First, _Last, _Val); } template inline void uninitialized_fill(_FwdIt _First, _FwdIt _Last, const _Tval& _Val) { // copy _Val throughout raw [_First, _Last) _Uninit_fill(_First, _Last, _Val, _Ptr_cat(_First, _First)); } // TEMPLATE FUNCTION uninitialized_fill_n template inline void _Uninit_fill_n(_FwdIt _First, _Diff _Count, const _Tval& _Val, _Nonscalar_ptr_iterator_tag) { // copy _Count *_Val to raw _First, arbitrary type _FwdIt _Next = _First; try { for (; 0 < _Count; --_Count, ++_First) _Construct(&*_First, _Val); } catch (...) { for (; _Next != _First; ++_Next) _Destroy(&*_Next); throw; } } template inline void _Uninit_fill_n(_Ty *_First, _Diff _Count, const _Tval& _Val, _Scalar_ptr_iterator_tag) { // copy _Count *_Val to raw _First, scalar type ::std:: fill_n(_First, _Count, _Val); } template inline void uninitialized_fill_n(_FwdIt _First, _Diff _Count, const _Tval& _Val) { // copy _Count *_Val to raw _First _Uninit_fill_n(_First, _Count, _Val, _Ptr_cat(_First, _First)); } // TEMPLATE FUNCTION _Uninitialized_fill_n WITH ALLOCATOR template inline void _Uninit_fill_n(_FwdIt _First, _Diff _Count, const _Tval& _Val, _Alloc& _Al, _Nonscalar_ptr_iterator_tag) { // copy _Count *_Val to raw _First, using _Al, arbitrary type _FwdIt _Next = _First; try { for (; 0 < _Count; --_Count, ++_First) _Al.construct(_First, _Val); } catch (...) { for (; _Next != _First; ++_Next) _Al.destroy(_Next); throw; } } template inline void _Uninit_fill_n(_FwdIt _First, _Diff _Count, const _Tval& _Val, _Alloc& _Al, _Scalar_ptr_iterator_tag) { // copy _Count *_Val to raw _First, using _Al, arbitrary type _Uninit_fill_n(_First, _Count, _Val, _Al, _Nonscalar_ptr_iterator_tag()); } template inline void _Uninit_fill_n(_Ty *_First, _Diff _Count, const _Tval& _Val, allocator<_Ty>&, _Scalar_ptr_iterator_tag) { // copy _Count *_Val to raw _First, using _Al, scalar type fill_n(_First, _Count, _Val); } template inline void _Uninitialized_fill_n(_FwdIt _First, _Diff _Count, const _Tval& _Val, _Alloc& _Al) { // copy _Count *_Val to raw _First, using _Al _Uninit_fill_n(_First, _Count, _Val, _Al, _Ptr_cat(_First, _First)); } // TEMPLATE CLASS raw_storage_iterator template class raw_storage_iterator : public _Outit { // wrap stores to raw buffer as output iterator public: typedef _FwdIt iterator_type; // retained typedef _FwdIt iter_type; // retained typedef _Ty element_type; // retained explicit raw_storage_iterator(_FwdIt _First) : _Next(_First) { // construct with iterator } raw_storage_iterator<_FwdIt, _Ty>& operator*() { // pretend to return designated value return (*this); } raw_storage_iterator<_FwdIt, _Ty>& operator=(const _Ty& _Val) { // construct value designated by stored iterator _Construct(&*_Next, _Val); return (*this); } raw_storage_iterator<_FwdIt, _Ty>& operator++() { // preincrement ++_Next; return (*this); } raw_storage_iterator<_FwdIt, _Ty> operator++(int) { // postincrement raw_storage_iterator<_FwdIt, _Ty> _Ans = *this; ++_Next; return (_Ans); } private: _FwdIt _Next; // the stored iterator }; // TEMPLATE CLASS _Temp_iterator template class _Temp_iterator : public _Outit { // wrap stores to temporary buffer as output iterator public: typedef _Ty *_Pty; _Temp_iterator(ptrdiff_t _Count = 0) { // construct from desired temporary buffer size pair<_Pty, ptrdiff_t> _Pair = ::std:: get_temporary_buffer<_Ty>(_Count); _Buf._Begin = _Pair.first; _Buf._Current = _Pair.first; _Buf._Hiwater = _Pair.first; _Buf._Size = _Pair.second; _Pbuf = &_Buf; } _Temp_iterator(const _Temp_iterator<_Ty>& _Right) { // construct from _Right (share active buffer) _Buf._Begin = 0; // clear stored buffer, to be tidy _Buf._Current = 0; _Buf._Hiwater = 0; _Buf._Size = 0; *this = _Right; } ~_Temp_iterator() { // destroy the object if (_Buf._Begin != 0) { // destroy any constructed elements in buffer for (_Pty _Next = _Buf._Begin; _Next != _Buf._Hiwater; ++_Next) _Destroy(&*_Next); ::std:: return_temporary_buffer(_Buf._Begin); } } _Temp_iterator<_Ty>& operator=(const _Temp_iterator<_Ty>& _Right) { // assign _Right (share active buffer) _Pbuf = _Right._Pbuf; return (*this); } _Temp_iterator<_Ty>& operator=(const _Ty& _Val) { // assign or construct value into active buffer, and increment if (_Pbuf->_Current < _Pbuf->_Hiwater) *_Pbuf->_Current++ = _Val; // below high water mark, assign else { // above high water mark, construct _Pty _Ptr = &*_Pbuf->_Current; _Construct(_Ptr, _Val); _Pbuf->_Hiwater = ++_Pbuf->_Current; } return (*this); } _Temp_iterator<_Ty>& operator*() { // pretend to return designated value return (*this); } _Temp_iterator<_Ty>& operator++() { // pretend to preincrement return (*this); } _Temp_iterator<_Ty>& operator++(int) { // pretend to postincrement return (*this); } _Temp_iterator<_Ty>& _Init() { // set pointer at beginning of buffer _Pbuf->_Current = _Pbuf->_Begin; return (*this); } _Pty _First() const { // return pointer to beginning of buffer return (_Pbuf->_Begin); } _Pty _Last() const { // return pointer past end of buffer contents return (_Pbuf->_Current); } ptrdiff_t _Maxlen() const { // return size of buffer return (_Pbuf->_Size); } private: struct _Bufpar { // control information for a temporary buffer _Pty _Begin; // pointer to beginning of buffer _Pty _Current; // pointer to next available element _Pty _Hiwater; // pointer to first unconstructed element ptrdiff_t _Size; // length of buffer }; _Bufpar _Buf; // buffer control stored in iterator _Bufpar *_Pbuf; // pointer to active buffer control }; // TEMPLATE CLASS auto_ptr template class auto_ptr; template struct auto_ptr_ref { // proxy reference for auto_ptr copying auto_ptr_ref(auto_ptr<_Ty>& _Right) : _Ref(_Right) { // construct from compatible auto_ptr } auto_ptr<_Ty>& _Ref; // reference to constructor argument }; template class auto_ptr { // wrap an object pointer to ensure destruction public: typedef _Ty element_type; explicit auto_ptr(_Ty *_Ptr = 0) throw () : _Myptr(_Ptr) { // construct from object pointer } auto_ptr(auto_ptr<_Ty>& _Right) throw () : _Myptr(_Right.release()) { // construct by assuming pointer from _Right auto_ptr } auto_ptr(auto_ptr_ref<_Ty> _Right) throw () : _Myptr(_Right._Ref.release()) { // construct by assuming pointer from _Right auto_ptr_ref } template operator auto_ptr<_Other>() throw () { // convert to compatible auto_ptr return (auto_ptr<_Other>(*this)); } template operator auto_ptr_ref<_Other>() throw () { // convert to compatible auto_ptr_ref return (auto_ptr_ref<_Other>(*this)); } template auto_ptr<_Ty>& operator=(auto_ptr<_Other>& _Right) throw () { // assign compatible _Right (assume pointer) reset(_Right.release()); return (*this); } template auto_ptr(auto_ptr<_Other>& _Right) throw () : _Myptr(_Right.release()) { // construct by assuming pointer from _Right } auto_ptr<_Ty>& operator=(auto_ptr<_Ty>& _Right) throw () { // assign compatible _Right (assume pointer) reset(_Right.release()); return (*this); } auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty>& _Right) throw () { // assign compatible _Right._Ref (assume pointer) reset(_Right._Ref.release()); return (*this); } ~auto_ptr() { // destroy the object delete _Myptr; } _Ty& operator*() const throw () { // return designated value return (*_Myptr); } _Ty *operator->() const throw () { // return pointer to class object return (&**this); } _Ty *get() const throw () { // return wrapped pointer return (_Myptr); } _Ty *release() throw () { // return wrapped pointer and give up ownership _Ty *_Tmp = _Myptr; _Myptr = 0; return (_Tmp); } void reset(_Ty* _Ptr = 0) { // destroy designated object and store new pointer if (_Ptr != _Myptr) delete _Myptr; _Myptr = _Ptr; } private: _Ty *_Myptr; // the wrapped object pointer }; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */ /* * This file is derived from software bearing the following * restrictions: * * 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. V4.02:1476 */ // functional standard header namespace std { // TEMPLATE STRUCT unary_function template struct unary_function { // base class for unary functions typedef _Arg argument_type; typedef _Result result_type; }; // TEMPLATE STRUCT binary_function template struct binary_function { // base class for binary functions typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; }; // TEMPLATE STRUCT plus template struct plus : public binary_function<_Ty, _Ty, _Ty> { // functor for operator+ _Ty operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator+ to operands return (_Left + _Right); } }; // TEMPLATE STRUCT minus template struct minus : public binary_function<_Ty, _Ty, _Ty> { // functor for operator- _Ty operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator- to operands return (_Left - _Right); } }; // TEMPLATE STRUCT multiplies template struct multiplies : public binary_function<_Ty, _Ty, _Ty> { // functor for operator* _Ty operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator* to operands return (_Left * _Right); } }; // TEMPLATE STRUCT divides template struct divides : public binary_function<_Ty, _Ty, _Ty> { // functor for operator/ _Ty operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator/ to operands return (_Left / _Right); } }; // TEMPLATE STRUCT modulus template struct modulus : public binary_function<_Ty, _Ty, _Ty> { // functor for operator% _Ty operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator% to operands return (_Left % _Right); } }; // TEMPLATE STRUCT negate template struct negate : public unary_function<_Ty, _Ty> { // functor for unary operator- _Ty operator()(const _Ty& _Left) const { // apply operator- to operand return (-_Left); } }; // TEMPLATE STRUCT equal_to template struct equal_to : public binary_function<_Ty, _Ty, bool> { // functor for operator== bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator== to operands return (_Left == _Right); } }; // TEMPLATE STRUCT not_equal_to template struct not_equal_to : public binary_function<_Ty, _Ty, bool> { // functor for operator!= bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator= to operands return (_Left != _Right); } }; // TEMPLATE STRUCT greater template struct greater : public binary_function<_Ty, _Ty, bool> { // functor for operator> bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator> to operands return (_Left > _Right); } }; // TEMPLATE STRUCT less template struct less : public binary_function<_Ty, _Ty, bool> { // functor for operator< bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator< to operands return (_Left < _Right); } }; // TEMPLATE STRUCT greater_equal template struct greater_equal : public binary_function<_Ty, _Ty, bool> { // functor for operator>= bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator>= to operands return (_Left >= _Right); } }; // TEMPLATE STRUCT less_equal template struct less_equal : public binary_function<_Ty, _Ty, bool> { // functor for operator<= bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator<= to operands return (_Left <= _Right); } }; // TEMPLATE STRUCT logical_and template struct logical_and : public binary_function<_Ty, _Ty, bool> { // functor for operator&& bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator&& to operands return (_Left && _Right); } }; // TEMPLATE STRUCT logical_or template struct logical_or : public binary_function<_Ty, _Ty, bool> { // functor for operator|| bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator|| to operands return (_Left || _Right); } }; // TEMPLATE STRUCT logical_not template struct logical_not : public unary_function<_Ty, bool> { // functor for unary operator! bool operator()(const _Ty& _Left) const { // apply operator! to operand return (!_Left); } }; // TEMPLATE CLASS unary_negate template class unary_negate : public unary_function { // functor adapter !_Func(left) public: explicit unary_negate(const _Fn1& _Func) : _Functor(_Func) { // construct from functor } bool operator()(const typename _Fn1::argument_type& _Left) const { // apply functor to operand return (!_Functor(_Left)); } protected: _Fn1 _Functor; // the functor to apply }; // TEMPLATE FUNCTION not1 template inline unary_negate<_Fn1> not1(const _Fn1& _Func) { // return a unary_negate functor adapter return (::std:: unary_negate<_Fn1>(_Func)); } // TEMPLATE CLASS binary_negate template class binary_negate : public binary_function { // functor adapter !_Func(left, right) public: explicit binary_negate(const _Fn2& _Func) : _Functor(_Func) { // construct from functor } bool operator()(const typename _Fn2::first_argument_type& _Left, const typename _Fn2::second_argument_type& _Right) const { // apply functor to operands return (!_Functor(_Left, _Right)); } protected: _Fn2 _Functor; // the functor to apply }; // TEMPLATE FUNCTION not2 template inline binary_negate<_Fn2> not2(const _Fn2& _Func) { // return a binary_negate functor adapter return (::std:: binary_negate<_Fn2>(_Func)); } // TEMPLATE CLASS binder1st template class binder1st : public unary_function { // functor adapter _Func(stored, right) public: typedef unary_function _Base; typedef typename _Base::argument_type argument_type; typedef typename _Base::result_type result_type; binder1st(const _Fn2& _Func, const typename _Fn2::first_argument_type& _Left) : op(_Func), value(_Left) { // construct from functor and left operand } result_type operator()(const argument_type& _Right) const { // apply functor to operands return (op(value, _Right)); } result_type operator()(argument_type& _Right) const { // apply functor to operands return (op(value, _Right)); } protected: _Fn2 op; // the functor to apply typename _Fn2::first_argument_type value; // the left operand }; // TEMPLATE FUNCTION bind1st template inline binder1st<_Fn2> bind1st(const _Fn2& _Func, const _Ty& _Left) { // return a binder1st functor adapter typename _Fn2::first_argument_type _Val(_Left); return (::std:: binder1st<_Fn2>(_Func, _Val)); } // TEMPLATE CLASS binder2nd template class binder2nd : public unary_function { // functor adapter _Func(left, stored) public: typedef unary_function _Base; typedef typename _Base::argument_type argument_type; typedef typename _Base::result_type result_type; binder2nd(const _Fn2& _Func, const typename _Fn2::second_argument_type& _Right) : op(_Func), value(_Right) { // construct from functor and right operand } result_type operator()(const argument_type& _Left) const { // apply functor to operands return (op(_Left, value)); } result_type operator()(argument_type& _Left) const { // apply functor to operands return (op(_Left, value)); } protected: _Fn2 op; // the functor to apply typename _Fn2::second_argument_type value; // the right operand }; // TEMPLATE FUNCTION bind2nd template inline binder2nd<_Fn2> bind2nd(const _Fn2& _Func, const _Ty& _Right) { // return a binder2nd functor adapter typename _Fn2::second_argument_type _Val(_Right); return (::std:: binder2nd<_Fn2>(_Func, _Val)); } // TEMPLATE CLASS pointer_to_unary_function template class pointer_to_unary_function : public unary_function<_Arg, _Result> { // functor adapter (*pfunc)(left) public: explicit pointer_to_unary_function(_Result (*_Left)(_Arg)) : _Pfun(_Left) { // construct from pointer } _Result operator()(_Arg _Left) const { // call function with operand return (_Pfun(_Left)); } protected: _Result (*_Pfun)(_Arg); // the function pointer }; // TEMPLATE CLASS pointer_to_binary_function template class pointer_to_binary_function : public binary_function<_Arg1, _Arg2, _Result> { // functor adapter (*pfunc)(left, right) public: explicit pointer_to_binary_function( _Result (*_Left)(_Arg1, _Arg2)) : _Pfun(_Left) { // construct from pointer } _Result operator()(_Arg1 _Left, _Arg2 _Right) const { // call function with operands return (_Pfun(_Left, _Right)); } protected: _Result (*_Pfun)(_Arg1, _Arg2); // the function pointer }; // TEMPLATE FUNCTION ptr_fun template inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*_Left)(_Arg)) { // return pointer_to_unary_function functor adapter return (::std:: pointer_to_unary_function<_Arg, _Result>(_Left)); } template inline pointer_to_binary_function<_Arg1, _Arg2, _Result> ptr_fun(_Result (*_Left)(_Arg1, _Arg2)) { // return pointer_to_binary_function functor adapter return (::std:: pointer_to_binary_function<_Arg1, _Arg2, _Result>(_Left)); } // TEMPLATE CLASS mem_fun_t template class mem_fun_t : public unary_function<_Ty *, _Result> { // functor adapter (*p->*pfunc)(), non-const *pfunc public: explicit mem_fun_t(_Result (_Ty::*_Pm)()) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(_Ty *_Pleft) const { // call function return ((_Pleft->*_Pmemfun)()); } private: _Result (_Ty::*_Pmemfun)(); // the member function pointer }; // TEMPLATE CLASS mem_fun1_t template class mem_fun1_t : public binary_function<_Ty *, _Arg, _Result> { // functor adapter (*p->*pfunc)(val), non-const *pfunc public: explicit mem_fun1_t(_Result (_Ty::*_Pm)(_Arg)) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(_Ty *_Pleft, _Arg _Right) const { // call function with operand return ((_Pleft->*_Pmemfun)(_Right)); } private: _Result (_Ty::*_Pmemfun)(_Arg); // the member function pointer }; // TEMPLATE CLASS const_mem_fun_t template class const_mem_fun_t : public unary_function { // functor adapter (*p->*pfunc)(), const *pfunc public: explicit const_mem_fun_t(_Result (_Ty::*_Pm)() const) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(const _Ty *_Pleft) const { // call function return ((_Pleft->*_Pmemfun)()); } private: _Result (_Ty::*_Pmemfun)() const; // the member function pointer }; // TEMPLATE CLASS const_mem_fun1_t template class const_mem_fun1_t : public binary_function { // functor adapter (*p->*pfunc)(val), const *pfunc public: explicit const_mem_fun1_t(_Result (_Ty::*_Pm)(_Arg) const) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(const _Ty *_Pleft, _Arg _Right) const { // call function with operand return ((_Pleft->*_Pmemfun)(_Right)); } private: _Result (_Ty::*_Pmemfun)(_Arg) const; // the member function pointer }; // TEMPLATE FUNCTION mem_fun template inline mem_fun_t<_Result, _Ty> mem_fun(_Result (_Ty::*_Pm)()) { // return a mem_fun_t functor adapter return (::std:: mem_fun_t<_Result, _Ty>(_Pm)); } template inline mem_fun1_t<_Result, _Ty, _Arg> mem_fun(_Result (_Ty::*_Pm)(_Arg)) { // return a mem_fun1_t functor adapter return (::std:: mem_fun1_t<_Result, _Ty, _Arg>(_Pm)); } template inline const_mem_fun_t<_Result, _Ty> mem_fun(_Result (_Ty::*_Pm)() const) { // return a const_mem_fun_t functor adapter return (::std:: const_mem_fun_t<_Result, _Ty>(_Pm)); } template inline const_mem_fun1_t<_Result, _Ty, _Arg> mem_fun(_Result (_Ty::*_Pm)(_Arg) const) { // return a const_mem_fun1_t functor adapter return (::std:: const_mem_fun1_t<_Result, _Ty, _Arg>(_Pm)); } // TEMPLATE FUNCTION mem_fun1 (retained) template inline mem_fun1_t<_Result, _Ty, _Arg> mem_fun1(_Result (_Ty::*_Pm)(_Arg)) { // return a mem_fun1_t functor adapter return (::std:: mem_fun1_t<_Result, _Ty, _Arg>(_Pm)); } // TEMPLATE CLASS mem_fun_ref_t template class mem_fun_ref_t : public unary_function<_Ty, _Result> { // functor adapter (*left.*pfunc)(), non-const *pfunc public: explicit mem_fun_ref_t(_Result (_Ty::*_Pm)()) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(_Ty& _Left) const { // call function return ((_Left.*_Pmemfun)()); } private: _Result (_Ty::*_Pmemfun)(); // the member function pointer }; // TEMPLATE CLASS mem_fun1_ref_t template class mem_fun1_ref_t : public binary_function<_Ty, _Arg, _Result> { // functor adapter (*left.*pfunc)(val), non-const *pfunc public: explicit mem_fun1_ref_t(_Result (_Ty::*_Pm)(_Arg)) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(_Ty& _Left, _Arg _Right) const { // call function with operand return ((_Left.*_Pmemfun)(_Right)); } private: _Result (_Ty::*_Pmemfun)(_Arg); // the member function pointer }; // TEMPLATE CLASS const_mem_fun_ref_t template class const_mem_fun_ref_t : public unary_function<_Ty, _Result> { // functor adapter (*left.*pfunc)(), const *pfunc public: explicit const_mem_fun_ref_t(_Result (_Ty::*_Pm)() const) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(const _Ty& _Left) const { // call function return ((_Left.*_Pmemfun)()); } private: _Result (_Ty::*_Pmemfun)() const; // the member function pointer }; // TEMPLATE CLASS const_mem_fun1_ref_t template class const_mem_fun1_ref_t : public binary_function<_Ty, _Arg, _Result> { // functor adapter (*left.*pfunc)(val), const *pfunc public: explicit const_mem_fun1_ref_t(_Result (_Ty::*_Pm)(_Arg) const) : _Pmemfun(_Pm) { // construct from pointer } _Result operator()(const _Ty& _Left, _Arg _Right) const { // call function with operand return ((_Left.*_Pmemfun)(_Right)); } private: _Result (_Ty::*_Pmemfun)(_Arg) const; // the member function pointer }; // TEMPLATE FUNCTION mem_fun_ref template inline mem_fun_ref_t<_Result, _Ty> mem_fun_ref(_Result (_Ty::*_Pm)()) { // return a mem_fun_ref_t functor adapter return (::std:: mem_fun_ref_t<_Result, _Ty>(_Pm)); } template inline mem_fun1_ref_t<_Result, _Ty, _Arg> mem_fun_ref(_Result (_Ty::*_Pm)(_Arg)) { // return a mem_fun1_ref_t functor adapter return (::std:: mem_fun1_ref_t<_Result, _Ty, _Arg>(_Pm)); } template inline const_mem_fun_ref_t<_Result, _Ty> mem_fun_ref(_Result (_Ty::*_Pm)() const) { // return a const_mem_fun_ref_t functor adapter return (::std:: const_mem_fun_ref_t<_Result, _Ty>(_Pm)); } template inline const_mem_fun1_ref_t<_Result, _Ty, _Arg> mem_fun_ref(_Result (_Ty::*_Pm)(_Arg) const) { // return a const_mem_fun1_ref_t functor adapter return (::std:: const_mem_fun1_ref_t<_Result, _Ty, _Arg>(_Pm)); } // TEMPLATE FUNCTION mem_fun1_ref (retained) template inline mem_fun1_ref_t<_Result, _Ty, _Arg> mem_fun1_ref(_Result (_Ty::*_Pm)(_Arg)) { // return a mem_fun1_ref_t functor adapter return (::std:: mem_fun1_ref_t<_Result, _Ty, _Arg>(_Pm)); } // TEMPLATE CLASS unary_compose template class unary_compose : public unary_function { // functor for f1(f2(x)) public: unary_compose(const _Fn1& _Func1, const _Fn2& _Func2) : _Functor1(_Func1), _Functor2(_Func2) { // construct from functors } typename _Fn1::result_type operator()( const typename _Fn2::argument_type& _Left) const { // apply functors to operand return (_Functor1(_Functor2(_Left))); } protected: _Fn1 _Functor1; _Fn2 _Functor2; }; // TEMPLATE FUNCTION compose1 template inline unary_compose<_Fn1, _Fn2> compose1(const _Fn1& _Func1, const _Fn2& _Func2) { // return a unary_compose<_Fn1, _Fn2> functor adapter return (unary_compose<_Fn1, _Fn2>(_Func1, _Func2)); } // TEMPLATE CLASS binary_compose template class binary_compose : public unary_function { // functor for f1(f2(x), f3(x)) public: binary_compose(const _Fn1& _Func1, const _Fn2& _Func2, const _Fn3& _Func3) : _Functor1(_Func1), _Functor2(_Func2), _Functor3(_Func3) { // construct from functors } typename _Fn1::result_type operator()( const typename _Fn2::argument_type& _Left) const { // apply functors to operand return (_Functor1(_Functor2(_Left), _Functor3(_Left))); } protected: _Fn1 _Functor1; _Fn2 _Functor2; _Fn3 _Functor3; }; // TEMPLATE FUNCTION compose2 template inline binary_compose<_Fn1, _Fn2, _Fn3> compose2(const _Fn1& _Func1, const _Fn2& _Func2, const _Fn3& _Func3) { // return a binary_compose<_Fn1, _Fn2, _Fn3> functor adapter return (binary_compose<_Fn1, _Fn2, _Fn3>(_Func1, _Func2, _Func3)); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */ /* * This file is derived from software bearing the following * restrictions: * * 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. V4.02:1476 */ // string standard header // istream standard header // ostream standard header // ios standard header // xlocnum internal header (from ) // streambuf standard header // xiosbase internal header (from ) // xlocale internal header (from ) // stdexcept standard header // xstring internal header (from ) namespace std { template, class _Ax = allocator<_Elem> > class basic_string; // TEMPLATE CLASS _String_const_iterator template class _String_const_iterator : public _Ranit<_Elem, typename _Alloc::difference_type, typename _Alloc::const_pointer, typename _Alloc::const_reference> { // iterator for nonmutable string public: typedef _String_const_iterator<_Elem, _Traits, _Alloc> _Myt; typedef basic_string<_Elem, _Traits, _Alloc> _Mystring; typedef random_access_iterator_tag iterator_category; typedef _Elem value_type; typedef typename _Alloc::difference_type difference_type; typedef typename _Alloc::const_pointer pointer; typedef typename _Alloc::const_reference reference; _String_const_iterator() { // construct with null pointer _Myptr = 0; } _String_const_iterator(pointer _Ptr) { // construct with pointer _Ptr _Myptr = _Ptr; } reference operator*() const { // return designated object return (*_Myptr); } pointer operator->() const { // return pointer to class object return (&**this); } _Myt& operator++() { // preincrement ++_Myptr; return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; ++*this; return (_Tmp); } _Myt& operator--() { // predecrement --_Myptr; return (*this); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; --*this; return (_Tmp); } _Myt& operator+=(difference_type _Off) { // increment by integer _Myptr += _Off; return (*this); } _Myt operator+(difference_type _Off) const { // return this + integer _Myt _Tmp = *this; return (_Tmp += _Off); } _Myt& operator-=(difference_type _Off) { // decrement by integer return (*this += -_Off); } _Myt operator-(difference_type _Off) const { // return this - integer _Myt _Tmp = *this; return (_Tmp -= _Off); } difference_type operator-(const _Myt& _Right) const { // return difference of iterators return (_Myptr - _Right._Myptr); } reference operator[](difference_type _Off) const { // subscript return (*(*this + _Off)); } bool operator==(const _Myt& _Right) const { // test for iterator equality return (_Myptr == _Right._Myptr); } bool operator!=(const _Myt& _Right) const { // test for iterator inequality return (!(*this == _Right)); } bool operator<(const _Myt& _Right) const { // test if this < _Right return (_Myptr < _Right._Myptr); } bool operator>(const _Myt& _Right) const { // test if this > _Right return (_Right < *this); } bool operator<=(const _Myt& _Right) const { // test if this <= _Right return (!(_Right < *this)); } bool operator>=(const _Myt& _Right) const { // test if this >= _Right return (!(*this < _Right)); } pointer _Myptr; // offset of element in string }; template inline _String_const_iterator<_Elem, _Traits, _Alloc> operator+( typename _String_const_iterator<_Elem, _Traits, _Alloc> ::difference_type _Off, _String_const_iterator<_Elem, _Traits, _Alloc> _Next) { // add offset to iterator return (_Next += _Off); } // TEMPLATE CLASS _String_iterator template class _String_iterator : public _String_const_iterator<_Elem, _Traits, _Alloc> { // iterator for mutable string public: typedef _String_iterator<_Elem, _Traits, _Alloc> _Myt; typedef _String_const_iterator<_Elem, _Traits, _Alloc> _Mybase; typedef random_access_iterator_tag iterator_category; typedef _Elem value_type; typedef typename _Alloc::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::reference reference; _String_iterator() { // construct with null string pointer } _String_iterator(pointer _Ptr) : _Mybase(_Ptr) { // construct with pointer _Ptr } reference operator*() const { // return designated object return ((reference)**(_Mybase *)this); } pointer operator->() const { // return pointer to class object return (&**this); } _Myt& operator++() { // preincrement ++this->_Myptr; return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; ++*this; return (_Tmp); } _Myt& operator--() { // predecrement --this->_Myptr; return (*this); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; --*this; return (_Tmp); } _Myt& operator+=(difference_type _Off) { // increment by integer this->_Myptr += _Off; return (*this); } _Myt operator+(difference_type _Off) const { // return this + integer _Myt _Tmp = *this; return (_Tmp += _Off); } _Myt& operator-=(difference_type _Off) { // decrement by integer return (*this += -_Off); } _Myt operator-(difference_type _Off) const { // return this - integer _Myt _Tmp = *this; return (_Tmp -= _Off); } difference_type operator-(const _Mybase& _Right) const { // return difference of iterators return ((_Mybase)*this - _Right); } reference operator[](difference_type _Off) const { // subscript return (*(*this + _Off)); } }; template inline _String_iterator<_Elem, _Traits, _Alloc> operator+( typename _String_iterator<_Elem, _Traits, _Alloc> ::difference_type _Off, _String_iterator<_Elem, _Traits, _Alloc> _Next) { // add offset to iterator return (_Next += _Off); } // CLASS _String_base class _String_base : public _Container_base { // ultimate base class for basic_string to hold error reporters public: void _Xlen() const; // report a length_error void _Xran() const; // report an out_of_range error }; // TEMPLATE CLASS _String_val template class _String_val : public _String_base { // base class for basic_string to hold allocator _Alval protected: typedef typename _Alloc::template rebind<_Ty>::other _Alty; _String_val(_Alty _Al = _Alty()) : _Alval(_Al) { // construct allocator from _Al } _Alty _Alval; // allocator object for strings }; // TEMPLATE CLASS basic_string template class basic_string : public _String_val<_Elem, _Ax> { // null-terminated transparent array of elements public: typedef basic_string<_Elem, _Traits, _Ax> _Myt; typedef _String_val<_Elem, _Ax> _Mybase; typedef typename _Mybase::_Alty _Alloc; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type _Dift; typedef _Dift difference_type; typedef typename _Alloc::pointer _Tptr; typedef typename _Alloc::const_pointer _Ctptr; typedef _Tptr pointer; typedef _Ctptr const_pointer; typedef typename _Alloc::reference _Reft; typedef _Reft reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Alloc::value_type value_type; typedef _String_iterator<_Elem, _Traits, _Alloc> iterator; typedef _String_const_iterator<_Elem, _Traits, _Alloc> const_iterator; // friend class _String_iterator<_Elem, _Traits, _Alloc>; friend class _String_const_iterator<_Elem, _Traits, _Alloc>; typedef ::std:: reverse_iterator reverse_iterator; typedef ::std:: reverse_iterator const_reverse_iterator; basic_string() : _Mybase() { // construct empty string _Tidy(); } explicit basic_string(const _Alloc& _Al) : _Mybase(_Al) { // construct empty string with allocator _Tidy(); } basic_string(const _Myt& _Right) : _Mybase(_Right._Alval) { // construct by copying _Right _Tidy(); assign(_Right, 0, npos); } basic_string(const _Myt& _Right, size_type _Roff, size_type _Count = npos) : _Mybase() { // construct from _Right [_Roff, _Roff + _Count) _Tidy(); assign(_Right, _Roff, _Count); } basic_string(const _Myt& _Right, size_type _Roff, size_type _Count, const _Alloc& _Al) : _Mybase(_Al) { // construct from _Right [_Roff, _Roff + _Count) with allocator _Tidy(); assign(_Right, _Roff, _Count); } basic_string(const _Elem *_Ptr, size_type _Count) : _Mybase() { // construct from [_Ptr, _Ptr + _Count) _Tidy(); assign(_Ptr, _Count); } basic_string(const _Elem *_Ptr, size_type _Count, const _Alloc& _Al) : _Mybase(_Al) { // construct from [_Ptr, _Ptr + _Count) with allocator _Tidy(); assign(_Ptr, _Count); } basic_string(const _Elem *_Ptr) : _Mybase() { // construct from [_Ptr, ) _Tidy(); assign(_Ptr); } basic_string(const _Elem *_Ptr, const _Alloc& _Al) : _Mybase(_Al) { // construct from [_Ptr, ) with allocator _Tidy(); assign(_Ptr); } basic_string(size_type _Count, _Elem _Ch) : _Mybase() { // construct from _Count * _Ch _Tidy(); assign(_Count, _Ch); } basic_string(size_type _Count, _Elem _Ch, const _Alloc& _Al) : _Mybase(_Al) { // construct from _Count * _Ch with allocator _Tidy(); assign(_Count, _Ch); } template basic_string(_It _First, _It _Last) : _Mybase() { // construct from [_First, _Last) _Tidy(); _Construct(_First, _Last, _Iter_cat(_First)); } template basic_string(_It _First, _It _Last, const _Alloc& _Al) : _Mybase(_Al) { // construct from [_First, _Last) with allocator _Tidy(); _Construct(_First, _Last, _Iter_cat(_First)); } template void _Construct(_It _Count, _It _Ch, _Int_iterator_tag) { // initialize from _Count * _Ch assign((size_type)_Count, (_Elem)_Ch); } template void _Construct(_It _First, _It _Last, input_iterator_tag) { // initialize from [_First, _Last), input iterators try { for (; _First != _Last; ++_First) append((size_type)1, (_Elem)*_First); } catch (...) { _Tidy(true); throw; } } template void _Construct(_It _First, _It _Last, forward_iterator_tag) { // initialize from [_First, _Last), forward iterators ; size_type _Count = 0; _Distance(_First, _Last, _Count); reserve(_Count); try { for (; _First != _Last; ++_First) append((size_type)1, (_Elem)*_First); } catch (...) { _Tidy(true); throw; } } basic_string(const_pointer _First, const_pointer _Last) : _Mybase() { // construct from [_First, _Last), const pointers ; _Tidy(); if (_First != _Last) assign(&*_First, _Last - _First); } basic_string(const_iterator _First, const_iterator _Last) : _Mybase() { // construct from [_First, _Last), const_iterators ; _Tidy(); if (_First != _Last) assign(&*_First, _Last - _First); } ~basic_string() { // destroy the string _Tidy(true); } typedef _Traits traits_type; typedef _Alloc allocator_type; static const far size_type npos; // generic bad/missing length/position _Myt& operator=(const _Myt& _Right) { // assign _Right return (assign(_Right)); } _Myt& operator=(const _Elem *_Ptr) { // assign [_Ptr, ) return (assign(_Ptr)); } _Myt& operator=(_Elem _Ch) { // assign 1 * _Ch return (assign(1, _Ch)); } _Myt& operator+=(const _Myt& _Right) { // append _Right return (append(_Right)); } _Myt& operator+=(const _Elem *_Ptr) { // append [_Ptr, ) return (append(_Ptr)); } _Myt& operator+=(_Elem _Ch) { // append 1 * _Ch return (append((size_type)1, _Ch)); } _Myt& append(const _Myt& _Right) { // append _Right return (append(_Right, 0, npos)); } _Myt& append(const _Myt& _Right, size_type _Roff, size_type _Count) { // append _Right [_Roff, _Roff + _Count) if (_Right.size() < _Roff) _String_base::_Xran(); // _Roff off end size_type _Num = _Right.size() - _Roff; if (_Num < _Count) _Count = _Num; // trim _Count to size if (npos - _Mysize <= _Count) _String_base::_Xlen(); // result too long if (0 < _Count && _Grow(_Num = _Mysize + _Count)) { // make room and append new stuff _Traits::copy(_Myptr() + _Mysize, _Right._Myptr() + _Roff, _Count); _Eos(_Num); } return (*this); } _Myt& append(const _Elem *_Ptr, size_type _Count) { // append [_Ptr, _Ptr + _Count) if (_Inside(_Ptr)) return (append(*this, _Ptr - _Myptr(), _Count)); // substring if (npos - _Mysize <= _Count) _String_base::_Xlen(); // result too long size_type _Num; if (0 < _Count && _Grow(_Num = _Mysize + _Count)) { // make room and append new stuff _Traits::copy(_Myptr() + _Mysize, _Ptr, _Count); _Eos(_Num); } return (*this); } _Myt& append(const _Elem *_Ptr) { // append [_Ptr, ) return (append(_Ptr, _Traits::length(_Ptr))); } _Myt& append(size_type _Count, _Elem _Ch) { // append _Count * _Ch if (npos - _Mysize <= _Count) _String_base::_Xlen(); // result too long size_type _Num; if (0 < _Count && _Grow(_Num = _Mysize + _Count)) { // make room and append new stuff using assign _Chassign(_Mysize, _Count, _Ch); _Eos(_Num); } return (*this); } template _Myt& append(_It _First, _It _Last) { // append [_First, _Last) return (_Append(_First, _Last, _Iter_cat(_First))); } template _Myt& _Append(_It _Count, _It _Ch, _Int_iterator_tag) { // append _Count * _Ch return (append((size_type)_Count, (_Elem)_Ch)); } template _Myt& _Append(_It _First, _It _Last, input_iterator_tag) { // append [_First, _Last), input iterators return (replace(end(), end(), _First, _Last)); } _Myt& append(const_pointer _First, const_pointer _Last) { // append [_First, _Last), const pointers return (replace(end(), end(), _First, _Last)); } _Myt& append(const_iterator _First, const_iterator _Last) { // append [_First, _Last), const_iterators return (replace(end(), end(), _First, _Last)); } _Myt& assign(const _Myt& _Right) { // assign _Right return (assign(_Right, 0, npos)); } _Myt& assign(const _Myt& _Right, size_type _Roff, size_type _Count) { // assign _Right [_Roff, _Roff + _Count) if (_Right.size() < _Roff) _String_base::_Xran(); // _Roff off end size_type _Num = _Right.size() - _Roff; if (_Count < _Num) _Num = _Count; // trim _Num to size if (this == &_Right) erase((size_type)(_Roff + _Num)), erase(0, _Roff); // substring else if (_Grow(_Num)) { // make room and assign new stuff _Traits::copy(_Myptr(), _Right._Myptr() + _Roff, _Num); _Eos(_Num); } return (*this); } _Myt& assign(const _Elem *_Ptr, size_type _Num) { // assign [_Ptr, _Ptr + _Num) if (_Inside(_Ptr)) return (assign(*this, _Ptr - _Myptr(), _Num)); // substring if (_Grow(_Num)) { // make room and assign new stuff _Traits::copy(_Myptr(), _Ptr, _Num); _Eos(_Num); } return (*this); } _Myt& assign(const _Elem *_Ptr) { // assign [_Ptr, ) return (assign(_Ptr, _Traits::length(_Ptr))); } _Myt& assign(size_type _Count, _Elem _Ch) { // assign _Count * _Ch if (_Count == npos) _String_base::_Xlen(); // result too long if (_Grow(_Count)) { // make room and assign new stuff _Chassign(0, _Count, _Ch); _Eos(_Count); } return (*this); } template _Myt& assign(_It _First, _It _Last) { // assign [First, _Last) return (_Assign(_First, _Last, _Iter_cat(_First))); } template _Myt& _Assign(_It _Count, _It _Ch, _Int_iterator_tag) { // assign _Count * _Ch return (assign((size_type)_Count, (_Elem)_Ch)); } template _Myt& _Assign(_It _First, _It _Last, input_iterator_tag) { // assign [First, _Last), input iterators return (replace(begin(), end(), _First, _Last)); } _Myt& assign(const_pointer _First, const_pointer _Last) { // assign [First, _Last), const pointers return (replace(begin(), end(), _First, _Last)); } _Myt& assign(const_iterator _First, const_iterator _Last) { // assign [First, _Last), const_iterators return (replace(begin(), end(), _First, _Last)); } _Myt& insert(size_type _Off, const _Myt& _Right) { // insert _Right at _Off return (insert(_Off, _Right, 0, npos)); } _Myt& insert(size_type _Off, const _Myt& _Right, size_type _Roff, size_type _Count) { // insert _Right [_Roff, _Roff + _Count) at _Off if (_Mysize < _Off || _Right.size() < _Roff) _String_base::_Xran(); // _Off or _Roff off end size_type _Num = _Right.size() - _Roff; if (_Num < _Count) _Count = _Num; // trim _Count to size if (npos - _Mysize <= _Count) _String_base::_Xlen(); // result too long if (0 < _Count && _Grow(_Num = _Mysize + _Count)) { // make room and insert new stuff _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off, _Mysize - _Off); // empty out hole if (this == &_Right) _Traits::move(_Myptr() + _Off, _Myptr() + (_Off < _Roff ? _Roff + _Count : _Roff), _Count); // substring else _Traits::copy(_Myptr() + _Off, _Right._Myptr() + _Roff, _Count); // fill hole _Eos(_Num); } return (*this); } _Myt& insert(size_type _Off, const _Elem *_Ptr, size_type _Count) { // insert [_Ptr, _Ptr + _Count) at _Off if (_Inside(_Ptr)) return (insert(_Off, *this, _Ptr - _Myptr(), _Count)); // substring if (_Mysize < _Off) _String_base::_Xran(); // _Off off end if (npos - _Mysize <= _Count) _String_base::_Xlen(); // result too long size_type _Num; if (0 < _Count && _Grow(_Num = _Mysize + _Count)) { // make room and insert new stuff _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off, _Mysize - _Off); // empty out hole _Traits::copy(_Myptr() + _Off, _Ptr, _Count); // fill hole _Eos(_Num); } return (*this); } _Myt& insert(size_type _Off, const _Elem *_Ptr) { // insert [_Ptr, ) at _Off return (insert(_Off, _Ptr, _Traits::length(_Ptr))); } _Myt& insert(size_type _Off, size_type _Count, _Elem _Ch) { // insert _Count * _Ch at _Off if (_Mysize < _Off) _String_base::_Xran(); // _Off off end if (npos - _Mysize <= _Count) _String_base::_Xlen(); // result too long size_type _Num; if (0 < _Count && _Grow(_Num = _Mysize + _Count)) { // make room and insert new stuff _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off, _Mysize - _Off); // empty out hole _Chassign(_Off, _Count, _Ch); // fill hole _Eos(_Num); } return (*this); } iterator insert(iterator _Where) { // insert at _Where return (insert(_Where, _Elem())); } iterator insert(iterator _Where, _Elem _Ch) { // insert _Ch at _Where size_type _Off = _Pdif(_Where, begin()); insert(_Off, 1, _Ch); return (begin() + _Off); } void insert(iterator _Where, size_type _Count, _Elem _Ch) { // insert _Count * _Elem at _Where size_type _Off = _Pdif(_Where, begin()); insert(_Off, _Count, _Ch); } template void insert(iterator _Where, _It _First, _It _Last) { // insert [_First, _Last) at _Where _Insert(_Where, _First, _Last, _Iter_cat(_First)); } template void _Insert(iterator _Where, _It _Count, _It _Ch, _Int_iterator_tag) { // insert _Count * _Ch at _Where insert(_Where, (size_type)_Count, (_Elem)_Ch); } template void _Insert(iterator _Where, _It _First, _It _Last, input_iterator_tag) { // insert [_First, _Last) at _Where, input iterators replace(_Where, _Where, _First, _Last); } void insert(iterator _Where, const_pointer _First, const_pointer _Last) { // insert [_First, _Last) at _Where, const pointers replace(_Where, _Where, _First, _Last); } void insert(iterator _Where, const_iterator _First, const_iterator _Last) { // insert [_First, _Last) at _Where, const_iterators replace(_Where, _Where, _First, _Last); } _Myt& erase(size_type _Off = 0, size_type _Count = npos) { // erase elements [_Off, _Off + _Count) if (_Mysize < _Off) _String_base::_Xran(); // _Off off end if (_Mysize - _Off < _Count) _Count = _Mysize - _Off; // trim _Count if (0 < _Count) { // move elements down _Traits::move(_Myptr() + _Off, _Myptr() + _Off + _Count, _Mysize - _Off - _Count); size_type _Newsize = _Mysize - _Count; _Eos(_Newsize); } return (*this); } iterator erase(iterator _Where) { // erase element at _Where size_type _Count = _Pdif(_Where, begin()); erase(_Count, 1); return (iterator(_Myptr() + _Count)); } iterator erase(iterator _First, iterator _Last) { // erase substring [_First, _Last) size_type _Count = _Pdif(_First, begin()); erase(_Count, _Pdif(_Last, _First)); return (iterator(_Myptr() + _Count)); } void clear() { // erase all erase(begin(), end()); } _Myt& replace(size_type _Off, size_type _N0, const _Myt& _Right) { // replace [_Off, _Off + _N0) with _Right return (replace(_Off, _N0, _Right, 0, npos)); } _Myt& replace(size_type _Off, size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count) { // replace [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count) if (_Mysize < _Off || _Right.size() < _Roff) _String_base::_Xran(); // _Off or _Roff off end if (_Mysize - _Off < _N0) _N0 = _Mysize - _Off; // trim _N0 to size size_type _Num = _Right.size() - _Roff; if (_Num < _Count) _Count = _Num; // trim _Count to size if (npos - _Count <= _Mysize - _N0) _String_base::_Xlen(); // result too long size_type _Nm = _Mysize - _N0 - _Off; // length of preserved tail size_type _Newsize = _Mysize + _Count - _N0; if (_Mysize < _Newsize) _Grow(_Newsize); if (this != &_Right) { // no overlap, just move down and copy in new stuff _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // empty hole _Traits::copy(_Myptr() + _Off, _Right._Myptr() + _Roff, _Count); // fill hole } else if (_Count <= _N0) { // hole doesn't get larger, just copy in substring _Traits::move(_Myptr() + _Off, _Myptr() + _Roff, _Count); // fill hole _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // move tail down } else if (_Roff <= _Off) { // hole gets larger, substring begins before hole _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // move tail down _Traits::move(_Myptr() + _Off, _Myptr() + _Roff, _Count); // fill hole } else if (_Off + _N0 <= _Roff) { // hole gets larger, substring begins after hole _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // move tail down _Traits::move(_Myptr() + _Off, _Myptr() + (_Roff + _Count - _N0), _Count); // fill hole } else { // hole gets larger, substring begins in hole _Traits::move(_Myptr() + _Off, _Myptr() + _Roff, _N0); // fill old hole _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // move tail down _Traits::move(_Myptr() + _Off + _N0, _Myptr() + _Roff + _Count, _Count - _N0); // fill rest of new hole } _Eos(_Newsize); return (*this); } _Myt& replace(size_type _Off, size_type _N0, const _Elem *_Ptr, size_type _Count) { // replace [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count) if (_Inside(_Ptr)) return (replace(_Off, _N0, *this, _Ptr - _Myptr(), _Count)); // substring, replace carefully if (_Mysize < _Off) _String_base::_Xran(); // _Off off end if (_Mysize - _Off < _N0) _N0 = _Mysize - _Off; // trim _N0 to size if (npos - _Count <= _Mysize - _N0) _String_base::_Xlen(); // result too long size_type _Nm = _Mysize - _N0 - _Off; if (_Count < _N0) _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // smaller hole, move tail up size_type _Num; if ((0 < _Count || 0 < _N0) && _Grow(_Num = _Mysize + _Count - _N0)) { // make room and rearrange if (_N0 < _Count) _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // move tail down _Traits::copy(_Myptr() + _Off, _Ptr, _Count); // fill hole _Eos(_Num); } return (*this); } _Myt& replace(size_type _Off, size_type _N0, const _Elem *_Ptr) { // replace [_Off, _Off + _N0) with [_Ptr, ) return (replace(_Off, _N0, _Ptr, _Traits::length(_Ptr))); } _Myt& replace(size_type _Off, size_type _N0, size_type _Count, _Elem _Ch) { // replace [_Off, _Off + _N0) with _Count * _Ch if (_Mysize < _Off) _String_base::_Xran(); // _Off off end if (_Mysize - _Off < _N0) _N0 = _Mysize - _Off; // trim _N0 to size if (npos - _Count <= _Mysize - _N0) _String_base::_Xlen(); // result too long size_type _Nm = _Mysize - _N0 - _Off; if (_Count < _N0) _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // smaller hole, move tail up size_type _Num; if ((0 < _Count || 0 < _N0) && _Grow(_Num = _Mysize + _Count - _N0)) { // make room and rearrange if (_N0 < _Count) _Traits::move(_Myptr() + _Off + _Count, _Myptr() + _Off + _N0, _Nm); // move tail down _Chassign(_Off, _Count, _Ch); // fill hole _Eos(_Num); } return (*this); } _Myt& replace(iterator _First, iterator _Last, const _Myt& _Right) { // replace [_First, _Last) with _Right return (replace( _Pdif(_First, begin()), _Pdif(_Last, _First), _Right)); } _Myt& replace(iterator _First, iterator _Last, const _Elem *_Ptr, size_type _Count) { // replace [_First, _Last) with [_Ptr, _Ptr + _Count) return (replace( _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr, _Count)); } _Myt& replace(iterator _First, iterator _Last, const _Elem *_Ptr) { // replace [_First, _Last) with [_Ptr, ) return (replace( _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr)); } _Myt& replace(iterator _First, iterator _Last, size_type _Count, _Elem _Ch) { // replace [_First, _Last) with _Count * _Ch return (replace( _Pdif(_First, begin()), _Pdif(_Last, _First), _Count, _Ch)); } template _Myt& replace(iterator _First, iterator _Last, _It _First2, _It _Last2) { // replace [_First, _Last) with [_First2, _Last2) return (_Replace(_First, _Last, _First2, _Last2, _Iter_cat(_First2))); } template _Myt& _Replace(iterator _First, iterator _Last, _It _Count, _It _Ch, _Int_iterator_tag) { // replace [_First, _Last) with _Count * _Ch return (replace(_First, _Last, (size_type)_Count, (_Elem)_Ch)); } template _Myt& _Replace(iterator _First, iterator _Last, _It _First2, _It _Last2, input_iterator_tag) { // replace [_First, _Last) with [_First2, _Last2), input iterators _Myt _Right(_First2, _Last2); replace(_First, _Last, _Right); return (*this); } _Myt& replace(iterator _First, iterator _Last, const_pointer _First2, const_pointer _Last2) { // replace [_First, _Last) with [_First2, _Last2), const pointers if (_First2 == _Last2) erase(_Pdif(_First, begin()), _Pdif(_Last, _First)); else replace(_Pdif(_First, begin()), _Pdif(_Last, _First), &*_First2, _Last2 - _First2); return (*this); } _Myt& replace(iterator _First, iterator _Last, const_iterator _First2, const_iterator _Last2) { // replace [_First, _Last) with [_First2, _Last2), const_iterators if (_First2 == _Last2) erase(_Pdif(_First, begin()), _Pdif(_Last, _First)); else replace(_Pdif(_First, begin()), _Pdif(_Last, _First), &*_First2, _Last2 - _First2); return (*this); } iterator begin() { // return iterator for beginning of mutable sequence return (iterator(_Myptr())); } const_iterator begin() const { // return iterator for beginning of nonmutable sequence return (const_iterator(_Myptr())); } iterator end() { // return iterator for end of mutable sequence return (iterator(_Myptr() + _Mysize)); } const_iterator end() const { // return iterator for end of nonmutable sequence return (const_iterator(_Myptr() + _Mysize)); } reverse_iterator rbegin() { // return iterator for beginning of reversed mutable sequence return (reverse_iterator(end())); } const_reverse_iterator rbegin() const { // return iterator for beginning of reversed nonmutable sequence return (const_reverse_iterator(end())); } reverse_iterator rend() { // return iterator for end of reversed mutable sequence return (reverse_iterator(begin())); } const_reverse_iterator rend() const { // return iterator for end of reversed nonmutable sequence return (const_reverse_iterator(begin())); } reference at(size_type _Off) { // subscript mutable sequence with checking if (_Mysize <= _Off) _String_base::_Xran(); // _Off off end return (_Myptr()[_Off]); } const_reference at(size_type _Off) const { // subscript nonmutable sequence with checking if (_Mysize <= _Off) _String_base::_Xran(); // _Off off end return (_Myptr()[_Off]); } reference operator[](size_type _Off) { // subscript mutable sequence return (_Myptr()[_Off]); } const_reference operator[](size_type _Off) const { // subscript nonmutable sequence return (_Myptr()[_Off]); } void push_back(_Elem _Ch) { // insert element at end insert(end(), _Ch); } const _Elem *c_str() const { // return pointer to null-terminated nonmutable array return (_Myptr()); } const _Elem *data() const { // return pointer to nonmutable array return (c_str()); } size_type length() const { // return length of sequence return (_Mysize); } size_type size() const { // return length of sequence return (_Mysize); } size_type max_size() const { // return maximum possible length of sequence size_type _Num = _Mybase::_Alval.max_size(); return (_Num <= 1 ? 1 : _Num - 1); } void resize(size_type _Newsize) { // determine new length, padding with null elements as needed resize(_Newsize, _Elem()); } void resize(size_type _Newsize, _Elem _Ch) { // determine new length, padding with _Ch elements as needed if (_Newsize <= _Mysize) erase(_Newsize); else append(_Newsize - _Mysize, _Ch); } size_type capacity() const { // return current length of allocated storage return (_Myres); } void reserve(size_type _Newcap = 0) { // determine new minimum length of allocated storage if (_Mysize <= _Newcap && _Myres != _Newcap) { // change reservation size_type _Size = _Mysize; if (_Grow(_Newcap, true)) _Eos(_Size); } } bool empty() const { // test if sequence is empty return (_Mysize == 0); } size_type copy(_Elem *_Ptr, size_type _Count, size_type _Off = 0) const { // copy [_Off, _Off + _Count) to [_Ptr, _Ptr + _Count) ; if (_Mysize < _Off) _String_base::_Xran(); // _Off off end if (_Mysize - _Off < _Count) _Count = _Mysize - _Off; _Traits::copy(_Ptr, _Myptr() + _Off, _Count); return (_Count); } void swap(_Myt& _Right) { // exchange contents with _Right if (_Mybase::_Alval == _Right._Alval) { // same allocator, swap control information _Bxty _Tbx = _Bx; _Bx = _Right._Bx, _Right._Bx = _Tbx; size_type _Tlen = _Mysize; _Mysize = _Right._Mysize, _Right._Mysize = _Tlen; size_type _Tres = _Myres; _Myres = _Right._Myres, _Right._Myres = _Tres; } else { // different allocator, do multiple assigns _Myt _Tmp = *this; *this = _Right, _Right = _Tmp; } } size_type find(const _Myt& _Right, size_type _Off = 0) const { // look for _Right beginnng at or after _Off return (find(_Right._Myptr(), _Off, _Right.size())); } size_type find(const _Elem *_Ptr, size_type _Off, size_type _Count) const { // look for [_Ptr, _Ptr + _Count) beginnng at or after _Off ; if (_Count == 0 && _Off <= _Mysize) return (_Off); // null string always matches (if inside string) size_type _Nm; if (_Off < _Mysize && _Count <= (_Nm = _Mysize - _Off)) { // room for match, look for it const _Elem *_Uptr, *_Vptr; for (_Nm -= _Count - 1, _Vptr = _Myptr() + _Off; (_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0; _Nm -= _Uptr - _Vptr + 1, _Vptr = _Uptr + 1) if (_Traits::compare(_Uptr, _Ptr, _Count) == 0) return (_Uptr - _Myptr()); // found a match } return (npos); // no match } size_type find(const _Elem *_Ptr, size_type _Off = 0) const { // look for [_Ptr, ) beginnng at or after _Off return (find(_Ptr, _Off, _Traits::length(_Ptr))); } size_type find(_Elem _Ch, size_type _Off = 0) const { // look for _Ch at or after _Off return (find((const _Elem *)&_Ch, _Off, 1)); } size_type rfind(const _Myt& _Right, size_type _Off = npos) const { // look for _Right beginning before _Off return (rfind(_Right._Myptr(), _Off, _Right.size())); } size_type rfind(const _Elem *_Ptr, size_type _Off, size_type _Count) const { // look for [_Ptr, _Ptr + _Count) beginning before _Off ; if (_Count == 0) return (_Off < _Mysize ? _Off : _Mysize); // null always matches if (_Count <= _Mysize) { // room for match, look for it const _Elem *_Uptr = _Myptr() + (_Off < _Mysize - _Count ? _Off : _Mysize - _Count); for (; ; --_Uptr) if (_Traits::eq(*_Uptr, *_Ptr) && _Traits::compare(_Uptr, _Ptr, _Count) == 0) return (_Uptr - _Myptr()); // found a match else if (_Uptr == _Myptr()) break; // at beginning, no more chance for match } return (npos); // no match } size_type rfind(const _Elem *_Ptr, size_type _Off = npos) const { // look for [_Ptr, ) beginning before _Off return (rfind(_Ptr, _Off, _Traits::length(_Ptr))); } size_type rfind(_Elem _Ch, size_type _Off = npos) const { // look for _Ch before _Off return (rfind((const _Elem *)&_Ch, _Off, 1)); } size_type find_first_of(const _Myt& _Right, size_type _Off = 0) const { // look for one of _Right at or after _Off return (find_first_of(_Right._Myptr(), _Off, _Right.size())); } size_type find_first_of(const _Elem *_Ptr, size_type _Off, size_type _Count) const { // look for one of [_Ptr, _Ptr + _Count) at or after _Off ; if (0 < _Count && _Off < _Mysize) { // room for match, look for it const _Elem *const _Vptr = _Myptr() + _Mysize; for (const _Elem *_Uptr = _Myptr() + _Off; _Uptr < _Vptr; ++_Uptr) if (_Traits::find(_Ptr, _Count, *_Uptr) != 0) return (_Uptr - _Myptr()); // found a match } return (npos); // no match } size_type find_first_of(const _Elem *_Ptr, size_type _Off = 0) const { // look for one of [_Ptr, ) at or after _Off return (find_first_of(_Ptr, _Off, _Traits::length(_Ptr))); } size_type find_first_of(_Elem _Ch, size_type _Off = 0) const { // look for _Ch at or after _Off return (find((const _Elem *)&_Ch, _Off, 1)); } size_type find_last_of(const _Myt& _Right, size_type _Off = npos) const { // look for one of _Right before _Off return (find_last_of(_Right._Myptr(), _Off, _Right.size())); } size_type find_last_of(const _Elem *_Ptr, size_type _Off, size_type _Count) const { // look for one of [_Ptr, _Ptr + _Count) before _Off ; if (0 < _Count && 0 < _Mysize) for (const _Elem *_Uptr = _Myptr() + (_Off < _Mysize ? _Off : _Mysize - 1); ; --_Uptr) if (_Traits::find(_Ptr, _Count, *_Uptr) != 0) return (_Uptr - _Myptr()); // found a match else if (_Uptr == _Myptr()) break; // at beginning, no more chance for match return (npos); // no match } size_type find_last_of(const _Elem *_Ptr, size_type _Off = npos) const { // look for one of [_Ptr, ) before _Off return (find_last_of(_Ptr, _Off, _Traits::length(_Ptr))); } size_type find_last_of(_Elem _Ch, size_type _Off = npos) const { // look for _Ch before _Off return (rfind((const _Elem *)&_Ch, _Off, 1)); } size_type find_first_not_of(const _Myt& _Right, size_type _Off = 0) const { // look for none of _Right at or after _Off return (find_first_not_of(_Right._Myptr(), _Off, _Right.size())); } size_type find_first_not_of(const _Elem *_Ptr, size_type _Off, size_type _Count) const { // look for none of [_Ptr, _Ptr + _Count) at or after _Off ; if (_Off < _Mysize) { // room for match, look for it const _Elem *const _Vptr = _Myptr() + _Mysize; for (const _Elem *_Uptr = _Myptr() + _Off; _Uptr < _Vptr; ++_Uptr) if (_Traits::find(_Ptr, _Count, *_Uptr) == 0) return (_Uptr - _Myptr()); } return (npos); } size_type find_first_not_of(const _Elem *_Ptr, size_type _Off = 0) const { // look for one of [_Ptr, ) at or after _Off return (find_first_not_of(_Ptr, _Off, _Traits::length(_Ptr))); } size_type find_first_not_of(_Elem _Ch, size_type _Off = 0) const { // look for non _Ch at or after _Off return (find_first_not_of((const _Elem *)&_Ch, _Off, 1)); } size_type find_last_not_of(const _Myt& _Right, size_type _Off = npos) const { // look for none of _Right before _Off return (find_last_not_of(_Right._Myptr(), _Off, _Right.size())); } size_type find_last_not_of(const _Elem *_Ptr, size_type _Off, size_type _Count) const { // look for none of [_Ptr, _Ptr + _Count) before _Off ; if (0 < _Mysize) for (const _Elem *_Uptr = _Myptr() + (_Off < _Mysize ? _Off : _Mysize - 1); ; --_Uptr) if (_Traits::find(_Ptr, _Count, *_Uptr) == 0) return (_Uptr - _Myptr()); else if (_Uptr == _Myptr()) break; return (npos); } size_type find_last_not_of(const _Elem *_Ptr, size_type _Off = npos) const { // look for none of [_Ptr, ) before _Off return (find_last_not_of(_Ptr, _Off, _Traits::length(_Ptr))); } size_type find_last_not_of(_Elem _Ch, size_type _Off = npos) const { // look for non _Ch before _Off return (find_last_not_of((const _Elem *)&_Ch, _Off, 1)); } _Myt substr(size_type _Off = 0, size_type _Count = npos) const { // return [_Off, _Off + _Count) as new string return (_Myt(*this, _Off, _Count)); } int compare(const _Myt& _Right) const { // compare [0, _Mysize) with _Right return (compare(0, _Mysize, _Right._Myptr(), _Right.size())); } int compare(size_type _Off, size_type _N0, const _Myt& _Right) const { // compare [_Off, _Off + _N0) with _Right return (compare(_Off, _N0, _Right, 0, npos)); } int compare(size_type _Off, size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count) const { // compare [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count) if (_Right.size() < _Roff) _String_base::_Xran(); // _Off off end if (_Right._Mysize - _Roff < _Count) _Count = _Right._Mysize - _Roff; // trim _Count to size return (compare(_Off, _N0, _Right._Myptr() + _Roff, _Count)); } int compare(const _Elem *_Ptr) const { // compare [0, _Mysize) with [_Ptr, ) return (compare(0, _Mysize, _Ptr, _Traits::length(_Ptr))); } int compare(size_type _Off, size_type _N0, const _Elem *_Ptr) const { // compare [_Off, _Off + _N0) with [_Ptr, ) return (compare(_Off, _N0, _Ptr, _Traits::length(_Ptr))); } int compare(size_type _Off, size_type _N0, const _Elem *_Ptr, size_type _Count) const { // compare [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count) ; if (_Mysize < _Off) _String_base::_Xran(); // _Off off end if (_Mysize - _Off < _N0) _N0 = _Mysize - _Off; // trim _N0 to size size_type _Ans = _N0 == 0 ? 0 : _Traits::compare(_Myptr() + _Off, _Ptr, _N0 < _Count ? _N0 : _Count); return (_Ans != 0 ? (int)_Ans : _N0 < _Count ? -1 : _N0 == _Count ? 0 : +1); } allocator_type get_allocator() const { // return allocator object for values return (_Mybase::_Alval); } enum { // length of internal buffer, [1, 16] _BUF_SIZE = 16 / sizeof (_Elem) < 1 ? 1 : 16 / sizeof(_Elem)}; protected: enum { // roundup mask for allocated buffers, [0, 15] _ALLOC_MASK = sizeof (_Elem) <= 1 ? 15 : sizeof (_Elem) <= 2 ? 7 : sizeof (_Elem) <= 4 ? 3 : sizeof (_Elem) <= 8 ? 1 : 0}; void _Chassign(size_type _Off, size_type _Count, _Elem _Ch) { // assign _Count copies of _Ch beginning at _Off if (_Count == 1) _Traits::assign(*(_Myptr() + _Off), _Ch); else _Traits::assign(_Myptr() + _Off, _Count, _Ch); } void _Copy(size_type _Newsize, size_type _Oldlen) { // copy _Oldlen elements to newly allocated buffer size_type _Newres = _Newsize | _ALLOC_MASK; if (max_size() < _Newres) _Newres = _Newsize; // undo roundup if too big else if (_Newres / 3 < _Myres / 2 && _Myres <= max_size() - _Myres / 2) _Newres = _Myres + _Myres / 2; // grow exponentially if possible _Elem *_Ptr; try { _Ptr = _Mybase::_Alval.allocate(_Newres + 1); } catch (...) { _Newres = _Newsize; // allocation failed, undo roundup and retry try { _Ptr = _Mybase::_Alval.allocate(_Newres + 1); } catch (...) { _Tidy(true); // failed again, discard storage and reraise throw; } } if (0 < _Oldlen) _Traits::copy(_Ptr, _Myptr(), _Oldlen); // copy existing elements _Tidy(true); _Bx._Ptr = _Ptr; _Myres = _Newres; _Eos(_Oldlen); } void _Eos(size_type _Newsize) { // set new length and null terminator _Traits::assign(_Myptr()[_Mysize = _Newsize], _Elem()); } bool _Grow(size_type _Newsize, bool _Trim = false) { // ensure buffer is big enough, trim to size if _Trim is true if (max_size() < _Newsize) _String_base::_Xlen(); // result too long if (_Myres < _Newsize) _Copy(_Newsize, _Mysize); // reallocate to grow else if (_Trim && _Newsize < _BUF_SIZE) _Tidy(true, // copy and deallocate if trimming to small string _Newsize < _Mysize ? _Newsize : _Mysize); else if (_Newsize == 0) _Eos(0); // new size is zero, just null terminate return (0 < _Newsize); // return true only if more work to do } bool _Inside(const _Elem *_Ptr) { // test if _Ptr points inside string ; if (_Ptr < _Myptr() || _Myptr() + _Mysize <= _Ptr) return (false); // don't ask else return (true); } static size_type _Pdif(const_iterator _P2, const_iterator _P1) { // compute safe iterator difference return ((_P2). _Myptr == 0 ? 0 : _P2 - _P1); } void _Tidy(bool _Built = false, size_type _Newsize = 0) { // initialize buffer, deallocating any storage if (!_Built) ; else if (_BUF_SIZE <= _Myres) { // copy any leftovers to small buffer and deallocate _Elem *_Ptr = _Bx._Ptr; if (0 < _Newsize) _Traits::copy(_Bx._Buf, _Ptr, _Newsize); _Mybase::_Alval.deallocate(_Ptr, _Myres + 1); } _Myres = _BUF_SIZE - 1; _Eos(_Newsize); } union _Bxty { // storage for small buffer or pointer to larger one _Elem _Buf[_BUF_SIZE]; _Elem *_Ptr; } _Bx; _Elem *_Myptr() { // determine current pointer to buffer for mutable string return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf); } const _Elem *_Myptr() const { // determine current pointer to buffer for nonmutable string return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf); } size_type _Mysize; // current length of string size_type _Myres; // current storage reserved for string }; // STATIC npos OBJECT template const typename basic_string<_Elem, _Traits, _Alloc>::size_type basic_string<_Elem, _Traits, _Alloc>::npos = (typename basic_string<_Elem, _Traits, _Alloc>::size_type)(-1); // basic_string TEMPLATE OPERATORS template inline void swap(basic_string<_Elem, _Traits, _Alloc>& _Left, basic_string<_Elem, _Traits, _Alloc>& _Right) { // swap _Left and _Right strings _Left.swap(_Right); } typedef basic_string, allocator > string; typedef basic_string, allocator > wstring; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // CLASS logic_error class logic_error : public ::std:: exception { // base of all logic-error exceptions public: explicit logic_error(const string& _Message) : _Str(_Message) { // construct from message string } virtual ~logic_error() { // destroy the object } virtual const char *what() const throw () { // return pointer to message string return (_Str.c_str()); } private: string _Str; // the stored message string }; // CLASS domain_error class domain_error : public logic_error { // base of all domain-error exceptions public: explicit domain_error(const string& _Message) : logic_error(_Message) { // construct from message string } virtual ~domain_error() { // destroy the object } }; // CLASS invalid_argument class invalid_argument : public logic_error { // base of all invalid-argument exceptions public: explicit invalid_argument(const string& _Message) : logic_error(_Message) { // construct from message string } virtual ~invalid_argument() { // destroy the object } }; // CLASS length_error class length_error : public logic_error { // base of all length-error exceptions public: explicit length_error(const string& _Message) : logic_error(_Message) { // construct from message string } virtual ~length_error() { // destroy the object } }; // CLASS out_of_range class out_of_range : public logic_error { // base of all out-of-range exceptions public: explicit out_of_range(const string& _Message) : logic_error(_Message) { // construct from message string } virtual ~out_of_range() { // destroy the object } }; // CLASS runtime_error class runtime_error : public ::std:: exception { // base of all runtime-error exceptions public: explicit runtime_error(const string& _Message) : _Str(_Message) { // construct from message string } virtual ~runtime_error() { // destroy the object } virtual const char *what() const throw () { // return pointer to message string return (_Str.c_str()); } private: string _Str; // the stored message string }; // CLASS overflow_error class overflow_error : public runtime_error { // base of all overflow-error exceptions public: explicit overflow_error(const string& _Message) : runtime_error(_Message) { // construct from message string } virtual ~overflow_error() { // destroy the object } }; // CLASS underflow_error class underflow_error : public runtime_error { // base of all underflow-error exceptions public: explicit underflow_error(const string& _Message) : runtime_error(_Message) { // construct from message string } virtual ~underflow_error() { // destroy the object } }; // CLASS range_error class range_error : public runtime_error { // base of all range-error exceptions public: explicit range_error(const string& _Message) : runtime_error(_Message) { // construct from message string } virtual ~range_error() { // destroy the object } }; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // xdebug internal header /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // xlocinfo internal header for gcc Linux // cctype standard header /*****************************************************************************/ /* ctype.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /************************************************************************/ /* */ /* CHARACTER TYPING FUNCTIONS AND MACROS */ /* */ /* Note that in this implementation, either macros or functions may */ /* be used. Macros are prefixed with an underscore. */ /* */ /************************************************************************/ //---------------------------------------------------------------------------- // IS RECOMMENDED OVER . IS PROVIDED FOR // COMPATIBILITY WITH C AND THIS USAGE IS DEPRECATED IN C++ //---------------------------------------------------------------------------- extern "C" namespace std { extern const far unsigned char _ctypes_[]; /************************************************************************/ /* FUNCTION DECLARATIONS */ /************************************************************************/ /****************************************************************************/ /* _ISFUNCDCL.H v7.3.6 */ /* */ /* Copyright (c) 2005-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ /* We need isblank for Dinkum math (C99 MATH support) */ extern "C" int isalnum(int _c); extern "C" int isalpha(int _c); extern "C" int iscntrl(int _c); extern "C" int isdigit(int _c); extern "C" int isgraph(int _c); extern "C" int islower(int _c); extern "C" int isprint(int _c); extern "C" int ispunct(int _c); extern "C" int isspace(int _c); extern "C" int isupper(int _c); extern "C" int isxdigit(int _c); extern "C" int isascii(int _c); extern "C" int toascii(int _c); extern "C" int toupper(int _c); extern "C" int tolower(int _c); } /* extern "C" namespace std */ /************************************************************************/ /* On this ELSE path, all the TI ctype table and ctype bit flags are */ /* defined. */ /************************************************************************/ /************************************************************************/ /* MACRO DEFINITIONS */ /************************************************************************/ /* remove any (improper) macro overrides */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // clocale standard header /*****************************************************************************/ /* locale.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ extern "C" namespace std { /* LOCALE CATEGORY INDEXES */ /* TYPE DEFINITIONS */ struct lconv { /* LC_NUMERIC */ char *decimal_point; char *grouping; char *thousands_sep; /* LC_MONETARY */ char *mon_decimal_point; char *mon_grouping; char *mon_thousands_sep; char *negative_sign; char *positive_sign; char *currency_symbol; char frac_digits; char n_cs_precedes; char n_sep_by_space; char n_sign_posn; char p_cs_precedes; char p_sep_by_space; char p_sign_posn; char *int_curr_symbol; char int_frac_digits; }; /* DECLARATIONS */ struct lconv *localeconv(void); char *setlocale(int, const char *); } /* extern "C" namespace std */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // ctime standard header /*****************************************************************************/ /* time.h v7.3.6 */ /* */ /* Copyright (c) 1990-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ extern "C" namespace std { typedef unsigned int clock_t; typedef unsigned int time_t; struct tm { int tm_sec; /* seconds after the minute - [0,59] */ int tm_min; /* minutes after the hour - [0,59] */ int tm_hour; /* hours after the midnight - [0,23] */ int tm_mday; /* day of the month - [1,31] */ int tm_mon; /* months since January - [0,11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday - [0,6] */ int tm_yday; /* days since Jan 1st - [0,365] */ int tm_isdst; /* Daylight Savings Time flag */ }; /*************************************************************************/ /* TIME ZONE STRUCTURE DEFINITION */ /*************************************************************************/ typedef struct { short daylight; long timezone; char tzname[4]; char dstname[4]; } TZ; extern far TZ _tz; /****************************************************************************/ /* FUNCTION DECLARATIONS. (NOTE : clock AND time ARE SYSTEM SPECIFIC) */ /****************************************************************************/ clock_t clock(void); time_t time(time_t *_timer); time_t mktime(struct tm *_tptr); double difftime(time_t _time1, time_t _time0); extern "C" char *ctime(const time_t *_timer); char *asctime(const struct tm *_timeptr); struct tm *gmtime(const time_t *_timer); struct tm *localtime(const time_t *_timer); size_t strftime(char *_out, size_t _maxsize, const char *_format, const struct tm *_timeptr); } /* extern "C" */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ /* xlocinfo.h internal header for gcc Linux */ /*****************************************************************************/ /* locale.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ using std::lconv; using std::localeconv; using std::setlocale; namespace std { extern "C" { /* CTYPE CODE BITS */ /* SUPPLEMENTAL LOCALE MACROS AND DECLARATIONS */ /* FUNCTION DECLARATIONS */ const short *_Getctyptab(); extern float _Stof(const char *, char **, long); extern double _Stod(const char *, char **, long); extern long double _Stold(const char *, char **, long); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // CLASS _Collvec struct _Collvec { // locale-specific collation information (none) char _Pad; }; // CLASS _Ctypevec struct _Ctypevec { // locale-specific ctype information const short *_Table; int _Delfl; }; // CLASS _Cvtvec struct _Cvtvec { // locale-specific codecvt information (none) char _Pad; }; // CLASS _Timevec class _Timevec { // smart pointer to information used by _Strftime public: void *_Getptr() const { // return pointer to time information return (0); } char _Pad; }; // CLASS _Locinfo class _Locinfo { // summary of all stuff peculiar to a locale used by standard facets public: typedef ::std:: _Collvec _Collvec; typedef ::std:: _Ctypevec _Ctypevec; typedef ::std:: _Cvtvec _Cvtvec; typedef ::std:: _Timevec _Timevec; _Locinfo(const char * = "C"); // construct from named locale _Locinfo(int, const char *); // construct from category ~_Locinfo(); // destroy the object _Locinfo& _Addcats(int, const char *); // add stuff for a category string _Getname() const { // return the new locale name return (_Newlocname); } _Collvec _Getcoll() const { // return collation stuff _Collvec _Vec = {0}; return (_Vec); } _Ctypevec _Getctype() const { // return ctype stuff _Ctypevec _Vec = {0}; _Vec._Table = ::std:: _Getctyptab(); _Vec._Delfl = 1; return (_Vec); } _Cvtvec _Getcvt() const { // return codecvt stuff _Cvtvec _Vec = {0}; return (_Vec); } const lconv *_Getlconv() const { // return localeconv stuff return (localeconv()); } _Timevec _Gettnames() const { // return names used by _Strftime _Timevec _Vec = {0}; return (_Vec); } const char *_Getdays() const { // return names for weekdays return (":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:Wednesday" ":Thu:Thursday:Fri:Friday:Sat:Saturday"); } const char *_Getmonths() const { // return names for months return (":Jan:January:Feb:February:Mar:March" ":Apr:April:May:May:Jun:June" ":Jul:July:Aug:August:Sep:September" ":Oct:October:Nov:November:Dec:December"); } const char *_Getfalse() const { // return false name (no C source) return ("false"); } const char *_Gettrue() const { // return true name (no C source) return ("true"); } private: _Lockit _Lock; // thread lock, because global locale is altered string _Oldlocname; // old locale name to revert to on destruction string _Newlocname; // new locale name for this object }; // TEMPLATE FUNCTION _LStrcoll template inline int _LStrcoll(const _Elem *_First1, const _Elem *_Last1, const _Elem *_First2, const _Elem *_Last2, const _Collvec *) { // perform locale-specific comparison of _Elem sequences for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2) if (*_First1 < *_First2) return (-1); // [_First1, _Last1) < [_First2, _Last2) else if (*_First2 < *_First1) return (+1); // [_First1, _Last1) > [_First2, _Last2) return (_First2 != _Last2 ? -1 : _First1 != _Last1 ? +1 : 0); } // TEMPLATE FUNCTION _LStrxfrm template inline size_t _LStrxfrm(_Elem *_First1, _Elem *_Last1, const _Elem *_First2, const _Elem *_Last2, const _Locinfo::_Collvec *) { // perform locale-specific transform of _Elems to [_First1, _Last1) size_t _Count = _Last2 - _First2; if (_Count <= (size_t)(_Last1 - _First1)) ::std:: memcpy(_First1, _First2, _Count * sizeof (_Elem)); return (_Count); } // FUNCTION _Mbrtowc inline int _Mbrtowc(wchar_t *_Wptr, const char *_Ptr, size_t _Count, _Mbstatet *_Pstate, const _Cvtvec *) { // perform locale-specific mbrtowc return (::std:: mbrtowc(_Wptr, _Ptr, _Count, (mbstate_t *)_Pstate)); } // FUNCTION _Strftime inline size_t _Strftime(char *_Ptr, size_t _Count, const char *_Format, const struct tm *_Ptime, void *) { // perform locale-specific strftime return (::std:: strftime(_Ptr, _Count, _Format, _Ptime)); } // FUNCTION _Tolower inline int _Tolower(int _Byte, const _Ctypevec *) { // perform locale-specific tolower return (::std:: tolower(_Byte & 0xff)); } // FUNCTION _Toupper inline int _Toupper(int _Byte, const _Ctypevec *) { // perform locale-specific toupper return (::std:: toupper(_Byte & 0xff)); } // FUNCTION _Wcrtomb inline int _Wcrtomb(char *_Ptr, wchar_t _Char, _Mbstatet *_Pstate, const _Cvtvec *) { // perform locale-specific wcrtomb return (::std:: wcrtomb(_Ptr, _Char, (mbstate_t *)_Pstate)); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // TEMPLATE CLASS _Locbase template class _Locbase { // define templatized category constants, instantiate on demand public: static const far int collate = (1 << ((1) - (1 < 2 ? 1 : 2))); static const far int ctype = (1 << ((2) - (1 < 2 ? 1 : 2))); static const far int monetary = (1 << ((3) - (1 < 2 ? 1 : 2))); static const far int numeric = (1 << ((4) - (1 < 2 ? 1 : 2))); static const far int time = (1 << ((5) - (1 < 2 ? 1 : 2))); static const far int messages = (1 << ((6) - (1 < 2 ? 1 : 2))); static const far int all = ((1 << (((6 + 1)) - (1 < 2 ? 1 : 2))) - 1); static const far int none = 0; }; template const int _Locbase<_Dummy>::collate; template const int _Locbase<_Dummy>::ctype; template const int _Locbase<_Dummy>::monetary; template const int _Locbase<_Dummy>::numeric; template const int _Locbase<_Dummy>::time; template const int _Locbase<_Dummy>::messages; template const int _Locbase<_Dummy>::all; template const int _Locbase<_Dummy>::none; // CLASS locale class locale; template const _Facet& use_facet(const locale&); class locale : public _Locbase { // nonmutable collection of facets that describe a locale public: typedef int category; // CLASS id class id { // identifier stamp, unique for each distinct kind of facet public: id(size_t _Val = 0) : _Id(_Val) { // construct with specified stamp value } operator size_t() { // get stamp, with lazy allocation if (_Id == 0) { // still zero, allocate stamp _Lockit _Lock(0); if (_Id == 0) _Id = ++_Id_cnt; } return (_Id); } private: id(const id&); // not defined id& operator=(const id&); // not defined size_t _Id; // the identifier stamp static far int _Id_cnt; // static source of unique stamps }; class _Locimp; // class facet class facet { // base class for all locale facets, performs reference counting friend class locale; friend class _Locimp; public: static size_t _Getcat(const facet ** = 0) { // get category value, or -1 if no corresponding C category return ((size_t)(-1)); } void _Incref() { // safely increment the reference count _Lockit _Lock(0); if (_Refs < (size_t)(-1)) ++_Refs; } facet *_Decref() { // safely decrement the reference count, return this when dead _Lockit _Lock(0); if (0 < _Refs && _Refs < (size_t)(-1)) --_Refs; return (_Refs == 0 ? this : 0); } void _Register(); // queue up lazy facet for destruction protected: virtual ~facet() { // destroy the object } protected: explicit facet(size_t _Initrefs = 0) : _Refs(_Initrefs) { // construct with initial reference count } private: facet(const facet&); // not defined facet& operator=(const facet&); // not defined size_t _Refs; // the reference count }; // CLASS _Locimp class _Locimp : public facet { // reference-counted actual implementation of a locale protected: ~_Locimp(); // destroy the object private: friend class locale; _Locimp(bool _Transparent = false); // construct from current locale _Locimp(const _Locimp&); // copy a _Locimp void _Addfac(facet *, size_t); // add a facet static _Locimp *_Makeloc(const _Locinfo&, category, _Locimp *, const locale *); // make essential facets static void _Makewloc(const _Locinfo&, category, _Locimp *, const locale *); // make wchar_t facets static void _Makexloc(const _Locinfo&, category, _Locimp *, const locale *); // make remaining facets facet **_Facetvec; // pointer to vector of facets size_t _Facetcount; // size of vector of facets category _Catmask; // mask describing implemented categories bool _Xparent; // true if locale is transparent string _Name; // locale name, or "*" if not known static far _Locimp *_Clocptr; // pointer to "C" locale object }; locale& _Addfac(facet *, size_t, size_t); // add a facet, copying on write template bool operator()(const basic_string<_Elem, _Traits, _Alloc>&, const basic_string<_Elem, _Traits, _Alloc>&) const; // compare strings template locale combine(const locale& _Loc) const { // combine two locales _Facet *_Facptr; try { _Facptr = (_Facet *)& ::std:: use_facet<_Facet>(_Loc); } catch (...) { throw runtime_error("locale::combine facet missing"); } _Locimp *_Newimp = new _Locimp(*_Ptr); _Newimp->_Addfac(_Facptr, _Facet::id); if (_Facet::_Getcat() != (size_t)(-1)) { // not a standard facet, result has no name _Newimp->_Catmask = 0; _Newimp->_Name = "*"; } return (locale(_Newimp)); } template locale(const locale& _Loc, _Facet *_Facptr) : _Ptr(new _Locimp(*_Loc._Ptr)) { // construct from _Loc, replacing facet with *_Facptr if (_Facptr != 0) { // replace facet _Ptr->_Addfac(_Facptr, _Facet::id); if (_Facet::_Getcat() != (size_t)(-1)) _Ptr->_Catmask = 0, _Ptr->_Name = "*"; // no C category } } locale() throw (); // construct from current locale locale(_Uninitialized) { // defer construction } locale(const locale& _Right) throw () : _Ptr(_Right._Ptr) { // construct by copying _Ptr->_Incref(); } locale(const locale&, const locale&, category); // construct from locale and category in another locale explicit locale(const char *, category = all); // construct from named locale for category locale(const locale&, const char *, category); // construct from locale and category in named locale ~locale() throw () { // destroy the object if (_Ptr != 0) delete (_Ptr->_Decref()); } locale& operator=(const locale& _Right) throw () { // assign a locale if (_Ptr != _Right._Ptr) { // different implementation, point at new one delete (_Ptr->_Decref()); _Ptr = _Right._Ptr; _Ptr->_Incref(); } return (*this); } string name() const { // return locale name return (_Ptr->_Name); } const facet *_Getfacet(size_t) const; // get facet by id bool operator==(const locale&) const; // test for locale equality bool operator!=(const locale& _Right) const { // test for locale inequality return (!(*this == _Right)); } static const locale& classic(); // return classic "C" locale static locale global(const locale&); // return current locale static locale empty(); // return empty (transparent) locale private: locale(_Locimp *_Ptrimp) : _Ptr(_Ptrimp) { // construct from _Locimp pointer } static _Locimp *_Init(); // initialize locale _Locimp *_Ptr; // pointer to locale implementation object }; // SUPPORT TEMPLATES template struct _Facetptr { // store pointer to lazy facet for use_facet static const far locale::facet *_Psave; }; template const locale::facet *_Facetptr<_Facet>::_Psave = 0; template inline const _Facet& use_facet(const locale& _Loc) { // get facet reference from locale _Lockit _Lock(0); // the thread lock, make get atomic const locale::facet *_Psave = _Facetptr<_Facet>::_Psave; // static pointer to lazy facet size_t _Id = _Facet::id; const locale::facet *_Pf = _Loc._Getfacet(_Id); if (_Pf != 0) ; // got facet from locale else if (_Psave != 0) _Pf = _Psave; // lazy facet already allocated else if (_Facet::_Getcat(&_Psave) == (size_t)(-1)) throw bad_cast(); // lazy disallowed else { // queue up lazy facet for destruction _Pf = _Psave; _Facetptr<_Facet>::_Psave = _Psave; locale::facet *_Pfmod = (_Facet *)_Psave; _Pfmod->_Incref(); _Pfmod->_Register(); } return ((const _Facet&)(*_Pf)); // should be dynamic_cast } // TEMPLATE FUNCTION _Getloctxt template inline int _Getloctxt(_InIt& _First, _InIt& _Last, size_t _Numfields, const _Elem *_Ptr) { // find field at _Ptr that matches longest in [_First, _Last) for (size_t _Off = 0; _Ptr[_Off] != (_Elem)0; ++_Off) if (_Ptr[_Off] == _Ptr[0]) ++_Numfields; // add fields with leading mark to initial count string _Str(_Numfields, '\0'); // one column counter for each field int _Ans = -2; // no candidates so far for (size_t _Column = 1; ; ++_Column, ++_First, _Ans = -1) { // test each element against all viable fields bool _Prefix = false; // seen at least one valid prefix size_t _Off = 0; // offset into fields size_t _Field = 0; // current field number for (; _Field < _Numfields; ++_Field) { // test element at _Column in field _Field for (; _Ptr[_Off] != (_Elem)0 && _Ptr[_Off] != _Ptr[0]; ++_Off) ; // find beginning of field if (_Str[_Field] != '\0') _Off += _Str[_Field]; // skip tested columns in field else if (_Ptr[_Off += _Column] == _Ptr[0] || _Ptr[_Off] == (_Elem)0) { // matched all of field, save as possible answer _Str[_Field] = (char)(_Column < 127 ? _Column : 127); // save skip count if small enough _Ans = (int)_Field; // save answer } else if (_First == _Last || _Ptr[_Off] != *_First) _Str[_Field] = (char)(_Column < 127 ? _Column : 127); // no match, just save skip count else _Prefix = true; // still a valid prefix } if (!_Prefix || _First == _Last) break; // no pending prefixes or no input, give up } return (_Ans); // return field number or negative value on failure } // TEMPLATE FUNCTION _Maklocbyte template inline char _Maklocbyte(_Elem _Char, const _Locinfo::_Cvtvec&) { // convert _Elem to char using _Cvtvec return ((char)(unsigned char)_Char); } template<> inline char _Maklocbyte(wchar_t _Char, const _Locinfo::_Cvtvec& _Cvt) { // convert wchar_t to char using _Cvtvec char _Byte = '\0'; _Mbstatet _Mbst1 = {0}; _Wcrtomb(&_Byte, _Char, &_Mbst1, &_Cvt); return (_Byte); } // TEMPLATE FUNCTION _Maklocchr template inline _Elem _Maklocchr(char _Byte, _Elem *, const _Locinfo::_Cvtvec&) { // convert char to _Elem using _Cvtvec return ((_Elem)(unsigned char)_Byte); } template<> inline wchar_t _Maklocchr(char _Byte, wchar_t *, const _Locinfo::_Cvtvec& _Cvt) { // convert char to wchar_t using _Cvtvec wchar_t _Wc = L'\0'; _Mbstatet _Mbst1 = {0}; _Mbrtowc(&_Wc, &_Byte, 1, &_Mbst1, &_Cvt); return (_Wc); } // TEMPLATE FUNCTION _Maklocstr template inline _Elem *_Maklocstr(const char *_Ptr, _Elem *, const _Locinfo::_Cvtvec&) { // convert C string to _Elem sequence using _Cvtvec size_t _Count = ::std:: strlen(_Ptr) + 1; _Elem *_Ptrdest = new _Elem[_Count]; for (_Elem *_Ptrnext = _Ptrdest; 0 < _Count; --_Count, ++_Ptrnext, ++_Ptr) *_Ptrnext = (_Elem)(unsigned char)*_Ptr; return (_Ptrdest); } template<> inline wchar_t *_Maklocstr(const char *_Ptr, wchar_t *, const _Locinfo::_Cvtvec& _Cvt) { // convert C string to wchar_t sequence using _Cvtvec size_t _Count, _Count1; size_t _Wchars; const char *_Ptr1; int _Bytes; wchar_t _Wc; _Mbstatet _Mbst1 = {0}; _Count1 = ::std:: strlen(_Ptr) + 1; for (_Count = _Count1, _Wchars = 0, _Ptr1 = _Ptr; 0 < _Count; _Count -= _Bytes, _Ptr1 += _Bytes, ++_Wchars) if ((_Bytes = _Mbrtowc(&_Wc, _Ptr1, _Count, &_Mbst1, &_Cvt)) <= 0) break; ++_Wchars; // count terminating nul wchar_t *_Ptrdest = new wchar_t[_Wchars]; wchar_t *_Ptrnext = _Ptrdest; _Mbstatet _Mbst2 = {0}; for (; 0 < _Wchars; _Count -= _Bytes, _Ptr += _Bytes, --_Wchars, ++_Ptrnext) if ((_Bytes = _Mbrtowc(_Ptrnext, _Ptr, _Count1, &_Mbst2, &_Cvt)) <= 0) break; *_Ptrnext = L'\0'; return (_Ptrdest); } // STRUCT codecvt_base class codecvt_base : public locale::facet { // base class for codecvt public: enum { // constants for different parse states ok, partial, error, noconv}; typedef int result; codecvt_base(size_t _Refs = 0) : locale::facet(_Refs) { // default constructor } bool always_noconv() const throw () { // return true if conversions never change input (from codecvt) return (do_always_noconv()); } int max_length() const throw () { // return maximum length required for a conversion (from codecvt) return (do_max_length()); } int encoding() const throw () { // return length of code sequence (from codecvt) return (do_encoding()); } ~codecvt_base() { // destroy the object } protected: virtual bool do_always_noconv() const throw () { // return true if conversions never change input (from codecvt) return (true); } virtual int do_max_length() const throw () { // return maximum length required for a conversion (from codecvt) return (1); } virtual int do_encoding() const throw () { // return length of code sequence (from codecvt) return (1); // -1 ==> state dependent, 0 ==> varying length } }; // TEMPLATE CLASS codecvt template class codecvt : public codecvt_base { // facet for converting between _Elem and char (_Byte) sequences public: typedef _Elem intern_type; typedef _Byte extern_type; typedef _Statype state_type; result in(_Statype& _State, const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1, _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const { // convert bytes [_First1, _Last1) to [_First2, _Last) return (do_in(_State, _First1, _Last1, _Mid1, _First2, _Last2, _Mid2)); } result out(_Statype& _State, const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const { // convert [_First1, _Last1) to bytes [_First2, _Last2) return (do_out(_State, _First1, _Last1, _Mid1, _First2, _Last2, _Mid2)); } result unshift(_Statype& _State, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const { // generate bytes to return to default shift state return (do_unshift(_State, _First2, _Last2, _Mid2)); } int length(const _Statype& _State, const _Byte *_First1, const _Byte *_Last1, size_t _Count) const { // return min(_Count, converted length of bytes [_First1, _Last1)) return (do_length(_State, _First1, _Last1, _Count)); } static far locale::id id; // unique facet id explicit codecvt(size_t _Refs = 0) : codecvt_base(_Refs) { // construct from current locale _Init(_Locinfo()); } codecvt(const _Locinfo& _Lobj, size_t _Refs = 0) : codecvt_base(_Refs) { // construct from specified locale _Init(_Lobj); } static size_t _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new codecvt<_Elem, _Byte, _Statype>; return (2); } protected: virtual ~codecvt() { // destroy the object } protected: void _Init(const _Locinfo&) { // initialize from _Locinfo object } virtual result do_in(_Statype&, const _Byte *_First1, const _Byte *, const _Byte *& _Mid1, _Elem *_First2, _Elem *, _Elem *& _Mid2) const { // convert bytes [_First1, _Last1) to [_First2, _Last) _Mid1 = _First1, _Mid2 = _First2; return (noconv); // convert nothing } virtual result do_out(_Statype&, const _Elem *_First1, const _Elem *, const _Elem *& _Mid1, _Byte *_First2, _Byte *, _Byte *& _Mid2) const { // convert [_First1, _Last1) to bytes [_First2, _Last) _Mid1 = _First1, _Mid2 = _First2; return (noconv); // convert nothing } virtual result do_unshift(_Statype&, _Byte *_First2, _Byte *, _Byte *&_Mid2) const { // generate bytes to return to default shift state _Mid2 = _First2; return (noconv); // convert nothing } virtual int do_length(const _Statype&, const _Byte *_First1, const _Byte *_Last1, size_t _Count) const { // return min(_Count, converted length of bytes [_First1, _Last1)) return ((int)(_Count < (size_t)(_Last1 - _First1) ? _Count : _Last1 - _First1)); // assume 1-to-1 conversion } }; // STATIC codecvt::id OBJECT template locale::id codecvt<_Elem, _Byte, _Statype>::id; // CLASS codecvt template<> class codecvt : public codecvt_base { // facet for converting between wchar_t and char (_Byte) sequences public: typedef wchar_t _Elem; typedef char _Byte; typedef _Mbstatet _Statype; typedef _Elem intern_type; typedef _Byte extern_type; typedef _Statype state_type; result in(_Statype& _State, const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1, _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const { // convert bytes [_First1, _Last1) to [_First2, _Last) return (do_in(_State, _First1, _Last1, _Mid1, _First2, _Last2, _Mid2)); } result out(_Statype& _State, const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const { // convert [_First1, _Last1) to bytes [_First2, _Last) return (do_out(_State, _First1, _Last1, _Mid1, _First2, _Last2, _Mid2)); } result unshift(_Statype& _State, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const { // generate bytes to return to default shift state return (do_unshift(_State, _First2, _Last2, _Mid2)); } int length(const _Statype& _State, const _Byte *_First1, const _Byte *_Last1, size_t _Count) const { // return min(_Count, converted length of bytes [_First1, _Last1)) return (do_length(_State, _First1, _Last1, _Count)); } static far locale::id id; // unique facet id explicit codecvt(size_t _Refs = 0) : codecvt_base(_Refs) { // construct from current locale _Init(_Locinfo()); } codecvt(const _Locinfo& _Lobj, size_t _Refs = 0) : codecvt_base(_Refs) { // construct from specified locale _Init(_Lobj); } static size_t _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new codecvt<_Elem, _Byte, _Statype>; return (2); } protected: virtual ~codecvt() { // destroy the object } protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Lobj _Cvt = _Lobj._Getcvt(); } virtual result do_in(_Statype& _State, const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1, _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const { // convert bytes [_First1, _Last1) to [_First2, _Last) ; ; _Mid1 = _First1, _Mid2 = _First2; result _Ans = _Mid1 == _Last1 ? ok : partial; int _Bytes; while (_Mid1 != _Last1 && _Mid2 != _Last2) switch (_Bytes = _Mbrtowc(_Mid2, _Mid1, _Last1 - _Mid1, &_State, &_Cvt)) { // test result of locale-specific mbrtowc call case -2: // partial conversion _Mid1 = _Last1; return (_Ans); case -1: // failed conversion return (error); case 0: // may have converted null character if (*_Mid2 == (_Elem)0) _Bytes = (int)::std:: strlen(_Mid1) + 1; // fall through default: // converted _Bytes bytes to a wchar_t _Mid1 += _Bytes, ++_Mid2, _Ans = ok; } return (_Ans); } virtual result do_out(_Statype& _State, const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const { // convert [_First1, _Last1) to bytes [_First2, _Last) ; ; _Mid1 = _First1, _Mid2 = _First2; result _Ans = _Mid1 == _Last1 ? ok : partial; int _Bytes; while (_Mid1 != _Last1 && _Mid2 != _Last2) if ((int)1 <= _Last2 - _Mid2) if ((_Bytes = _Wcrtomb(_Mid2, *_Mid1, &_State, &_Cvt)) < 0) return (error); // locale-specific wcrtomb failed else ++_Mid1, _Mid2 += _Bytes, _Ans = ok; else { // destination too small, convert into buffer _Byte _Buf[1]; _Statype _Stsave = _State; if ((_Bytes = _Wcrtomb(_Buf, *_Mid1, &_State, &_Cvt)) < 0) return (error); // locale-specific wcrtomb failed else if (_Last2 - _Mid2 < _Bytes) { // converted too many, roll back and return previous _State = _Stsave; return (_Ans); } else { // copy converted bytes from buffer ::std:: memcpy(_Mid2, _Buf, _Bytes); ++_Mid1, _Mid2 += _Bytes, _Ans = ok; } } return (_Ans); } virtual result do_unshift(_Statype& _State, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const { // generate bytes to return to default shift state ; _Mid2 = _First2; result _Ans = ok; int _Bytes; _Byte _Buf[1]; _Statype _Stsave = _State; if ((_Bytes = _Wcrtomb(_Buf, L'\0', &_State, &_Cvt)) <= 0) _Ans = error; // locale-specific wcrtomb failed else if (_Last2 - _Mid2 < --_Bytes) { // converted too many, roll back and return _State = _Stsave; _Ans = partial; } else if (0 < _Bytes) { // copy converted bytes from buffer ::std:: memcpy(_Mid2, _Buf, _Bytes); _Mid2 += _Bytes; } return (_Ans); } virtual int do_length(const _Statype& _State, const _Byte *_First1, const _Byte *_Last1, size_t _Count) const { // return min(_Count, converted length of bytes [_First1, _Last1)) ; int _Wchars; const _Byte *_Mid1; _Statype _Mystate = _State; for (_Wchars = 0, _Mid1 = _First1; (size_t)_Wchars < _Count && _Mid1 != _Last1; ) { // convert another wchar_t int _Bytes; _Elem _Ch; switch (_Bytes = _Mbrtowc(&_Ch, _Mid1, _Last1 - _Mid1, &_Mystate, &_Cvt)) { // test result of locale-specific mbrtowc call case -2: // partial conversion return (_Wchars); case -1: // failed conversion return (_Wchars); case 0: // may have converted null character if (_Ch == (_Elem)0) _Bytes = (int)::std:: strlen(_Mid1) + 1; // fall through default: // converted _Bytes bytes to a wchar_t _Mid1 += _Bytes, ++_Wchars; } } return (_Wchars); } virtual bool do_always_noconv() const throw () { // return true if conversions never change input return (false); } virtual int do_max_length() const throw () { // return maximum length required for a conversion (from codecvt) return (1); } virtual int do_encoding() const throw () { // return length of code sequence (from codecvt) return (0); } private: _Locinfo::_Cvtvec _Cvt; // locale info passed to _Mbrtowc, _Wcrtomb }; // TEMPLATE CLASS codecvt_byname template class codecvt_byname : public codecvt<_Elem, _Byte, _Statype> { // codecvt for named locale public: explicit codecvt_byname(const char *_Locname, size_t _Refs = 0) : codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Locname), _Refs) { // construct for named locale } protected: virtual ~codecvt_byname() { // destroy the object } }; // STRUCT ctype_base struct ctype_base : public locale::facet { // base for ctype enum { // constants for character classifications alnum = 0x20|0x10|0x02|0x200, alpha = 0x10|0x02|0x200, cntrl = 0x80, digit = 0x20, graph = 0x20|0x10|0x08|0x02|0x200, lower = 0x10, print = 0x20|0x10|0x08|0x04|0x02|0x200|0x01, punct = 0x08, space = 0x40|0x04|0x100, upper = 0x02, xdigit = 0x01}; typedef short mask; // to match ctype_base(size_t _Refs = 0) : locale::facet(_Refs) { // default constructor } ~ctype_base() { // destroy the object } }; // TEMPLATE CLASS ctype template class ctype : public ctype_base { // facet for classifying elements, converting cases public: typedef _Elem char_type; bool is(mask _Maskval, _Elem _Ch) const { // test if element fits any mask classifications return (do_is(_Maskval, _Ch)); } const _Elem *is(const _Elem *_First, const _Elem *_Last, mask *_Dest) const { // get mask sequence for elements in [_First, _Last) return (do_is(_First, _Last, _Dest)); } const _Elem *scan_is(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) that fits mask classification return (do_scan_is(_Maskval, _First, _Last)); } const _Elem *scan_not(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) not fitting mask classification return (do_scan_not(_Maskval, _First, _Last)); } _Elem tolower(_Elem _Ch) const { // convert element to lower case return (do_tolower(_Ch)); } const _Elem *tolower(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to lower case return (do_tolower(_First, _Last)); } _Elem toupper(_Elem _Ch) const { // convert element to upper case return (do_toupper(_Ch)); } const _Elem *toupper(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to upper case return (do_toupper(_First, _Last)); } _Elem widen(char _Byte) const { // widen char return (do_widen(_Byte)); } const char *widen(const char *_First, const char *_Last, _Elem *_Dest) const { // widen chars in [_First, _Last) return (do_widen(_First, _Last, _Dest)); } char narrow(_Elem _Ch, char _Dflt = '\0') const { // narrow element to char return (do_narrow(_Ch, _Dflt)); } const _Elem *narrow(const _Elem *_First, const _Elem *_Last, char _Dflt, char *_Dest) const { // narrow elements in [_First, _Last) to chars return (do_narrow(_First, _Last, _Dflt, _Dest)); } static far locale::id id; // unique facet id explicit ctype(size_t _Refs = 0) : ctype_base(_Refs) { // construct from current locale _Init(_Locinfo()); } ctype(const _Locinfo& _Lobj, size_t _Refs = 0) : ctype_base(_Refs) { // construct from specified locale _Init(_Lobj); } static size_t _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new ctype<_Elem>; return (2); } protected: virtual ~ctype() { // destroy the object if (_Ctype._Delfl) free((void *)_Ctype._Table); } protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Lobj _Ctype = _Lobj._Getctype(); } virtual bool do_is(mask _Maskval, _Elem _Ch) const { // test if element fits any mask classifications return ((_Ctype._Table[(unsigned char)narrow(_Ch)] & _Maskval) != 0); } virtual const _Elem *do_is(const _Elem *_First, const _Elem *_Last, mask *_Dest) const { // get mask sequence for elements in [_First, _Last) ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Ctype._Table[(unsigned char)narrow(*_First)]; return (_First); } virtual const _Elem *do_scan_is(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) that fits mask classification ; for (; _First != _Last && !is(_Maskval, *_First); ++_First) ; return (_First); } virtual const _Elem *do_scan_not(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) not fitting mask classification ; for (; _First != _Last && is(_Maskval, *_First); ++_First) ; return (_First); } virtual _Elem do_tolower(_Elem _Ch) const { // convert element to lower case unsigned char _Byte = (unsigned char)narrow(_Ch, '\0'); if (_Byte == '\0') return (_Ch); else return (widen((char)_Tolower(_Byte, &_Ctype))); } virtual const _Elem *do_tolower(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to lower case ; for (; _First != _Last; ++_First) { // convert *_First to lower case unsigned char _Byte = (unsigned char)narrow(*_First, '\0'); if (_Byte != '\0') *_First = (widen((char)_Tolower(_Byte, &_Ctype))); } return ((const _Elem *)_First); } virtual _Elem do_toupper(_Elem _Ch) const { // convert element to upper case unsigned char _Byte = (unsigned char)narrow(_Ch, '\0'); if (_Byte == '\0') return (_Ch); else return (widen((char)_Toupper(_Byte, &_Ctype))); } virtual const _Elem *do_toupper(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to upper case ; for (; _First != _Last; ++_First) { // convert *_First to upper case unsigned char _Byte = (unsigned char)narrow(*_First, '\0'); if (_Byte != '\0') *_First = (widen((char)_Toupper(_Byte, &_Ctype))); } return ((const _Elem *)_First); } virtual _Elem do_widen(char _Byte) const { // widen char return (_Maklocchr(_Byte, (_Elem *)0, _Cvt)); } virtual const char *do_widen(const char *_First, const char *_Last, _Elem *_Dest) const { // widen chars in [_First, _Last) ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Maklocchr(*_First, (_Elem *)0, _Cvt); return (_First); } char _Donarrow(_Elem _Ch, char _Dflt) const { // narrow element to char char _Byte; if (_Ch == (_Elem)0) return ('\0'); else if ((_Byte = _Maklocbyte((_Elem)_Ch, _Cvt)) == '\0') return (_Dflt); else return (_Byte); } virtual char do_narrow(_Elem _Ch, char _Dflt) const { // narrow element to char return (_Donarrow(_Ch, _Dflt)); } virtual const _Elem *do_narrow(const _Elem *_First, const _Elem *_Last, char _Dflt, char *_Dest) const { // narrow elements in [_First, _Last) to chars ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Donarrow(*_First, _Dflt); return (_First); } private: _Locinfo::_Ctypevec _Ctype; // locale info passed to _Tolower, etc. _Locinfo::_Cvtvec _Cvt; // conversion information }; // STATIC ctype::id OBJECT template locale::id ctype<_Elem>::id; // CLASS ctype template<> class ctype : public ctype_base { // facet for classifying char elements, converting cases typedef ctype _Myt; public: typedef char _Elem; typedef _Elem char_type; bool is(mask _Maskval, _Elem _Ch) const { // test if element fits any mask classifications return ((_Ctype._Table[(unsigned char)_Ch] & _Maskval) != 0); } const _Elem *is(const _Elem *_First, const _Elem *_Last, mask *_Dest) const { // get mask sequence for elements in [_First, _Last) ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Ctype._Table[(unsigned char)*_First]; return (_First); } const _Elem *scan_is(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) that fits mask classification ; for (; _First != _Last && !is(_Maskval, *_First); ++_First) ; return (_First); } const _Elem *scan_not(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) not fitting mask classification ; for (; _First != _Last && is(_Maskval, *_First); ++_First) ; return (_First); } _Elem tolower(_Elem _Ch) const { // convert element to lower case return (do_tolower(_Ch)); } const _Elem *tolower(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to lower case return (do_tolower(_First, _Last)); } _Elem toupper(_Elem _Ch) const { // convert element to upper case return (do_toupper(_Ch)); } const _Elem *toupper(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to upper case return (do_toupper(_First, _Last)); } _Elem widen(char _Byte) const { // widen char return (do_widen(_Byte)); } const _Elem *widen(const char *_First, const char *_Last, _Elem *_Dest) const { // widen chars in [_First, _Last) return (do_widen(_First, _Last, _Dest)); } _Elem narrow(_Elem _Ch, char _Dflt = '\0') const { // narrow element to char return (do_narrow(_Ch, _Dflt)); } const _Elem *narrow(const _Elem *_First, const _Elem *_Last, char _Dflt, char *_Dest) const { // narrow elements in [_First, _Last) to chars return (do_narrow(_First, _Last, _Dflt, _Dest)); } static far locale::id id; // unique facet id explicit ctype(const mask *_Table = 0, bool _Deletetable = false, size_t _Refs = 0) : ctype_base(_Refs) { // construct with specified table and delete flag for table _Init(_Locinfo()); if (_Table != 0) { // replace existing char to mask table _Tidy(); _Ctype._Table = _Table; _Ctype._Delfl = _Deletetable ? -1 : 0; } } ctype(const _Locinfo& _Lobj, size_t _Refs = 0) : ctype_base(_Refs) { // construct from current locale _Init(_Lobj); } static size_t _Getcat(const locale::facet **_Ppf = 0) { // construct from specified locale if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new ctype<_Elem>; return (2); } static const far size_t table_size; // size of _Ctype._Table (char to mask) protected: virtual ~ctype() { // destroy the object _Tidy(); } protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Lobj _Ctype = _Lobj._Getctype(); } void _Tidy() { // free any allocated storage if (0 < _Ctype._Delfl) free((void *)_Ctype._Table); else if (_Ctype._Delfl < 0) delete[] _Ctype._Table; } virtual _Elem do_tolower(_Elem _Ch) const { // convert element to lower case return ((_Elem)_Tolower((unsigned char)_Ch, &_Ctype)); } virtual const _Elem *do_tolower(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to lower case ; for (; _First != _Last; ++_First) *_First = (_Elem)_Tolower((unsigned char)*_First, &_Ctype); return ((const _Elem *)_First); } virtual _Elem do_toupper(_Elem _Ch) const { // convert element to upper case return ((_Elem)_Toupper((unsigned char)_Ch, &_Ctype)); } virtual const _Elem *do_toupper(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to upper case ; for (; _First != _Last; ++_First) *_First = (_Elem)_Toupper((unsigned char)*_First, &_Ctype); return ((const _Elem *)_First); } virtual _Elem do_widen(char _Byte) const { // widen char return (_Byte); } virtual const _Elem *do_widen(const char *_First, const char *_Last, _Elem *_Dest) const { // widen chars in [_First, _Last) ; ; ::std:: memcpy(_Dest, _First, _Last - _First); return (_Last); } virtual _Elem do_narrow(_Elem _Ch, char) const { // narrow char return (_Ch); } virtual const _Elem *do_narrow(const _Elem *_First, const _Elem *_Last, char, char *_Dest) const { // narrow elements in [_First, _Last) to chars ; ; ::std:: memcpy(_Dest, _First, _Last - _First); return (_Last); } const mask *table() const throw () { // return address of char to mask table return (_Ctype._Table); } static const mask *classic_table() throw () { // return address of char to mask table for "C" locale const _Myt& _Ctype_fac = use_facet< _Myt >(locale::classic()); return (_Ctype_fac.table()); } private: _Locinfo::_Ctypevec _Ctype; // information }; // CLASS ctype template<> class ctype : public ctype_base { // facet for classifying wchar_t elements, converting cases typedef ctype _Myt; public: typedef wchar_t _Elem; typedef _Elem char_type; bool is(mask _Maskval, _Elem _Ch) const { // test if element fits any mask classifications return (do_is(_Maskval, _Ch)); } const _Elem *is(const _Elem *_First, const _Elem *_Last, mask *_Dest) const { // get mask sequence for elements in [_First, _Last) return (do_is(_First, _Last, _Dest)); } const _Elem *scan_is(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) that fits mask classification return (do_scan_is(_Maskval, _First, _Last)); } const _Elem *scan_not(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) not fitting mask classification return (do_scan_not(_Maskval, _First, _Last)); } _Elem tolower(_Elem _Ch) const { // convert element to lower case return (do_tolower(_Ch)); } const _Elem *tolower(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to lower case return (do_tolower(_First, _Last)); } _Elem toupper(_Elem _Ch) const { // convert element to upper case return (do_toupper(_Ch)); } const _Elem *toupper(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to upper case return (do_toupper(_First, _Last)); } _Elem widen(char _Byte) const { // widen char return (do_widen(_Byte)); } const char *widen(const char *_First, const char *_Last, _Elem *_Dest) const { // widen chars in [_First, _Last) return (do_widen(_First, _Last, _Dest)); } char narrow(_Elem _Ch, char _Dflt = '\0') const { // narrow element to char return (do_narrow(_Ch, _Dflt)); } const _Elem *narrow(const _Elem *_First, const _Elem *_Last, char _Dflt, char *_Dest) const { // narrow elements in [_First, _Last) to chars return (do_narrow(_First, _Last, _Dflt, _Dest)); } static far locale::id id; // unique facet id explicit ctype(size_t _Refs = 0) : ctype_base(_Refs) { // construct from current locale _Init(_Locinfo()); } ctype(const _Locinfo& _Lobj, size_t _Refs = 0) : ctype_base(_Refs) { // construct from specified locale _Init(_Lobj); } static size_t _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new ctype<_Elem>; return (2); } protected: virtual ~ctype() { // destroy the object if (_Ctype._Delfl) free((void *)_Ctype._Table); } protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Lobj _Ctype = _Lobj._Getctype(); _Cvt = _Lobj._Getcvt(); } virtual bool do_is(mask _Maskval, _Elem _Ch) const { // test if element fits any mask classifications return ((_Ctype._Table[(unsigned char)narrow(_Ch)] & _Maskval) != 0); } virtual const _Elem *do_is(const _Elem *_First, const _Elem *_Last, mask *_Dest) const { // get mask sequence for elements in [_First, _Last) ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Ctype._Table[(unsigned char)narrow(*_First)]; return (_First); } virtual const _Elem *do_scan_is(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) that fits mask classification ; for (; _First != _Last && !is(_Maskval, *_First); ++_First) ; return (_First); } virtual const _Elem *do_scan_not(mask _Maskval, const _Elem *_First, const _Elem *_Last) const { // find first in [_First, _Last) not fitting mask classification ; for (; _First != _Last && is(_Maskval, *_First); ++_First) ; return (_First); } virtual _Elem do_tolower(_Elem _Ch) const { // convert element to lower case unsigned char _Byte = (unsigned char)narrow(_Ch, '\0'); if (_Byte == '\0') return (_Ch); else return (widen((char)_Tolower(_Byte, &_Ctype))); } virtual const _Elem *do_tolower(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to lower case ; for (; _First != _Last; ++_First) { // convert *_First to lower case unsigned char _Byte = (unsigned char)narrow(*_First, '\0'); if (_Byte != '\0') *_First = (widen((char)_Tolower(_Byte, &_Ctype))); } return ((const _Elem *)_First); } virtual _Elem do_toupper(_Elem _Ch) const { // convert element to upper case unsigned char _Byte = (unsigned char)narrow(_Ch, '\0'); if (_Byte == '\0') return (_Ch); else return (widen((char)_Toupper(_Byte, &_Ctype))); } virtual const _Elem *do_toupper(_Elem *_First, const _Elem *_Last) const { // convert [_First, _Last) in place to upper case ; for (; _First != _Last; ++_First) { // convert *_First to upper case unsigned char _Byte = (unsigned char)narrow(*_First, '\0'); if (_Byte != '\0') *_First = (widen((char)_Toupper(_Byte, &_Ctype))); } return ((const _Elem *)_First); } _Elem _Dowiden(char _Byte) const { // widen char _Mbstatet _Mbst = {0}; wchar_t _Wc; return (_Mbrtowc(&_Wc, &_Byte, 1, &_Mbst, &_Cvt) <= 0 ? (wchar_t)((wint_t)(-1)) : _Wc); } virtual _Elem do_widen(char _Byte) const { // widen char return (_Dowiden(_Byte)); } virtual const char *do_widen(const char *_First, const char *_Last, _Elem *_Dest) const { // widen chars in [_First, _Last) ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Dowiden(*_First); return (_First); } char _Donarrow(_Elem _Ch, char _Dflt) const { // narrow element to char char _Buf[1]; _Mbstatet _Mbst = {0}; return (_Wcrtomb(_Buf, _Ch, &_Mbst, &_Cvt) != 1 ? _Dflt : _Buf[0]); } virtual char do_narrow(_Elem _Ch, char _Dflt) const { // narrow element to char return (_Donarrow(_Ch, _Dflt)); } virtual const _Elem *do_narrow(const _Elem *_First, const _Elem *_Last, char _Dflt, char *_Dest) const { // narrow elements in [_First, _Last) to chars ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Donarrow(*_First, _Dflt); return (_First); } private: _Locinfo::_Ctypevec _Ctype; // locale info passed to _Tolower, etc. _Locinfo::_Cvtvec _Cvt; // conversion information }; // TEMPLATE CLASS ctype_byname template class ctype_byname : public ctype<_Elem> { // ctype for named locale public: explicit ctype_byname(const char *_Locname, size_t _Refs = 0) : ctype<_Elem>(_Locinfo(_Locname), _Refs) { // construct from named locale } protected: virtual ~ctype_byname() { // destroy the object } }; // TEMPLATE CLASS ctype_byname template<> class ctype_byname : public ctype { // ctype_byname for named locale public: explicit ctype_byname(const char *_Locname, size_t _Refs = 0) : ctype(_Locinfo(_Locname), _Refs) { // construct from named locale } protected: virtual ~ctype_byname() { // destroy the object } }; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // TEMPLATE CLASS _Iosb template class _Iosb { // define templatized bitmask/enumerated types, instantiate on demand public: enum _Dummy_enum {_Dummy_enum_val = 1}; // don't ask enum _Fmtflags { // constants for formatting options _Fmtmask = 0xffff, _Fmtzero = 0}; typedef _Fmtflags fmtflags; static const far _Fmtflags skipws = (_Fmtflags)0x0001; static const far _Fmtflags unitbuf = (_Fmtflags)0x0002; static const far _Fmtflags uppercase = (_Fmtflags)0x0004; static const far _Fmtflags showbase = (_Fmtflags)0x0008; static const far _Fmtflags showpoint = (_Fmtflags)0x0010; static const far _Fmtflags showpos = (_Fmtflags)0x0020; static const far _Fmtflags left = (_Fmtflags)0x0040; static const far _Fmtflags right = (_Fmtflags)0x0080; static const far _Fmtflags internal = (_Fmtflags)0x0100; static const far _Fmtflags dec = (_Fmtflags)0x0200; static const far _Fmtflags oct = (_Fmtflags)0x0400; static const far _Fmtflags hex = (_Fmtflags)0x0800; static const far _Fmtflags scientific = (_Fmtflags)0x1000; static const far _Fmtflags fixed = (_Fmtflags)0x2000; static const far _Fmtflags boolalpha = (_Fmtflags)0x4000; static const far _Fmtflags _Stdio = (_Fmtflags)0x8000; static const far _Fmtflags adjustfield = (_Fmtflags)(0x0040 | 0x0080 | 0x0100); static const far _Fmtflags basefield = (_Fmtflags)(0x0200 | 0x0400 | 0x0800); static const far _Fmtflags floatfield = (_Fmtflags)(0x1000 | 0x2000); enum _Iostate { // constants for stream states _Statmask = 0x17}; typedef _Iostate iostate; static const far _Iostate goodbit = (_Iostate)0x0; static const far _Iostate eofbit = (_Iostate)0x1; static const far _Iostate failbit = (_Iostate)0x2; static const far _Iostate badbit = (_Iostate)0x4; static const far _Iostate _Hardfail = (_Iostate)0x10; enum _Openmode { // constants for file opening options _Openmask = 0xff}; typedef _Openmode openmode; static const far _Openmode in = (_Openmode)0x01; static const far _Openmode out = (_Openmode)0x02; static const far _Openmode ate = (_Openmode)0x04; static const far _Openmode app = (_Openmode)0x08; static const far _Openmode trunc = (_Openmode)0x10; static const far _Openmode _Nocreate = (_Openmode)0x40; static const far _Openmode _Noreplace = (_Openmode)0x80; static const far _Openmode binary = (_Openmode)0x20; enum _Seekdir { // constants for file positioning options _Seekmask = 0x3}; typedef _Seekdir seekdir; static const far _Seekdir beg = (_Seekdir)0; static const far _Seekdir cur = (_Seekdir)1; static const far _Seekdir end = (_Seekdir)2; enum { // constant for default file opening protection _Openprot = 0666}; }; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::skipws; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::unitbuf; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::uppercase; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::showbase; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::showpoint; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::showpos; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::left; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::right; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::internal; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::dec; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::oct; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::hex; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::scientific; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::fixed; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::boolalpha; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::_Stdio; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::adjustfield; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::basefield; template const typename _Iosb<_Dummy>::_Fmtflags _Iosb<_Dummy>::floatfield; template const typename _Iosb<_Dummy>::_Iostate _Iosb<_Dummy>::goodbit; template const typename _Iosb<_Dummy>::_Iostate _Iosb<_Dummy>::eofbit; template const typename _Iosb<_Dummy>::_Iostate _Iosb<_Dummy>::failbit; template const typename _Iosb<_Dummy>::_Iostate _Iosb<_Dummy>::badbit; template const typename _Iosb<_Dummy>::_Iostate _Iosb<_Dummy>::_Hardfail; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::in; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::out; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::ate; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::app; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::trunc; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::_Nocreate; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::_Noreplace; template const typename _Iosb<_Dummy>::_Openmode _Iosb<_Dummy>::binary; template const typename _Iosb<_Dummy>::_Seekdir _Iosb<_Dummy>::beg; template const typename _Iosb<_Dummy>::_Seekdir _Iosb<_Dummy>::cur; template const typename _Iosb<_Dummy>::_Seekdir _Iosb<_Dummy>::end; // CLASS ios_base class ios_base : public _Iosb { // base class for ios public: typedef ::std:: streamoff streamoff; typedef ::std:: streampos streampos; enum event { // constants for ios events erase_event, imbue_event, copyfmt_event}; typedef void (*event_callback)(event, ios_base&, int); typedef unsigned int io_state, open_mode, seek_dir; // CLASS failure class failure : public runtime_error { // base of all iostreams exceptions public: explicit failure(const string &_Message) : runtime_error(_Message) { // construct with message } virtual ~failure() throw () { // destroy the object } }; // CLASS Init class Init { // controller for standard-stream initialization public: Init(); // initialize standard streams on first construction ~Init(); // flush standard streams on last destruction private: static far int _Init_cnt; // net constructions - destructions }; ios_base& operator=(const ios_base& _Right) { // assign state and format stuff from _Right if (this != &_Right) { // worth doing _Mystate = _Right._Mystate; copyfmt(_Right); } return (*this); } operator void *() const { // test if any stream operation has failed return (fail() ? 0 : (void *)this); } bool operator!() const { // test if no stream operation has failed return (fail()); } void clear(iostate, bool); // set state, possibly reraise exception void clear(iostate _State = goodbit) { // set state to argument clear(_State, false); } void clear(io_state _State) { // set state to argument, old-style clear((iostate)_State); } iostate rdstate() const { // return stream state return (_Mystate); } void setstate(iostate _State, bool _Exreraise) { // merge in state argument, possibly reraise exception if (_State != goodbit) clear((iostate)((int)rdstate() | (int)_State), _Exreraise); } void setstate(iostate _State) { // merge in state argument if (_State != goodbit) clear((iostate)((int)rdstate() | (int)_State), false); } void setstate(io_state _State) { // merge in state argument, old style setstate((iostate)_State); } bool good() const { // test if no state bits are set return (rdstate() == goodbit); } bool eof() const { // test if eofbit is set in stream state return ((int)rdstate() & (int)eofbit); } bool fail() const { // test if badbit or failbit is set in stream state return (((int)rdstate() & ((int)badbit | (int)failbit)) != 0); } bool bad() const { // test if badbit is set in stream state return (((int)rdstate() & (int)badbit) != 0); } iostate exceptions() const { // return exception mask return (_Except); } void exceptions(iostate _Newexcept) { // set exception mask to argument _Except = (iostate)((int)_Newexcept & (int)_Statmask); clear(_Mystate); } void exceptions(io_state _State) { // set exception mask to argument, old style exceptions((iostate)_State); } fmtflags flags() const { // return format flags return (_Fmtfl); } fmtflags flags(fmtflags _Newfmtflags) { // set format flags to argument fmtflags _Oldfmtflags = _Fmtfl; _Fmtfl = (fmtflags)((int)_Newfmtflags & (int)_Fmtmask); return (_Oldfmtflags); } fmtflags setf(fmtflags _Newfmtflags) { // merge in format flags argument ios_base::fmtflags _Oldfmtflags = _Fmtfl; _Fmtfl = (fmtflags)((int)_Fmtfl | (int)_Newfmtflags & (int)_Fmtmask); return (_Oldfmtflags); } fmtflags setf(fmtflags _Newfmtflags, fmtflags _Mask) { // merge in format flags argument under mask argument ios_base::fmtflags _Oldfmtflags = _Fmtfl; _Fmtfl = (fmtflags)(((int)_Fmtfl & (int)~_Mask) | ((int)_Newfmtflags & (int)_Mask & (int)_Fmtmask)); return (_Oldfmtflags); } void unsetf(fmtflags _Mask) { // clear format flags under mask argument _Fmtfl = (fmtflags)((int)_Fmtfl & (int)~_Mask); } streamsize precision() const { // return precision return (_Prec); } streamsize precision(streamsize _Newprecision) { // set precision to argument streamsize _Oldprecision = _Prec; _Prec = _Newprecision; return (_Oldprecision); } streamsize width() const { // return width return (_Wide); } streamsize width(streamsize _Newwidth) { // set width to argument streamsize _Oldwidth = _Wide; _Wide = _Newwidth; return (_Oldwidth); } locale getloc() const { // get locale return (*_Ploc); } locale imbue(const locale&); // set locale to argument static int xalloc() { // allocate new iword/pword index _Lockit _Lock(2); // lock thread to ensure atomicity return (_Index++); } long& iword(int _Idx) { // return reference to long element return (_Findarr(_Idx)._Lo); } void *& pword(int _Idx) { // return reference to pointer element return (_Findarr(_Idx)._Vp); } void register_callback(event_callback, int); // register event handler ios_base& copyfmt(const ios_base&); // copy format stuff virtual ~ios_base(); // destroy the object static bool sync_with_stdio(bool _Newsync = true) { // set C/C++ synchronization flag from argument _Lockit _Lock(2); // lock thread to ensure atomicity const bool _Oldsync = _Sync; _Sync = _Newsync; return (_Oldsync); } void _Addstd(); // add this to list of standard streams size_t _Stdstr; // if > 0 index of standard stream to suppress destruction protected: ios_base() { // default constructor } void _Init(); // initialize to standard values private: // STRUCT _Iosarray struct _Iosarray { // list element for open-ended sparse array of longs/pointers public: _Iosarray(int _Idx, _Iosarray *_Link) : _Next(_Link), _Index(_Idx), _Lo(0), _Vp(0) { // construct node for index _Idx and link it in } _Iosarray *_Next; // pointer to next node int _Index; // index of this node long _Lo; // stored long value void *_Vp; // stored pointer value }; // STRUCT _Fnarray struct _Fnarray { // list element for open-ended sparse array of event handlers _Fnarray(int _Idx, event_callback _Pnew, _Fnarray *_Link) : _Next(_Link), _Index(_Idx), _Pfn(_Pnew) { // construct node for index _Idx and link it in } _Fnarray *_Next; // pointer to next node int _Index; // index of this node event_callback _Pfn; // pointer to event handler }; void _Callfns(event); // call all event handlers, reporting event _Iosarray& _Findarr(int); // find an array element void _Tidy(); // free allocated storage iostate _Mystate; // stream state iostate _Except; // exception mask fmtflags _Fmtfl; // format flags streamsize _Prec; // field precision streamsize _Wide; // field width _Iosarray *_Arr; // pointer to first node of long/pointer array _Fnarray *_Calls; // pointer to first node of call list locale *_Ploc; // pointer to locale static far int _Index; // source of unique indexes for long/pointer array static far bool _Sync; // C/C++ synchronization flag (ignored) }; inline ios_base::_Fmtflags& operator&=(ios_base::_Fmtflags& _Left, ios_base::_Fmtflags _Right) { _Left = (ios_base::_Fmtflags)((int)_Left & (int)_Right); return _Left; } inline ios_base::_Fmtflags& operator|=(ios_base::_Fmtflags& _Left, ios_base::_Fmtflags _Right) { _Left = (ios_base::_Fmtflags)((int)_Left | (int)_Right); return _Left; } inline ios_base::_Fmtflags& operator^=(ios_base::_Fmtflags& _Left, ios_base::_Fmtflags _Right) { _Left = (ios_base::_Fmtflags)((int)_Left ^ (int)_Right); return _Left; } inline ios_base::_Fmtflags operator&(ios_base::_Fmtflags _Left, ios_base::_Fmtflags _Right) { return ((ios_base::_Fmtflags)((int)_Left & (int)_Right)); } inline ios_base::_Fmtflags operator|(ios_base::_Fmtflags _Left, ios_base::_Fmtflags _Right) { return ((ios_base::_Fmtflags)((int)_Left | (int)_Right)); } inline ios_base::_Fmtflags operator^(ios_base::_Fmtflags _Left, ios_base::_Fmtflags _Right) { return ((ios_base::_Fmtflags)((int)_Left ^ (int)_Right)); } inline ios_base::_Fmtflags operator~(ios_base::_Fmtflags _Left) { return ((ios_base::_Fmtflags)~(int)_Left); } inline ios_base::_Iostate& operator&=(ios_base::_Iostate& _Left, ios_base::_Iostate _Right) { _Left = (ios_base::_Iostate)((int)_Left & (int)_Right); return _Left; } inline ios_base::_Iostate& operator|=(ios_base::_Iostate& _Left, ios_base::_Iostate _Right) { _Left = (ios_base::_Iostate)((int)_Left | (int)_Right); return _Left; } inline ios_base::_Iostate& operator^=(ios_base::_Iostate& _Left, ios_base::_Iostate _Right) { _Left = (ios_base::_Iostate)((int)_Left ^ (int)_Right); return _Left; } inline ios_base::_Iostate operator&(ios_base::_Iostate _Left, ios_base::_Iostate _Right) { return ((ios_base::_Iostate)((int)_Left & (int)_Right)); } inline ios_base::_Iostate operator|(ios_base::_Iostate _Left, ios_base::_Iostate _Right) { return ((ios_base::_Iostate)((int)_Left | (int)_Right)); } inline ios_base::_Iostate operator^(ios_base::_Iostate _Left, ios_base::_Iostate _Right) { return ((ios_base::_Iostate)((int)_Left ^ (int)_Right)); } inline ios_base::_Iostate operator~(ios_base::_Iostate _Left) { return ((ios_base::_Iostate)~(int)_Left); } inline ios_base::_Openmode& operator&=(ios_base::_Openmode& _Left, ios_base::_Openmode _Right) { _Left = (ios_base::_Openmode)((int)_Left & (int)_Right); return _Left; } inline ios_base::_Openmode& operator|=(ios_base::_Openmode& _Left, ios_base::_Openmode _Right) { _Left = (ios_base::_Openmode)((int)_Left | (int)_Right); return _Left; } inline ios_base::_Openmode& operator^=(ios_base::_Openmode& _Left, ios_base::_Openmode _Right) { _Left = (ios_base::_Openmode)((int)_Left ^ (int)_Right); return _Left; } inline ios_base::_Openmode operator&(ios_base::_Openmode _Left, ios_base::_Openmode _Right) { return ((ios_base::_Openmode)((int)_Left & (int)_Right)); } inline ios_base::_Openmode operator|(ios_base::_Openmode _Left, ios_base::_Openmode _Right) { return ((ios_base::_Openmode)((int)_Left | (int)_Right)); } inline ios_base::_Openmode operator^(ios_base::_Openmode _Left, ios_base::_Openmode _Right) { return ((ios_base::_Openmode)((int)_Left ^ (int)_Right)); } inline ios_base::_Openmode operator~(ios_base::_Openmode _Left) { return ((ios_base::_Openmode)~(int)_Left); } inline ios_base::_Seekdir& operator&=(ios_base::_Seekdir& _Left, ios_base::_Seekdir _Right) { _Left = (ios_base::_Seekdir)((int)_Left & (int)_Right); return _Left; } inline ios_base::_Seekdir& operator|=(ios_base::_Seekdir& _Left, ios_base::_Seekdir _Right) { _Left = (ios_base::_Seekdir)((int)_Left | (int)_Right); return _Left; } inline ios_base::_Seekdir& operator^=(ios_base::_Seekdir& _Left, ios_base::_Seekdir _Right) { _Left = (ios_base::_Seekdir)((int)_Left ^ (int)_Right); return _Left; } inline ios_base::_Seekdir operator&(ios_base::_Seekdir _Left, ios_base::_Seekdir _Right) { return ((ios_base::_Seekdir)((int)_Left & (int)_Right)); } inline ios_base::_Seekdir operator|(ios_base::_Seekdir _Left, ios_base::_Seekdir _Right) { return ((ios_base::_Seekdir)((int)_Left | (int)_Right)); } inline ios_base::_Seekdir operator^(ios_base::_Seekdir _Left, ios_base::_Seekdir _Right) { return ((ios_base::_Seekdir)((int)_Left ^ (int)_Right)); } inline ios_base::_Seekdir operator~(ios_base::_Seekdir _Left) { return ((ios_base::_Seekdir)~(int)_Left); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // TEMPLATE CLASS basic_streambuf template class basic_streambuf { // control read/write buffers basic_streambuf(const basic_streambuf<_Elem, _Traits>&); // not defined basic_streambuf<_Elem, _Traits>& operator=(const basic_streambuf<_Elem, _Traits>&); // not defined protected: basic_streambuf() : _Plocale(new(locale)) { // construct with no buffers _Init(); } basic_streambuf(_Uninitialized) { // construct uninitialized } public: typedef basic_streambuf<_Elem, _Traits> _Myt; typedef _Elem char_type; typedef _Traits traits_type; virtual ~basic_streambuf() { // destroy the object delete (_Plocale); } typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; pos_type pubseekoff(off_type _Off, ios_base::seekdir _Way, ios_base::openmode _Mode = ios_base::in | ios_base::out) { // change position by _Off, according to _Way, _Mode return (seekoff(_Off, _Way, _Mode)); } pos_type pubseekoff(off_type _Off, ios_base::seek_dir _Way, ios_base::open_mode _Mode) { // change position by _Off, according to _Way, _Mode (old style) return (pubseekoff(_Off, (ios_base::seekdir)_Way, (ios_base::openmode)_Mode)); } pos_type pubseekpos(pos_type _Pos, ios_base::openmode _Mode = ios_base::in | ios_base::out) { // change position to _Pos, according to _Mode return (seekpos(_Pos, _Mode)); } pos_type pubseekpos(pos_type _Pos, ios_base::open_mode _Mode) { // change position to _Pos, according to _Mode (old style) return (seekpos(_Pos, (ios_base::openmode)_Mode)); } _Myt *pubsetbuf(_Elem *_Buffer, streamsize _Count) { // offer _Buffer to external agent return (setbuf(_Buffer, _Count)); } locale pubimbue(const locale &_Newlocale) { // set locale to argument locale _Oldlocale = *_Plocale; imbue(_Newlocale); *_Plocale = _Newlocale; return (_Oldlocale); } locale getloc() const { // get locale return (*_Plocale); } streamsize in_avail() { // return count of buffered input characters streamsize _Res = _Gnavail(); return (0 < _Res ? _Res : showmanyc()); } int pubsync() { // synchronize with external agent return (sync()); } int_type sbumpc() { // get a character and point past it return (0 < _Gnavail() ? _Traits::to_int_type(*_Gninc()) : uflow()); } int_type sgetc() { // get a character and don't point past it return (0 < _Gnavail() ? _Traits::to_int_type(*gptr()) : underflow()); } streamsize sgetn(_Elem *_Ptr, streamsize _Count) { // get up to _Count characters into array beginning at _Ptr return (xsgetn(_Ptr, _Count)); } int_type snextc() { // point to next character and return it return (1 < _Gnavail() ? _Traits::to_int_type(*_Gnpreinc()) : _Traits::eq_int_type(_Traits::eof(), sbumpc()) ? _Traits::eof() : sgetc()); } int_type sputbackc(_Elem _Ch) { // put back _Ch return (gptr() != 0 && eback() < gptr() && _Traits::eq(_Ch, gptr()[-1]) ? _Traits::to_int_type(*_Gndec()) : pbackfail(_Traits::to_int_type(_Ch))); } void stossc() { // point past a character if (0 < _Gnavail()) _Gninc(); else uflow(); } int_type sungetc() { // back up one position return (gptr() != 0 && eback() < gptr() ? _Traits::to_int_type(*_Gndec()) : pbackfail()); } int_type sputc(_Elem _Ch) { // put a character return (0 < _Pnavail() ? _Traits::to_int_type(*_Pninc() = _Ch) : overflow(_Traits::to_int_type(_Ch))); } streamsize sputn(const _Elem *_Ptr, streamsize _Count) { // put _Count characters from array beginning at _Ptr return (xsputn(_Ptr, _Count)); } virtual void _Lock() { // set the thread lock _Mylock._Lock(); } virtual void _Unlock() { // clear the thread lock _Mylock._Unlock(); } protected: _Elem *eback() const { // return beginning of read buffer return (*_IGfirst); } _Elem *gptr() const { // return current position in read buffer return (*_IGnext); } _Elem *pbase() const { // return beginning of write buffer return (*_IPfirst); } _Elem *pptr() const { // return current position in write buffer return (*_IPnext); } _Elem *egptr() const { // return end of read buffer return (*_IGlast); } void gbump(int _Off) { // alter current position in read buffer by _Off *_IGnext += _Off; } void setg(_Elem *_First, _Elem *_Next, _Elem *_Last) { // set pointers for read buffer *_IGfirst = _First, *_IGnext = _Next, *_IGlast = _Last; } _Elem *epptr() const { // return end of write buffer return (*_IPlast); } _Elem *_Gndec() { // decrement current position in read buffer return (--*_IGnext); } _Elem *_Gninc() { // increment current position in read buffer return ((*_IGnext)++); } _Elem *_Gnpreinc() { // preincrement current position in read buffer return (++(*_IGnext)); } streamsize _Gnavail() const { // count number of available elements in read buffer return (*_IGnext != 0 ? *_IGlast - *_IGnext : 0); } void pbump(int _Off) { // alter current position in write buffer by _Off *_IPnext += _Off; } void setp(_Elem *_First, _Elem *_Last) { // set pointers for write buffer *_IPfirst = _First, *_IPnext = _First, *_IPlast = _Last; } void setp(_Elem *_First, _Elem *_Next, _Elem *_Last) { // set pointers for write buffer, extended version *_IPfirst = _First, *_IPnext = _Next, *_IPlast = _Last; } _Elem *_Pninc() { // increment current position in write buffer return ((*_IPnext)++); } streamsize _Pnavail() const { // count number of available positions in write buffer return (*_IPnext != 0 ? *_IPlast - *_IPnext : 0); } void _Init() { // initialize buffer parameters for no buffers _IGfirst = &_Gfirst, _IPfirst = &_Pfirst; _IGnext = &_Gnext, _IPnext = &_Pnext; _IGlast = &_Glast, _IPlast = &_Plast; setp(0, 0), setg(0, 0, 0); } void _Init(_Elem **_Gf, _Elem **_Gn, _Elem **_Gl, _Elem **_Pf, _Elem **_Pn, _Elem **_Pl) { // initialize buffer parameters as specified _IGfirst = _Gf, _IPfirst = _Pf; _IGnext = _Gn, _IPnext = _Pn; _IGlast = _Gl, _IPlast = _Pl; } virtual int_type overflow(int_type = _Traits::eof()) { // put a character to stream (always fail) return (_Traits::eof()); } virtual int_type pbackfail(int_type = _Traits::eof()) { // put a character back to stream (always fail) return (_Traits::eof()); } virtual streamsize showmanyc() { // return count of input characters return (0); } virtual int_type underflow() { // get a character from stream, but don't point past it return (_Traits::eof()); } virtual int_type uflow() { // get a character from stream, point past it return (_Traits::eq_int_type(_Traits::eof(), underflow()) ? _Traits::eof() : _Traits::to_int_type(*_Gninc())); } virtual streamsize xsgetn(_Elem * _Ptr, streamsize _Count) { // get _Count characters from stream int_type _Meta; streamsize _Size, _Copied; for (_Copied = 0; 0 < _Count; ) if (0 < (_Size = _Gnavail())) { // copy from read buffer if (_Count < _Size) _Size = _Count; _Traits::copy(_Ptr, gptr(), _Size); _Ptr += _Size; _Copied += _Size; _Count -= _Size; gbump((int)_Size); } else if (_Traits::eq_int_type(_Traits::eof(), _Meta = uflow())) break; // end of file, quit else { // get a single character *_Ptr++ = _Traits::to_char_type(_Meta); ++_Copied; --_Count; } return (_Copied); } virtual streamsize xsputn(const _Elem *_Ptr, streamsize _Count) { // put _Count characters to stream streamsize _Size, _Copied; for (_Copied = 0; 0 < _Count; ) if (0 < (_Size = _Pnavail())) { // copy to write buffer if (_Count < _Size) _Size = _Count; _Traits::copy(pptr(), _Ptr, _Size); _Ptr += _Size; _Copied += _Size; _Count -= _Size; pbump((int)_Size); } else if (_Traits::eq_int_type(_Traits::eof(), overflow(_Traits::to_int_type(*_Ptr)))) break; // single character put failed, quit else { // count character successfully put ++_Ptr; ++_Copied; --_Count; } return (_Copied); } virtual pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode = ios_base::in | ios_base::out) { // change position by offset, according to way and mode return (streampos(_BADOFF)); } virtual pos_type seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out) { // change to specified position, according to mode return (streampos(_BADOFF)); } virtual _Myt *setbuf(_Elem *, streamsize) { // offer buffer to external agent (do nothing) return (this); } virtual int sync() { // synchronize with external agent (do nothing) return (0); } virtual void imbue(const locale&) { // set locale to argument (do nothing) } private: _Mutex _Mylock; // thread lock _Elem *_Gfirst; // beginning of read buffer _Elem *_Pfirst; // beginning of write buffer _Elem **_IGfirst; // pointer to beginning of read buffer _Elem **_IPfirst; // pointer to beginning of write buffer _Elem *_Gnext; // current position in read buffer _Elem *_Pnext; // current position in write buffer _Elem **_IGnext; // pointer to current position in read buffer _Elem **_IPnext; // pointer to current position in write buffer _Elem *_Glast; // end of read buffer _Elem *_Plast; // end of write buffer _Elem **_IGlast; // pointer to end of read buffer _Elem **_IPlast; // pointer to end of write buffer locale *_Plocale; // pointer to imbued locale object }; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // TEXT-TO-NUMERIC CONVERSION FUNCTIONS namespace std { extern "C" { extern long _Stolx(const char *, char **, int, int *); extern unsigned long _Stoulx(const char *, char **, int, int *); extern float _Stofx(const char *, char **, long, int *); extern double _Stodx(const char *, char **, long, int *); extern long double _Stoldx(const char *, char **, long, int *); extern long long _Stollx(const char *, char **, int, int *); extern unsigned long long _Stoullx(const char *, char **, int, int *); } } namespace std { // TEMPLATE CLASS numpunct template class numpunct : public locale::facet { // facet for defining numeric punctuation text public: typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> > string_type; typedef _Elem char_type; static far locale::id id; // unique facet id _Elem decimal_point() const { // return decimal point return (do_decimal_point()); } _Elem thousands_sep() const { // return thousands separator return (do_thousands_sep()); } string grouping() const { // return grouping string return (do_grouping()); } string_type falsename() const { // return name for false return (do_falsename()); } string_type truename() const { // return name for true return (do_truename()); } explicit numpunct(size_t _Refs = 0) : locale::facet(_Refs) { // construct from current locale _Init(_Locinfo()); } numpunct(const _Locinfo& _Lobj, size_t _Refs = 0) : locale::facet(_Refs) { // construct from specified locale _Init(_Lobj); } static size_t _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new numpunct<_Elem>; return (4); } protected: virtual ~numpunct() { // destroy the object _Tidy(); } protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Lobj const lconv *_Ptr = _Lobj._Getlconv(); _Grouping = 0; _Falsename = 0; _Truename = 0; try { _Grouping = _Maklocstr(_Ptr->grouping, (char *)0, _Lobj . _Getcvt()); _Falsename = _Maklocstr(_Lobj . _Getfalse(), (_Elem *)0, _Lobj . _Getcvt()); _Truename = _Maklocstr(_Lobj . _Gettrue(), (_Elem *)0, _Lobj . _Getcvt()); } catch (...) { _Tidy(); throw; } _Dp = _Maklocchr(_Ptr->decimal_point[0], (_Elem *)0, _Lobj . _Getcvt()); _Kseparator = _Maklocchr(_Ptr->thousands_sep[0], (_Elem *)0, _Lobj . _Getcvt()); } virtual _Elem do_decimal_point() const { // return decimal point return (_Dp); } virtual _Elem do_thousands_sep() const { // return thousands separator return (_Kseparator); } virtual string do_grouping() const { // return grouping string return (string(_Grouping)); } virtual string_type do_falsename() const { // return name for false return (string_type(_Falsename)); } virtual string_type do_truename() const { // return name for true return (string_type(_Truename)); } private: void _Tidy() { // free all storage delete[] _Grouping; delete[] _Falsename; delete[] _Truename; } const char *_Grouping; // grouping string, "" for "C" locale _Elem _Dp; // decimal point, '.' for "C" locale _Elem _Kseparator; // thousands separator, '\0' for "C" locale const _Elem *_Falsename; // name for false, "false" for "C" locale const _Elem *_Truename; // name for true, "true" for "C" locale }; typedef numpunct _Npc; typedef numpunct _Npwc; // TEMPLATE CLASS numpunct_byname template class numpunct_byname : public numpunct<_Elem> { // numpunct for named locale public: explicit numpunct_byname(const char *_Locname, size_t _Refs = 0) : numpunct<_Elem>(_Locinfo(_Locname), _Refs) { // construct for named locale } protected: virtual ~numpunct_byname() { // destroy the object } }; // STATIC numpunct::id OBJECT template locale::id numpunct<_Elem>::id; // TEMPLATE CLASS num_get template > > class num_get : public locale::facet { // facet for converting text to encoded numbers public: typedef numpunct<_Elem> _Mypunct; typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> > _Mystr; static size_t _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new num_get<_Elem, _InIt>; return (4); } static far locale::id id; // unique facet id protected: virtual ~num_get() { // destroy the object } protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Locinfo object _Cvt = _Lobj._Getcvt(); } _Locinfo::_Cvtvec _Cvt; // conversion information public: explicit num_get(size_t _Refs = 0) : locale::facet(_Refs) { // construct from current locale _Init(_Locinfo()); } num_get(const _Locinfo& _Lobj, size_t _Refs = 0) : locale::facet(_Refs) { // construct from specified locale _Init(_Lobj); } typedef _Elem char_type; typedef _InIt iter_type; _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _Bool& _Val) const { // get bool from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned short& _Val) const { // get unsigned short from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned int& _Val) const { // get unsigned int from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long& _Val) const { // get long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long& _Val) const { // get unsigned long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long long& _Val) const { // get long long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long long& _Val) const { // get unsigned long long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, float& _Val) const { // get float from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, double& _Val) const { // get double from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long double& _Val) const { // get long double from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } _InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, void *& _Val) const { // get void pointer from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } protected: virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _Bool& _Val) const { // get bool from [_First, _Last) into _Val ; int _Ans = -1; // negative answer indicates failure if (_Iosbase.flags() & ios_base::boolalpha) { // get false name or true name typedef typename _Mystr::size_type _Mystrsize; const _Mypunct& _Punct_fac = use_facet< _Mypunct >(_Iosbase.getloc()); _Mystr _Str((_Mystrsize)1, (char_type)0); _Str += _Punct_fac.falsename(); _Str += (char_type)0; _Str += _Punct_fac.truename(); // construct "\0false\0true" _Ans = _Getloctxt(_First, _Last, (size_t)2, _Str.c_str()); } else { // get zero or nonzero integer char _Ac[32], *_Ep; int _Errno = 0; const unsigned long _Ulo = ::std:: _Stoulx(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()), &_Errno); if (_Ep != _Ac && _Errno == 0 && _Ulo <= 1) _Ans = _Ulo; } if (_First == _Last) _State |= ios_base::eofbit; if (_Ans < 0) _State |= ios_base::failbit; else _Val = _Ans != 0; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned short& _Val) const { // get unsigned short from [_First, _Last) into _Val ; char _Ac[32], *_Ep; int _Errno = 0; int _Base = _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field into _Ac char *_Ptr = _Ac[0] == '-' ? _Ac + 1 : _Ac; // point past any sign const unsigned long _Ans = ::std:: _Stoulx(_Ptr, &_Ep, _Base, &_Errno); // convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ptr || _Errno != 0 || 65535 < _Ans) _State |= ios_base::failbit; else _Val = (unsigned short)(_Ac[0] == '-' ? 0 -_Ans : _Ans); // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned int& _Val) const { // get unsigned int from [_First, _Last) into _Val ; char _Ac[32], *_Ep; int _Errno = 0; int _Base = _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field into _Ac char *_Ptr = _Ac[0] == '-' ? _Ac + 1 : _Ac; // point past any sign const unsigned long _Ans = ::std:: _Stoulx(_Ptr, &_Ep, _Base, &_Errno); // convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ptr || _Errno != 0 || 4294967295U < _Ans) _State |= ios_base::failbit; else _Val = _Ac[0] == '-' ? 0 -_Ans : _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long& _Val) const { // get long from [_First, _Last) into _Val ; char _Ac[32], *_Ep; int _Errno = 0; const long _Ans = ::std:: _Stolx(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()), &_Errno); // gather field, convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long& _Val) const { // get unsigned long from [_First, _Last) into _Val ; char _Ac[32], *_Ep; int _Errno = 0; const unsigned long _Ans = ::std:: _Stoulx(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()), &_Errno); // gather field, convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long long& _Val) const { // get long long from [_First, _Last) into _Val ; char _Ac[32], *_Ep; int _Errno = 0; const long long _Ans = ::std:: _Stollx(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase . flags(), _Iosbase . getloc()), &_Errno); // gather field, convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long long& _Val) const { // get unsigned long long from [_First, _Last) into _Val ; char _Ac[32], *_Ep; int _Errno = 0; const unsigned long long _Ans = ::std:: _Stoullx(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase . flags(), _Iosbase . getloc()), &_Errno); // gather field, convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, float& _Val) const { // get float from [_First, _Last) into _Val ; char _Ac[8 + 36 + 16], *_Ep; int _Errno = 0; const float _Ans = ::std:: _Stofx(_Ac, &_Ep, _Getffld(_Ac, _First, _Last, _Iosbase.getloc()), &_Errno); // gather field, convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, double& _Val) const { // get double from [_First, _Last) into _Val ; char _Ac[8 + 36 + 16], *_Ep; int _Errno = 0; const double _Ans = ::std:: _Stodx(_Ac, &_Ep, _Getffld(_Ac, _First, _Last, _Iosbase.getloc()), &_Errno); // gather field, convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long double& _Val) const { // get long double from [_First, _Last) into _Val ; char _Ac[8 + 36 + 16], *_Ep; int _Errno = 0; const long double _Ans = ::std:: _Stoldx(_Ac, &_Ep, _Getffld(_Ac, _First, _Last, _Iosbase.getloc()), &_Errno); // gather field, convert if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } virtual _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, void *& _Val) const { // get void pointer from [_First, _Last) into _Val ; char _Ac[32], *_Ep; int _Errno = 0; int _Base = _Getifld(_Ac, _First, _Last, ios_base::hex, _Iosbase.getloc()); // gather field const unsigned long long _Ans = (sizeof (void *) == sizeof (unsigned long)) ? (unsigned long long)::std:: _Stoulx(_Ac, &_Ep, _Base, &_Errno) : ::std:: _Stoullx(_Ac, &_Ep, _Base, &_Errno); if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || _Errno != 0) _State |= ios_base::failbit; else #pragma diag_suppress 1107 _Val = (void *)_Ans; // deliver value #pragma diag_default 1107 return (_First); } private: int _Getifld(char *_Ac, _InIt& _First, _InIt& _Last, ios_base::fmtflags _Basefield, const locale& _Loc) const { // get integer field from [_First, _Last) into _Ac const _Mypunct& _Punct_fac = use_facet< _Mypunct >(_Loc); const string _Grouping = _Punct_fac.grouping(); const _Elem _Kseparator = _Punct_fac.thousands_sep(); const _Elem _E0 = _Maklocchr('0', (_Elem *)0, _Cvt); char *_Ptr = _Ac; if (_First == _Last) ; // empty field else if (*_First == _Maklocchr('+', (_Elem *)0, _Cvt)) *_Ptr++ = '+', ++_First; // gather plus sign else if (*_First == _Maklocchr('-', (_Elem *)0, _Cvt)) *_Ptr++ = '-', ++_First; // gather minus sign _Basefield &= ios_base::basefield; int _Base = _Basefield == ios_base::oct ? 8 : _Basefield == ios_base::hex ? 16 : _Basefield == ios_base::_Fmtzero ? 0 : 10; bool _Seendigit = false; // seen a digit in input bool _Nonzero = false; // seen a nonzero digit in input if (_First != _Last && *_First == _E0) { // leading zero, look for 0x, 0X _Seendigit = true, ++_First; if (_First != _Last && (*_First == _Maklocchr('x', (_Elem *)0, _Cvt) || *_First == _Maklocchr('X', (_Elem *)0, _Cvt)) && (_Base == 0 || _Base == 16)) _Base = 16, _Seendigit = false, ++_First; else if (_Base == 0) _Base = 8; } int _Dlen = _Base == 0 || _Base == 10 ? 10 : _Base == 8 ? 8 : 16 + 6; string _Groups((size_t)1, (char)_Seendigit); size_t _Group = 0; for (char *const _Pe = &_Ac[32 - 1]; _First != _Last; ++_First) if (::std:: memchr("0123456789abcdefABCDEF", *_Ptr = _Maklocbyte((_Elem)*_First, _Cvt), _Dlen) != 0) { // got a digit, characterize it and add to group size if ((_Nonzero || *_Ptr != '0') && _Ptr < _Pe) ++_Ptr, _Nonzero = true; _Seendigit = true; if (_Groups[_Group] != 127) ++_Groups[_Group]; } else if (_Groups[_Group] == '\0' || _Kseparator == (_Elem)0 || *_First != _Kseparator) break; // not a group separator, done else { // add a new group to _Groups string _Groups.append((string::size_type)1, '\0'); ++_Group; } if (_Group == 0) ; // no thousands separators seen else if ('\0' < _Groups[_Group]) ++_Group; // add trailing group to group count else _Seendigit = false; // trailing separator, fail for (const char *_Pg = _Grouping.c_str(); _Seendigit && 0 < _Group; ) if (*_Pg == 127) break; // end of grouping constraints to check else if (0 < --_Group && *_Pg != _Groups[_Group] || 0 == _Group && *_Pg < _Groups[_Group]) _Seendigit = false; // bad group size, fail else if ('\0' < _Pg[1]) ++_Pg; // group size okay, advance to next test if (_Seendigit && !_Nonzero) *_Ptr++ = '0'; // zero field, replace stripped zero(s) else if (!_Seendigit) _Ptr = _Ac; // roll back pointer to indicate failure *_Ptr = '\0'; return (_Base); } int _Getffld(char *_Ac, _InIt& _First, _InIt &_Last, const locale& _Loc) const { // get floating-point field from [_First, _Last) into _Ac const _Mypunct& _Punct_fac = use_facet< _Mypunct >(_Loc); const string _Grouping = _Punct_fac.grouping(); const _Elem _E0 = _Maklocchr('0', (_Elem *)0, _Cvt); char *_Ptr = _Ac; bool _Bad = false; if (_First == _Last) ; // empty field else if (*_First == _Maklocchr('+', (_Elem *)0, _Cvt)) *_Ptr++ = '+', ++_First; // gather plus sign else if (*_First == _Maklocchr('-', (_Elem *)0, _Cvt)) *_Ptr++ = '-', ++_First; // gather minus sign bool _Seendigit = false; // seen a digit in input int _Significant = 0; // number of significant digits int _Pten = 0; // power of 10 multiplier if (*_Grouping.c_str() == 127 || *_Grouping.c_str() <= '\0') for (; _First != _Last && _E0 <= *_First && *_First <= _E0 + 9; _Seendigit = true, ++_First) if (36 <= _Significant) ++_Pten; // just scale by 10 else if (*_First == _E0 && _Significant == 0) ; // drop leading zeros else { // save a significant digit *_Ptr++ = (char)((*_First - _E0) + '0'); ++_Significant; } else { // grouping specified, gather digits and group sizes const _Elem _Kseparator = _Punct_fac.thousands_sep(); string _Groups((size_t)1, '\0'); size_t _Group = 0; for (; _First != _Last; ++_First) if (_E0 <= *_First && *_First <= _E0 + 9) { // got a digit, add to group size _Seendigit = true; if (36 <= _Significant) ++_Pten; // just scale by 10 else if (*_First == _E0 && _Significant == 0) ; // drop leading zeros else { // save a significant digit *_Ptr++ = (char)((*_First - _E0) + '0'); ++_Significant; } if (_Groups[_Group] != 127) ++_Groups[_Group]; } else if (_Groups[_Group] == '\0' || _Kseparator == (_Elem)0 || *_First != _Kseparator) break; // not a group separator, done else { // add a new group to _Groups string _Groups.append((size_t)1, '\0'); ++_Group; } if (_Group == 0) ; // no thousands separators seen else if ('\0' < _Groups[_Group]) ++_Group; // add trailing group to group count else _Bad = true; // trailing separator, fail for (const char *_Pg = _Grouping.c_str(); !_Bad && 0 < _Group; ) if (*_Pg == 127) break; // end of grouping constraints to check else if (0 < --_Group && *_Pg != _Groups[_Group] || 0 == _Group && *_Pg < _Groups[_Group]) _Bad = true; // bad group size, fail else if ('\0' < _Pg[1]) ++_Pg; // group size okay, advance to next test } if (_Seendigit && _Significant == 0) *_Ptr++ = '0'; // save at least one leading digit if (_First != _Last && *_First == _Punct_fac.decimal_point()) *_Ptr++ = localeconv()->decimal_point[0], ++_First; // add . if (_Significant == 0) { // 0000. so far for (; _First != _Last && *_First == _E0; _Seendigit = true, ++_First) --_Pten; // just count leading fraction zeros if (_Pten < 0) *_Ptr++ = '0', ++_Pten; // put one back } for (; _First != _Last && _E0 <= *_First && *_First <= _E0 + 9; _Seendigit = true, ++_First) if (_Significant < 36) { // save a significant fraction digit *_Ptr++ = (char)((*_First - _E0) + '0'); ++_Significant; } if (_Seendigit && _First != _Last && (*_First == _Maklocchr('e', (_Elem *)0, _Cvt) || *_First == _Maklocchr('E', (_Elem *)0, _Cvt))) { // 'e' or 'E', collect exponent *_Ptr++ = 'e', ++_First; _Seendigit = false, _Significant = 0; if (_First == _Last) ; // 'e' or 'E' is last element else if (*_First == _Maklocchr('+', (_Elem *)0, _Cvt)) *_Ptr++ = '+', ++_First; // gather plus sign else if (*_First == _Maklocchr('-', (_Elem *)0, _Cvt)) *_Ptr++ = '-', ++_First; // gather minus sign for (; _First != _Last && *_First == _E0; ) _Seendigit = true, ++_First; // strip leading zeros if (_Seendigit) *_Ptr++ = '0'; // put one back for (; _First != _Last && _E0 <= *_First && *_First <= _E0 + 9; _Seendigit = true, ++_First) if (_Significant < 8) { // save a significant exponent digit *_Ptr++ = (char)((*_First - _E0) + '0'); ++_Significant; } } if (_Bad || !_Seendigit) _Ptr = _Ac; // roll back pointer to indicate failure *_Ptr = '\0'; return (_Pten); } }; // STATIC num_get::id OBJECT template locale::id num_get<_Elem, _InIt>::id; // TEMPLATE CLASS num_put template > > class num_put : public locale::facet { // facet for converting encoded numbers to text public: typedef numpunct<_Elem> _Mypunct; typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> > _Mystr; static size_t _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = new num_put<_Elem, _OutIt>; return (4); } static far locale::id id; // unique facet id protected: virtual ~num_put() { // destroy the object } protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Locinfo object _Cvt = _Lobj._Getcvt(); } _Locinfo::_Cvtvec _Cvt; // conversion information public: explicit num_put(size_t _Refs = 0) : locale::facet(_Refs) { // construct from current locale _Init(_Locinfo()); } num_put(const _Locinfo& _Lobj, size_t _Refs = 0) : locale::facet(_Refs) { // construct from specified locale _Init(_Lobj); } typedef _Elem char_type; typedef _OutIt iter_type; _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _Bool _Val) const { // put formatted bool to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long _Val) const { // put formatted long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long _Val) const { // put formatted unsigned long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long long _Val) const { // put formatted long long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long long _Val) const { // put formatted unsigned long long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, double _Val) const { // put formatted double to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long double _Val) const { // put formatted long double to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } _OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const void *_Val) const { // put formatted void pointer to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } protected: virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _Bool _Val) const { // put formatted bool to _Dest ; if (!(_Iosbase.flags() & ios_base::boolalpha)) return (do_put(_Dest, _Iosbase, _Fill, (long)_Val)); else { // put "false" or "true" const _Mypunct& _Punct_fac = use_facet< _Mypunct >(_Iosbase.getloc()); _Mystr _Str; if (_Val) _Str.assign(_Punct_fac.truename()); else _Str.assign(_Punct_fac.falsename()); size_t _Fillcount = _Iosbase.width() <= 0 || (size_t)_Iosbase.width() <= _Str.size() ? 0 : (size_t)_Iosbase.width() - _Str.size(); if ((_Iosbase.flags() & ios_base::adjustfield) != ios_base::left) { // put leading fill _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } _Dest = _Put(_Dest, _Str.c_str(), _Str.size()); // put field _Iosbase.width(0); return (_Rep(_Dest, _Fill, _Fillcount)); // put trailing fill } } virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long _Val) const { // put formatted long to _Dest char _Buf[2 * 32], _Fmt[6]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::std:: sprintf(_Buf, _Ifmt(_Fmt, "ld", _Iosbase.flags()), _Val))); } virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long _Val) const { // put formatted unsigned long to _Dest char _Buf[2 * 32], _Fmt[6]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::std:: sprintf(_Buf, _Ifmt(_Fmt, "lu", _Iosbase.flags()), _Val))); } virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long long _Val) const { // put formatted long long to _Dest char _Buf[2 * 32], _Fmt[8]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::std:: sprintf(_Buf, _Ifmt(_Fmt, "Ld", _Iosbase.flags()), _Val))); } virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long long _Val) const { // put formatted unsigned long long to _Dest char _Buf[2 * 32], _Fmt[8]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::std:: sprintf(_Buf, _Ifmt(_Fmt, "Lu", _Iosbase.flags()), _Val))); } virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, double _Val) const { // put formatted double to _Dest char _Buf[8 + 36 + 64], _Fmt[8]; streamsize _Precision = _Iosbase.precision() <= 0 && !(_Iosbase.flags() & ios_base::fixed) ? 6 : _Iosbase.precision(); // desired precision int _Significance = 36 < _Precision ? 36 : (int)_Precision; // actual sprintf precision _Precision -= _Significance; size_t _Beforepoint = 0; // zeros to add before decimal point size_t _Afterpoint = 0; // zeros to add after decimal point if ((_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed) { // scale silly fixed-point value bool _Signed = _Val < 0; if (_Signed) _Val = -_Val; for (; 1e35 <= _Val && _Beforepoint < 5000; _Beforepoint += 10) _Val /= 1e10; // drop 10 zeros before decimal point if (0 < _Val) for (; 10 <= _Precision && _Val <= 1e-35 && _Afterpoint < 5000; _Afterpoint += 10) { // drop 10 zeros after decimal point _Val *= 1e10; _Precision -= 10; } if (_Signed) _Val = -_Val; } return (_Fput(_Dest, _Iosbase, _Fill, _Buf, _Beforepoint, _Afterpoint, _Precision, ::std:: sprintf(_Buf, _Ffmt(_Fmt, 0, _Iosbase.flags()), _Significance, _Val))); // convert and put } virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long double _Val) const { // put formatted long double to _Dest char _Buf[8 + 36 + 64], _Fmt[8]; streamsize _Precision = _Iosbase.precision() <= 0 && !(_Iosbase.flags() & ios_base::fixed) ? 6 : _Iosbase.precision(); // desired precision int _Significance = 36 < _Precision ? 36 : (int)_Precision; // actual sprintf precision _Precision -= _Significance; size_t _Beforepoint = 0; // zeros to add before decimal point size_t _Afterpoint = 0; // zeros to add after decimal point if ((_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed) { // scale silly fixed-point value bool _Signed = _Val < 0; if (_Signed) _Val = -_Val; for (; 1e35 <= _Val && _Beforepoint < 5000; _Beforepoint += 10) _Val /= 1e10; // drop 10 zeros before decimal point if (0 < _Val) for (; 10 <= _Precision && _Val <= 1e-35 && _Afterpoint < 5000; _Afterpoint += 10) { // drop 10 zeros after decimal point _Val *= 1e10; _Precision -= 10; } if (_Signed) _Val = -_Val; } return (_Fput(_Dest, _Iosbase, _Fill, _Buf, _Beforepoint, _Afterpoint, _Precision, ::std:: sprintf(_Buf, _Ffmt(_Fmt, 'L', _Iosbase.flags()), _Significance, _Val))); // convert and put } virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const void *_Val) const { // put formatted void pointer to _Dest char _Buf[2 * 32], _Fmt[8]; unsigned long long _Off = (unsigned long long)_Val; if (sizeof (void *) == sizeof (unsigned long)) _Off = (unsigned long)_Off; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::std:: sprintf(_Buf, _Ifmt(_Fmt, "Lu", ios_base::hex), _Off))); } private: char *_Ffmt(char *_Fmt, char _Spec, ios_base::fmtflags _Flags) const { // generate sprintf format for floating-point char *_Ptr = _Fmt; *_Ptr++ = '%'; if (_Flags & ios_base::showpos) *_Ptr++ = '+'; if (_Flags & ios_base::showpoint) *_Ptr++ = '#'; *_Ptr++ = '.'; *_Ptr++ = '*'; // for precision argument if (_Spec != '\0') *_Ptr++ = _Spec; // 'L' qualifier for long double only ios_base::fmtflags _Ffl = _Flags & ios_base::floatfield; *_Ptr++ = _Ffl == ios_base::fixed ? 'f' : _Ffl == ios_base::scientific ? 'e' : 'g'; // specifier *_Ptr = '\0'; return (_Fmt); } _OutIt _Fput(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const char *_Buf, size_t _Beforepoint, size_t _Afterpoint, size_t _Trailing, size_t _Count) const { // put formatted floating-point to _Dest ; const _Mypunct& _Punct_fac = use_facet< _Mypunct >(_Iosbase.getloc()); const string _Grouping = _Punct_fac.grouping(); const _Elem _Kseparator = _Punct_fac.thousands_sep(); string _Groupstring; const _Elem _E0 = _Maklocchr('0', (_Elem *)0, _Cvt); size_t _Prefix = _Buf[0] == '+' || _Buf[0] == '-' ? 1 : 0; char _Enders[3]; _Enders[0] = ::std:: localeconv()->decimal_point[0]; _Enders[1] = 'e'; _Enders[2] = '\0'; if (*_Grouping.c_str() != 127 && '\0' < *_Grouping.c_str()) { // grouping specified, add thousands separators _Groupstring.append(_Buf, _Count); // assemble field into string const char *_Ptr = (const char *)::std:: memchr(_Buf, 'e', _Count); // find exponent if (_Ptr == 0) _Groupstring.append(_Trailing, '0'); else _Groupstring.insert(_Ptr - _Buf, _Trailing, '0'); _Ptr = (const char *)::std:: memchr(_Buf, _Enders[0], _Count); // find decimal point if (_Ptr == 0) _Groupstring.append(_Beforepoint, '0'); else { // fill in zeros around decimal point _Groupstring.insert(_Ptr - _Buf + 1, _Afterpoint, '0'); _Groupstring.insert(_Ptr - _Buf, _Beforepoint, '0'); } const char *_Pg = _Grouping.c_str(); size_t _Off = ::std:: strcspn(&_Groupstring[0], &_Enders[0]); while (*_Pg != 127 && '\0' < *_Pg && (size_t)*_Pg < _Off - _Prefix) { // add a comma to mark thousands separator _Groupstring.insert(_Off -= *_Pg, (size_t)1, ','); if ('\0' < _Pg[1]) ++_Pg; // not last group, advance } _Buf = &_Groupstring[0]; _Beforepoint = 0; _Afterpoint = 0; _Trailing = 0; _Count = _Groupstring.size(); } size_t _Fillcount = _Beforepoint + _Afterpoint + _Trailing + _Count; _Fillcount = _Iosbase.width() <= 0 || (size_t)_Iosbase.width() <= _Fillcount ? 0 : (size_t)_Iosbase.width() - _Fillcount; ios_base::fmtflags _Adjustfield = _Iosbase.flags() & ios_base::adjustfield; if (_Adjustfield != ios_base::left && _Adjustfield != ios_base::internal) { // put leading fill _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } else if (_Adjustfield == ios_base::internal) { // put internal fill if (0 < _Prefix) { // but first put sign _Dest = _Putc(_Dest, _Buf, 1); ++_Buf, --_Count; } _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } const char *_Ptr = (const char *)::std:: memchr(_Buf, _Enders[0], _Count); // find decimal point if (_Ptr != 0) { // has decimal point, put pieces and zero fills size_t _Fracoffset = _Ptr - _Buf + 1; _Dest = _Putgrouped(_Dest, _Buf, _Fracoffset - 1, _Kseparator); _Dest = _Rep(_Dest, _E0, _Beforepoint); _Dest = _Rep(_Dest, _Punct_fac.decimal_point(), 1); _Dest = _Rep(_Dest, _E0, _Afterpoint); _Buf += _Fracoffset, _Count -= _Fracoffset; } if ((_Ptr = (const char *)::std:: memchr(_Buf, 'e', _Count)) != 0) { // has exponent field, put it out size_t _Expoffset = _Ptr - _Buf + 1; _Dest = _Putgrouped(_Dest, _Buf, _Expoffset - 1, _Kseparator); _Dest = _Rep(_Dest, _E0, _Trailing), _Trailing = 0; _Dest = _Putc(_Dest, _Iosbase.flags() & ios_base::uppercase ? "E" : "e", 1); _Buf += _Expoffset, _Count -= _Expoffset; } _Dest = _Putgrouped(_Dest, _Buf, _Count, _Kseparator); // put leftover field _Dest = _Rep(_Dest, _E0, _Trailing); // put trailing zeros _Iosbase.width(0); return (_Rep(_Dest, _Fill, _Fillcount)); // put trailing fill } char *_Ifmt(char *_Fmt, const char *_Spec, ios_base::fmtflags _Flags) const { // generate sprintf format for integer char *_Ptr = _Fmt; *_Ptr++ = '%'; if (_Flags & ios_base::showpos) *_Ptr++ = '+'; if (_Flags & ios_base::showbase) *_Ptr++ = '#'; if (_Spec[0] != 'L') *_Ptr++ = _Spec[0]; // qualifier else { /* change L to ll */ *_Ptr++ = 'l'; *_Ptr++ = 'l'; } ios_base::fmtflags _Basefield = _Flags & ios_base::basefield; *_Ptr++ = _Basefield == ios_base::oct ? 'o' : _Basefield != ios_base::hex ? _Spec[1] // 'd' or 'u' : _Flags & ios_base::uppercase ? 'X' : 'x'; *_Ptr = '\0'; return (_Fmt); } _OutIt _Iput(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, char *_Buf, size_t _Count) const { // put formatted integer to _Dest ; const _Mypunct& _Punct_fac = use_facet< _Mypunct >(_Iosbase.getloc()); const string _Grouping = _Punct_fac.grouping(); const size_t _Prefix = *_Buf == '+' || *_Buf == '-' ? 1 : *_Buf == '0' && (_Buf[1] == 'x' || _Buf[1] == 'X') ? 2 : 0; if (*_Grouping.c_str() != 127 && '\0' < *_Grouping.c_str()) { // grouping specified, add thousands separators const char *_Pg = _Grouping.c_str(); size_t _Off = _Count; while (*_Pg != 127 && '\0' < *_Pg && (size_t)*_Pg < _Off - _Prefix) { // add a comma to mark thousands separator _Off -= *_Pg; ::std:: memmove(&_Buf[_Off + 1], &_Buf[_Off], _Count + 1 - _Off); _Buf[_Off] = ',', ++_Count; if ('\0' < _Pg[1]) ++_Pg; // not last group, advance } } size_t _Fillcount = _Iosbase.width() <= 0 || (size_t)_Iosbase.width() <= _Count ? 0 : (size_t)_Iosbase.width() - _Count; ios_base::fmtflags _Adjustfield = _Iosbase.flags() & ios_base::adjustfield; if (_Adjustfield != ios_base::left && _Adjustfield != ios_base::internal) { // put leading fill _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } else if (_Adjustfield == ios_base::internal) { // put internal fill _Dest = _Putc(_Dest, _Buf, _Prefix); // put prefix _Buf += _Prefix, _Count -= _Prefix; _Dest = _Rep(_Dest, _Fill, _Fillcount), _Fillcount = 0; } _Dest = _Putgrouped(_Dest, _Buf, _Count, _Punct_fac.thousands_sep()); // put field _Iosbase.width(0); return (_Rep(_Dest, _Fill, _Fillcount)); // put trailing fill } _OutIt _Put(_OutIt _Dest, const _Elem *_Ptr, size_t _Count) const { // put [_Ptr, _Ptr + _Count) to _Dest for (; 0 < _Count; --_Count, ++_Dest, ++_Ptr) *_Dest = *_Ptr; return (_Dest); } _OutIt _Putc(_OutIt _Dest, const char *_Ptr, size_t _Count) const { // put char sequence [_Ptr, _Ptr + _Count) to _Dest for (; 0 < _Count; --_Count, ++_Dest, ++_Ptr) *_Dest = _Maklocchr(*_Ptr, (_Elem *)0, _Cvt); return (_Dest); } _OutIt _Putgrouped(_OutIt _Dest, const char *_Ptr, size_t _Count, _Elem _Kseparator) const { // put char sequence [_Ptr, _Ptr + _Count) to _Dest with commas for (; ; ++_Ptr, --_Count) { // put field with thousands separators for commas const char *_Pend = (const char *)::std:: memchr(_Ptr, ',', _Count); size_t _Groupsize = _Pend != 0 ? _Pend - _Ptr : _Count; _Dest = _Putc(_Dest, _Ptr, _Groupsize); _Ptr += _Groupsize, _Count -= _Groupsize; if (_Count == 0) break; if (_Kseparator != (_Elem)0) _Dest = _Rep(_Dest, _Kseparator, 1); } return (_Dest); } _OutIt _Rep(_OutIt _Dest, _Elem _Ch, size_t _Count) const { // put _Count * _Ch to _Dest for (; 0 < _Count; --_Count, ++_Dest) *_Dest = _Ch; return (_Dest); } }; // STATIC num_put::id OBJECT template locale::id num_put<_Elem, _OutIt>::id; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // TEMPLATE CLASS basic_ios template class basic_ios : public ios_base { // base class for basic_istream/basic_ostream public: typedef basic_ios<_Elem, _Traits> _Myt; typedef basic_ostream<_Elem, _Traits> _Myos; typedef basic_streambuf<_Elem, _Traits> _Mysb; typedef ctype<_Elem> _Ctype; typedef _Elem char_type; typedef _Traits traits_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; explicit basic_ios(_Mysb *_Strbuf) { // construct from stream buffer pointer init(_Strbuf); } virtual ~basic_ios() { // destroy the object } void clear(iostate _State = goodbit, bool _Reraise = false) { // set state, possibly reraise exception ios_base::clear((iostate)(_Mystrbuf == 0 ? (int)_State | (int)badbit : (int)_State), _Reraise); } void clear(io_state _State) { // set state to _State clear((iostate)_State); } void setstate(iostate _State, bool _Reraise = false) { // merge _State into state, possible reraise exception if (_State != goodbit) clear((iostate)((int)rdstate() | (int)_State), _Reraise); } void setstate(io_state _State) { // merge _State into state setstate((iostate)_State); } _Myt& copyfmt(const _Myt& _Right) { // copy format parameters _Tiestr = _Right.tie(); _Fillch = _Right.fill(); ios_base::copyfmt(_Right); return (*this); } _Myos *tie() const { // return tie pointer return (_Tiestr); } _Myos *tie(_Myos *_Newtie) { // set tie pointer _Myos *_Oldtie = _Tiestr; _Tiestr = _Newtie; return (_Oldtie); } _Mysb *rdbuf() const { // return stream buffer pointer return (_Mystrbuf); } _Mysb *rdbuf(_Mysb *_Strbuf) { // set stream buffer pointer _Mysb *_Oldstrbuf = _Mystrbuf; _Mystrbuf = _Strbuf; clear(); return (_Oldstrbuf); } locale imbue(const locale& _Loc) { // set locale to argument locale _Oldlocale = ios_base::imbue(_Loc); if (rdbuf() != 0) rdbuf()->pubimbue(_Loc); return (_Oldlocale); } _Elem fill() const { // return fill character return (_Fillch); } _Elem fill(_Elem _Newfill) { // set fill character _Elem _Oldfill = _Fillch; _Fillch = _Newfill; return (_Oldfill); } char narrow(_Elem _Ch, char _Dflt = '\0') const { // convert _Ch to byte using imbued locale const _Ctype& _Ctype_fac = use_facet< _Ctype >(getloc()); return (_Ctype_fac.narrow(_Ch, _Dflt)); } _Elem widen(char _Byte) const { // convert _Byte to character using imbued locale const _Ctype& _Ctype_fac = use_facet< _Ctype >(getloc()); return (_Ctype_fac.widen(_Byte)); } protected: void init(_Mysb *_Strbuf = 0, bool _Isstd = false) { // initialize with stream buffer pointer _Init(); // initialize ios_base _Mystrbuf = _Strbuf; _Tiestr = 0; _Fillch = widen(' '); if (_Mystrbuf == 0) setstate(badbit); if (_Isstd) _Addstd(); // special handling for standard streams else _Stdstr = 0; } basic_ios() { // default constructor, do nothing } private: _Mysb *_Mystrbuf; // pointer to stream buffer _Myos *_Tiestr; // pointer to tied output stream _Elem _Fillch; // the fill character }; // MANIPULATORS inline ios_base& boolalpha(ios_base& _Iosbase) { // set boolalpha _Iosbase.setf(ios_base::boolalpha); return (_Iosbase); } inline ios_base& dec(ios_base& _Iosbase) { // set basefield to dec _Iosbase.setf(ios_base::dec, ios_base::basefield); return (_Iosbase); } inline ios_base& fixed(ios_base& _Iosbase) { // set floatfield to fixed _Iosbase.setf(ios_base::fixed, ios_base::floatfield); return (_Iosbase); } inline ios_base& hex(ios_base& _Iosbase) { // set basefield to hex _Iosbase.setf(ios_base::hex, ios_base::basefield); return (_Iosbase); } inline ios_base& internal(ios_base& _Iosbase) { // set adjustfield to internal _Iosbase.setf(ios_base::internal, ios_base::adjustfield); return (_Iosbase); } inline ios_base& left(ios_base& _Iosbase) { // set adjustfield to left _Iosbase.setf(ios_base::left, ios_base::adjustfield); return (_Iosbase); } inline ios_base& noboolalpha(ios_base& _Iosbase) { // clear boolalpha _Iosbase.unsetf(ios_base::boolalpha); return (_Iosbase); } inline ios_base& noshowbase(ios_base& _Iosbase) { // clear showbase _Iosbase.unsetf(ios_base::showbase); return (_Iosbase); } inline ios_base& noshowpoint(ios_base& _Iosbase) { // clear showpoint _Iosbase.unsetf(ios_base::showpoint); return (_Iosbase); } inline ios_base& noshowpos(ios_base& _Iosbase) { // clear showpos _Iosbase.unsetf(ios_base::showpos); return (_Iosbase); } inline ios_base& noskipws(ios_base& _Iosbase) { // clear skipws _Iosbase.unsetf(ios_base::skipws); return (_Iosbase); } inline ios_base& nounitbuf(ios_base& _Iosbase) { // clear unitbuf _Iosbase.unsetf(ios_base::unitbuf); return (_Iosbase); } inline ios_base& nouppercase(ios_base& _Iosbase) { // clear uppercase _Iosbase.unsetf(ios_base::uppercase); return (_Iosbase); } inline ios_base& oct(ios_base& _Iosbase) { // set oct in basefield _Iosbase.setf(ios_base::oct, ios_base::basefield); return (_Iosbase); } inline ios_base& right(ios_base& _Iosbase) { // set right in adjustfield _Iosbase.setf(ios_base::right, ios_base::adjustfield); return (_Iosbase); } inline ios_base& scientific(ios_base& _Iosbase) { // set scientific in floatfield _Iosbase.setf(ios_base::scientific, ios_base::floatfield); return (_Iosbase); } inline ios_base& showbase(ios_base& _Iosbase) { // set showbase _Iosbase.setf(ios_base::showbase); return (_Iosbase); } inline ios_base& showpoint(ios_base& _Iosbase) { // set showpoint _Iosbase.setf(ios_base::showpoint); return (_Iosbase); } inline ios_base& showpos(ios_base& _Iosbase) { // set showpos _Iosbase.setf(ios_base::showpos); return (_Iosbase); } inline ios_base& skipws(ios_base& _Iosbase) { // set skipws _Iosbase.setf(ios_base::skipws); return (_Iosbase); } inline ios_base& unitbuf(ios_base& _Iosbase) { // set unitbuf _Iosbase.setf(ios_base::unitbuf); return (_Iosbase); } inline ios_base& uppercase(ios_base& _Iosbase) { // set uppercase _Iosbase.setf(ios_base::uppercase); return (_Iosbase); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // I/O EXCEPTION MACROS // TEMPLATE CLASS basic_ostream template class basic_ostream : virtual public basic_ios<_Elem, _Traits> { // control insertions into a stream buffer public: typedef basic_ostream<_Elem, _Traits> _Myt; typedef basic_ios<_Elem, _Traits> _Myios; typedef basic_streambuf<_Elem, _Traits> _Mysb; typedef ostreambuf_iterator<_Elem, _Traits> _Iter; typedef num_put<_Elem, _Iter> _Nput; explicit basic_ostream(basic_streambuf<_Elem, _Traits> *_Strbuf, bool _Isstd = false) { // construct from a stream buffer pointer _Myios::init(_Strbuf, _Isstd); } basic_ostream(_Uninitialized) { // construct uninitialized ios_base::_Addstd(); } virtual ~basic_ostream() { // destroy the object } typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; class _Sentry_base { // stores thread lock and reference to output stream public: _Sentry_base(_Myt& _Ostr) : _Myostr(_Ostr) { // lock the stream buffer, if there if (_Myostr.rdbuf() != 0) _Myostr.rdbuf()->_Lock(); } ~_Sentry_base() { // destroy after unlocking if (_Myostr.rdbuf() != 0) _Myostr.rdbuf()->_Unlock(); } _Myt& _Myostr; // the output stream, for _Unlock call at destruction }; class sentry : public _Sentry_base { // stores thread lock and state of stream public: explicit sentry(_Myt& _Ostr) : _Sentry_base(_Ostr) { // construct locking and testing stream if (_Ostr.good() && _Ostr.tie() != 0) _Ostr.tie()->flush(); _Ok = _Ostr.good(); // store test only after flushing tie } ~sentry() { // destroy the object if (! ::std:: uncaught_exception()) this->_Myostr._Osfx(); } operator bool() const { // test if stream state okay return (_Ok); } private: sentry(const sentry&); // not defined sentry& operator=(const sentry&); // not defined bool _Ok; // true if stream state okay at construction }; bool opfx() { // test stream state and flush tie stream as needed (retained) if (ios_base::good() && _Myios::tie() != 0) _Myios::tie()->flush(); return (ios_base::good()); } void osfx() { // perform any wrapup (retained) _Osfx(); } void _Osfx() { // perform any wrapup if (ios_base::flags() & ios_base::unitbuf) flush(); // flush stream as needed } _Myt& operator<<(_Myt& (*_Pfn)(_Myt&)) { // call basic_ostream manipulator ; return ((*_Pfn)(*this)); } _Myt& operator<<(_Myios& (*_Pfn)(_Myios&)) { // call basic_ios manipulator ; (*_Pfn)(*(_Myios *)this); return (*this); } _Myt& operator<<(ios_base& (*_Pfn)(ios_base&)) { // call ios_base manipulator ; (*_Pfn)(*(ios_base *)this); return (*this); } _Myt& operator<<(_Bool _Val) { // insert a boolean ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(short _Val) { // insert a short ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); ios_base::fmtflags _Bfl = ios_base::flags() & ios_base::basefield; long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex) ? (long)(unsigned short)_Val : (long)_Val; try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Tmp).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(unsigned short _Val) { // insert an unsigned short ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), (unsigned long)_Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(int _Val) { // insert an int ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); ios_base::fmtflags _Bfl = ios_base::flags() & ios_base::basefield; long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex) ? (long)(unsigned int)_Val : (long)_Val; try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Tmp).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(unsigned int _Val) { // insert an unsigned int ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), (unsigned long)_Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(long _Val) { // insert a long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(unsigned long _Val) { // insert an unsigned long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(long long _Val) { // insert a long long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(unsigned long long _Val) { // insert an unsigned long long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(float _Val) { // insert a float ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), (double)_Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(double _Val) { // insert a double ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(long double _Val) { // insert a long double ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(const void *_Val) { // insert a void pointer ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = use_facet< _Nput >(ios_base::getloc()); try { if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator<<(_Mysb *_Strbuf) { // insert until end-of-file from a stream buffer ios_base::iostate _State = ios_base::goodbit; bool _Copied = false; const sentry _Ok(*this); if (_Ok && _Strbuf != 0) for (int_type _Meta = _Traits::eof(); ; _Copied = true) { // extract another character from stream buffer try { _Meta = _Traits::eq_int_type(_Traits::eof(), _Meta) ? _Strbuf->sgetc() : _Strbuf->snextc(); } catch (...) { _Myios::setstate(ios_base::failbit); throw; } if (_Traits::eq_int_type(_Traits::eof(), _Meta)) break; // end of file, quit try { if (_Traits::eq_int_type(_Traits::eof(), _Myios::rdbuf()->sputc( _Traits::to_char_type(_Meta)))) { // insertion failed, quit _State |= ios_base::badbit; break; } } catch (...) { _Myios::setstate(ios_base::badbit, true); } } ios_base::width(0); _Myios::setstate(_Strbuf == 0 ? ios_base::badbit : !_Copied ? _State | ios_base::failbit : _State); return (*this); } _Myt& put(_Elem _Ch) { // insert a character ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert character try { if (_Traits::eq_int_type(_Traits::eof(), _Myios::rdbuf()->sputc(_Ch))) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& write(const _Elem *_Str, streamsize _Count) { // insert _Count characters from array _Str ; ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert characters try { if (_Myios::rdbuf()->sputn(_Str, _Count) != _Count) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& flush() { // flush output stream ios_base::iostate _State = ios_base::goodbit; if (!ios_base::fail() && _Myios::rdbuf()->pubsync() == -1) _State |= ios_base::badbit; // sync failed _Myios::setstate(_State); return (*this); } _Myt& seekp(pos_type _Pos) { // set output stream position to _Pos if (!ios_base::fail() && (off_type)_Myios::rdbuf()->pubseekpos(_Pos, ios_base::out) == _BADOFF) _Myios::setstate(ios_base::failbit); return (*this); } _Myt& seekp(off_type _Off, ios_base::seekdir _Way) { // change output stream position by _Off, according to _Way if (!ios_base::fail() && (off_type)_Myios::rdbuf()->pubseekoff(_Off, _Way, ios_base::out) == _BADOFF) _Myios::setstate(ios_base::failbit); return (*this); } pos_type tellp() { // return output stream position if (!ios_base::fail()) return (_Myios::rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out)); else return (pos_type(_BADOFF)); } }; // INSERTERS template inline basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const char *_Val) { // insert NTBS ios_base::iostate _State = ios_base::goodbit; streamsize _Count = (streamsize)::std:: strlen(_Val); // may overflow streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count ? 0 : _Ostr.width() - _Count; const typename basic_ostream<_Elem, _Traits>::sentry _Ok(_Ostr); if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert characters try { const ctype<_Elem>& _Ctype_fac = use_facet< ctype<_Elem> >(_Ostr.getloc()); if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } for (; _State == ios_base::goodbit && 0 < _Count; --_Count, ++_Val) if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ctype_fac.widen(*_Val)))) _State |= ios_base::badbit; if (_State == ios_base::goodbit) for (; 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } _Ostr.width(0); } catch (...) { (_Ostr). setstate(ios_base::badbit, true); } } _Ostr.setstate(_State); return (_Ostr); } template inline basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, char _Ch) { // insert a character ios_base::iostate _State = ios_base::goodbit; const typename basic_ostream<_Elem, _Traits>::sentry _Ok(_Ostr); if (_Ok) { // state okay, insert const ctype<_Elem>& _Ctype_fac = use_facet< ctype<_Elem> >(_Ostr.getloc()); streamsize _Pad = _Ostr.width() <= 1 ? 0 : _Ostr.width() - 1; try { if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit; if (_State == ios_base::goodbit && _Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ctype_fac.widen(_Ch)))) _State |= ios_base::badbit; for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit; } catch (...) { (_Ostr). setstate(ios_base::badbit, true); } } _Ostr.width(0); _Ostr.setstate(_State); return (_Ostr); } template inline basic_ostream& operator<<( basic_ostream& _Ostr, const char *_Val) { // insert NTBS into char stream typedef char _Elem; typedef basic_ostream<_Elem, _Traits> _Myos; ios_base::iostate _State = ios_base::goodbit; streamsize _Count = (streamsize)_Traits::length(_Val); // may overflow streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count ? 0 : _Ostr.width() - _Count; const typename _Myos::sentry _Ok(_Ostr); if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert try { if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } if (_State == ios_base::goodbit && _Ostr.rdbuf()->sputn(_Val, _Count) != _Count) _State |= ios_base::badbit; if (_State == ios_base::goodbit) for (; 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } _Ostr.width(0); } catch (...) { (_Ostr). setstate(ios_base::badbit, true); } } _Ostr.setstate(_State); return (_Ostr); } template inline basic_ostream& operator<<( basic_ostream& _Ostr, char _Ch) { // insert a char into char stream typedef char _Elem; typedef basic_ostream<_Elem, _Traits> _Myos; ios_base::iostate _State = ios_base::goodbit; const typename _Myos::sentry _Ok(_Ostr); if (_Ok) { // state okay, insert streamsize _Pad = _Ostr.width() <= 1 ? 0 : _Ostr.width() - 1; try { if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit; if (_State == ios_base::goodbit && _Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ch))) _State |= ios_base::badbit; for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit; } catch (...) { (_Ostr). setstate(ios_base::badbit, true); } } _Ostr.width(0); _Ostr.setstate(_State); return (_Ostr); } template inline basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const _Elem *_Val) { // insert NTCS typedef basic_ostream<_Elem, _Traits> _Myos; ios_base::iostate _State = ios_base::goodbit; streamsize _Count = (streamsize)_Traits::length(_Val); // may overflow streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count ? 0 : _Ostr.width() - _Count; const typename _Myos::sentry _Ok(_Ostr); if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert try { if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } if (_State == ios_base::goodbit && _Ostr.rdbuf()->sputn(_Val, _Count) != _Count) _State |= ios_base::badbit; if (_State == ios_base::goodbit) for (; 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } _Ostr.width(0); } catch (...) { (_Ostr). setstate(ios_base::badbit, true); } } _Ostr.setstate(_State); return (_Ostr); } template inline basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, _Elem _Ch) { // insert a character typedef basic_ostream<_Elem, _Traits> _Myos; ios_base::iostate _State = ios_base::goodbit; const typename _Myos::sentry _Ok(_Ostr); if (_Ok) { // state okay, insert streamsize _Pad = _Ostr.width() <= 1 ? 0 : _Ostr.width() - 1; try { if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit; if (_State == ios_base::goodbit && _Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ch))) _State |= ios_base::badbit; for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit; } catch (...) { (_Ostr). setstate(ios_base::badbit, true); } } _Ostr.width(0); _Ostr.setstate(_State); return (_Ostr); } template inline basic_ostream& operator<<( basic_ostream& _Ostr, const signed char *_Val) { // insert a signed char NTBS return (_Ostr << (const char *)_Val); } template inline basic_ostream& operator<<( basic_ostream& _Ostr, signed char _Ch) { // insert a signed char return (_Ostr << (char)_Ch); } template inline basic_ostream& operator<<( basic_ostream& _Ostr, const unsigned char *_Val) { // insert an unsigned char NTBS return (_Ostr << (const char *)_Val); } template inline basic_ostream& operator<<( basic_ostream& _Ostr, unsigned char _Ch) { // insert an unsigned char return (_Ostr << (char)_Ch); } // MANIPULATORS template inline basic_ostream<_Elem, _Traits>& endl(basic_ostream<_Elem, _Traits>& _Ostr) { // insert newline and flush stream _Ostr.put(_Ostr.widen('\n')); _Ostr.flush(); return (_Ostr); } template inline basic_ostream<_Elem, _Traits>& ends(basic_ostream<_Elem, _Traits>& _Ostr) { // insert null character _Ostr.put(_Elem()); return (_Ostr); } template inline basic_ostream<_Elem, _Traits>& flush(basic_ostream<_Elem, _Traits>& _Ostr) { // flush stream _Ostr.flush(); return (_Ostr); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // TEMPLATE CLASS basic_istream template class basic_istream : virtual public basic_ios<_Elem, _Traits> { // control extractions from a stream buffer public: typedef basic_istream<_Elem, _Traits> _Myt; typedef basic_ios<_Elem, _Traits> _Myios; typedef basic_streambuf<_Elem, _Traits> _Mysb; typedef istreambuf_iterator<_Elem, _Traits> _Iter; typedef ctype<_Elem> _Ctype; typedef num_get<_Elem, _Iter> _Nget; explicit basic_istream(_Mysb *_Strbuf, bool _Isstd = false, bool _Noinit = false) : _Chcount(0) { // construct from stream buffer pointer if (!_Noinit) _Myios::init(_Strbuf, _Isstd); } basic_istream(_Uninitialized) { // construct uninitialized ios_base::_Addstd(); } virtual ~basic_istream() { // destroy the object } typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; // TEMPLATE CLASS sentry class _Sentry_base { // stores thread lock and reference to input stream public: _Sentry_base(_Myt& _Istr) : _Myistr(_Istr) { // lock the stream buffer, if there if (_Myistr.rdbuf() != 0) _Myistr.rdbuf()->_Lock(); } ~_Sentry_base() { // destroy after unlocking if (_Myistr.rdbuf() != 0) _Myistr.rdbuf()->_Unlock(); } _Myt& _Myistr; // the input stream, for _Unlock call at destruction }; class sentry : public _Sentry_base { // stores thread lock and result of _Ipfx call public: explicit sentry(_Myt& _Istr, bool _Noskip = false) : _Sentry_base(_Istr) { // construct locking and calling _Ipfx _Ok = this->_Myistr._Ipfx(_Noskip); } operator bool() const { // test if _Ipfx succeeded return (_Ok); } private: sentry(const sentry&); // not defined sentry& operator=(const sentry&); // not defined bool _Ok; // true if _Ipfx succeeded at construction }; bool _Ipfx(bool _Noskip = false) { // test stream state and skip whitespace as needed if (ios_base::good()) { // state okay, flush tied stream and skip whitespace if (_Myios::tie() != 0) _Myios::tie()->flush(); if (!_Noskip && ios_base::flags() & ios_base::skipws) { // skip whitespace const _Ctype& _Ctype_fac = use_facet< _Ctype >(ios_base::getloc()); try { int_type _Meta = _Myios::rdbuf()->sgetc(); for (; ; _Meta = _Myios::rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _Myios::setstate(ios_base::eofbit); break; } else if (!_Ctype_fac.is(_Ctype::space, _Traits::to_char_type(_Meta))) break; // not whitespace, quit } catch (...) { _Myios::setstate(ios_base::badbit, true); } } if (ios_base::good()) return (true); } _Myios::setstate(ios_base::failbit); return (false); } bool ipfx(bool _Noskip = false) { // test stream state and skip whitespace as needed (retained) return _Ipfx(_Noskip); } void isfx() { // perform any wrapup (retained) } _Myt& operator>>(_Myt& (*_Pfn)(_Myt&)) { // call basic_istream manipulator ; return ((*_Pfn)(*this)); } _Myt& operator>>(_Myios& (*_Pfn)(_Myios&)) { // call basic_ios manipulator ; (*_Pfn)(*(_Myios *)this); return (*this); } _Myt& operator>>(ios_base& (*_Pfn)(ios_base&)) { // call ios_base manipulator ; (*_Pfn)(*(ios_base *)this); return (*this); } _Myt& operator>>(_Bool& _Val) { // extract a boolean ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(short& _Val) { // extract a short ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract long _Tmp = 0; const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Tmp); } catch (...) { _Myios::setstate(ios_base::badbit, true); } if (_State & ios_base::failbit || _Tmp < -32768 || 32767 < _Tmp) _State |= ios_base::failbit; else _Val = (short)_Tmp; } _Myios::setstate(_State); return (*this); } _Myt& operator>>(unsigned short& _Val) { // extract an unsigned short ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(int& _Val) { // extract an int ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract long _Tmp = 0; const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Tmp); } catch (...) { _Myios::setstate(ios_base::badbit, true); } if (_State & ios_base::failbit || _Tmp < (-2147483647-1) || 2147483647 < _Tmp) _State |= ios_base::failbit; else _Val = _Tmp; } _Myios::setstate(_State); return (*this); } _Myt& operator>>(unsigned int& _Val) { // extract an unsigned int ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(long& _Val) { // extract a long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(unsigned long& _Val) { // extract an unsigned long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(long long& _Val) { // extract a long long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(unsigned long long& _Val) { // extract an unsigned long long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(float& _Val) { // extract a float ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(double& _Val) { // extract a double ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(long double& _Val) { // extract a long double ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(void *& _Val) { // extract a void pointer ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to extract const _Nget& _Nget_fac = use_facet< _Nget >(ios_base::getloc()); try { _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Val); } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& operator>>(_Mysb *_Strbuf) { // extract until end-of-file into a stream buffer ios_base::iostate _State = ios_base::goodbit; bool _Copied = false; const sentry _Ok(*this); if (_Ok && _Strbuf != 0) { // state okay, extract characters try { int_type _Meta = _Myios::rdbuf()->sgetc(); for (; ; _Meta = _Myios::rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else { // got a character, insert it into buffer try { if (_Traits::eq_int_type(_Traits::eof(), _Strbuf->sputc(_Traits::to_char_type(_Meta)))) break; } catch (...) { break; } _Copied = true; } } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(!_Copied ? _State | ios_base::failbit : _State); return (*this); } int_type get() { // extract a metacharacter int_type _Meta = 0; ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (!_Ok) _Meta = _Traits::eof(); // state not okay, return EOF else { // state okay, extract a character try { _Meta = _Myios::rdbuf()->sbumpc(); if (_Traits::eq_int_type(_Traits::eof(), _Meta)) _State |= ios_base::eofbit | ios_base::failbit; // end of file else ++_Chcount; // got a character, count it } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (_Meta); } _Myt& get(_Elem *_Str, streamsize _Count) { // get up to _Count characters into NTCS return (get(_Str, _Count, _Myios::widen('\n'))); } _Myt& get(_Elem *_Str, streamsize _Count, _Elem _Delim) { // get up to _Count characters into NTCS, stop before _Delim ; ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (_Ok && 0 < _Count) { // state okay, extract characters try { int_type _Meta = _Myios::rdbuf()->sgetc(); for (; 0 < --_Count; _Meta = _Myios::rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else if (_Traits::to_char_type(_Meta) == _Delim) break; // got a delimiter, quit else { // got a character, add it to string *_Str++ = _Traits::to_char_type(_Meta); ++_Chcount; } } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State); *_Str = _Elem(); // add terminating null character return (*this); } _Myt& get(_Elem& _Ch) { // get a character int_type _Meta = get(); if (!_Traits::eq_int_type(_Traits::eof(), _Meta)) _Ch = _Traits::to_char_type(_Meta); return (*this); } _Myt& get(_Mysb& _Strbuf) { // extract up to newline and insert into stream buffer return (get(_Strbuf, _Myios::widen('\n'))); } _Myt& get(_Mysb& _Strbuf, _Elem _Delim) { // extract up to delimiter and insert into stream buffer ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (_Ok) { // state okay, use facet to extract try { int_type _Meta = _Myios::rdbuf()->sgetc(); for (; ; _Meta = _Myios::rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else { // got a character, insert it into stream buffer try { _Elem _Ch = _Traits::to_char_type(_Meta); if (_Ch == _Delim || _Traits::eq_int_type(_Traits::eof(), _Strbuf.sputc(_Ch))) break; } catch (...) { break; } ++_Chcount; } } catch (...) { _Myios::setstate(ios_base::badbit, true); } } if (_Chcount == 0) _State |= ios_base::failbit; _Myios::setstate(_State); return (*this); } _Myt& getline(_Elem *_Str, streamsize _Count) { // get up to _Count characters into NTCS, discard newline return (getline(_Str, _Count, _Myios::widen('\n'))); } _Myt& getline(_Elem *_Str, streamsize _Count, _Elem _Delim) { // get up to _Count characters into NTCS, discard _Delim ; ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (_Ok && 0 < _Count) { // state okay, use facet to extract int_type _Metadelim = _Traits::to_int_type(_Delim); try { int_type _Meta = _Myios::rdbuf()->sgetc(); for (; ; _Meta = _Myios::rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else if (_Meta == _Metadelim) { // got a delimiter, discard it and quit ++_Chcount; _Myios::rdbuf()->sbumpc(); break; } else if (--_Count <= 0) { // buffer full, quit _State |= ios_base::failbit; break; } else { // got a character, add it to string ++_Chcount; *_Str++ = _Traits::to_char_type(_Meta); } } catch (...) { _Myios::setstate(ios_base::badbit, true); } } *_Str = _Elem(); // add terminating null character _Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State); return (*this); } _Myt& ignore(streamsize _Count = 1, int_type _Metadelim = _Traits::eof()) { // ignore up to _Count characters, discarding delimiter ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (_Ok && 0 < _Count) { // state okay, use facet to extract try { for (; ; ) { // get a metacharacter if more room in buffer int_type _Meta; if (_Count != 2147483647 && --_Count < 0) break; // buffer full, quit else if (_Traits::eq_int_type(_Traits::eof(), _Meta = _Myios::rdbuf()->sbumpc())) { // end of file, quit _State |= ios_base::eofbit; break; } else { // got a character, count it ++_Chcount; if (_Meta == _Metadelim) break; // got a delimiter, quit } } } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& read(_Elem *_Str, streamsize _Count) { // read up to _Count characters into buffer ; ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (_Ok) { // state okay, use facet to extract try { const streamsize _Num = _Myios::rdbuf()->sgetn(_Str, _Count); _Chcount += _Num; if (_Num != _Count) _State |= ios_base::eofbit | ios_base::failbit; // short read } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } streamsize readsome(_Elem *_Str, streamsize _Count) { // read up to _Count characters into buffer, without blocking ; ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); streamsize _Num; if (!_Ok) _State |= ios_base::failbit; // no buffer, fail else if ((_Num = _Myios::rdbuf()->in_avail()) < 0) _State |= ios_base::eofbit; // no characters available else if (0 < _Num) read(_Str, _Num < _Count ? _Num : _Count); // read available _Myios::setstate(_State); return (gcount()); } int_type peek() { // return next character, unconsumed ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; int_type _Meta = 0; const sentry _Ok(*this, true); if (!_Ok) _Meta = _Traits::eof(); // state not okay, return EOF else { // state okay, read a character try { if (_Traits::eq_int_type(_Traits::eof(), _Meta = _Myios::rdbuf()->sgetc())) _State |= ios_base::eofbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (_Meta); } _Myt& putback(_Elem _Ch) { // put back a character ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (_Ok) { // state okay, put character back try { if (_Traits::eq_int_type(_Traits::eof(), _Myios::rdbuf()->sputbackc(_Ch))) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } _Myt& unget() { // put back last read character ios_base::iostate _State = ios_base::goodbit; _Chcount = 0; const sentry _Ok(*this, true); if (_Ok) { // state okay, use facet to extract try { if (_Traits::eq_int_type(_Traits::eof(), _Myios::rdbuf()->sungetc())) _State |= ios_base::badbit; } catch (...) { _Myios::setstate(ios_base::badbit, true); } } _Myios::setstate(_State); return (*this); } streamsize gcount() const { // get count from last extraction return (_Chcount); } int sync() { // synchronize with input source ios_base::iostate _State = ios_base::goodbit; int _Ans; if (_Myios::rdbuf() == 0) _Ans = -1; // no buffer, fail else if (_Myios::rdbuf()->pubsync() == -1) { // stream buffer sync failed, fail _State |= ios_base::badbit; _Ans = -1; } else _Ans = 0; // success _Myios::setstate(_State); return (_Ans); } _Myt& seekg(pos_type _Pos) { // set input stream position to _Pos if (!ios_base::fail() && (off_type)_Myios::rdbuf()->pubseekpos(_Pos, ios_base::in) == _BADOFF) _Myios::setstate(ios_base::failbit); return (*this); } _Myt& seekg(off_type _Off, ios_base::seekdir _Way) { // change input stream position by _Off, according to _Way if (!ios_base::fail() && (off_type)_Myios::rdbuf()->pubseekoff(_Off, _Way, ios_base::in) == _BADOFF) _Myios::setstate(ios_base::failbit); return (*this); } pos_type tellg() { // return input stream position if (!ios_base::fail()) return (_Myios::rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in)); else return (pos_type(_BADOFF)); } private: streamsize _Chcount; // the character count }; // TEMPLATE CLASS basic_iostream template class basic_iostream : public basic_istream<_Elem, _Traits>, public basic_ostream<_Elem, _Traits> { // control insertions and extractions from a stream buffer public: typedef _Elem char_type; typedef _Traits traits_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; explicit basic_iostream(basic_streambuf<_Elem, _Traits> *_Strbuf) : basic_istream<_Elem, _Traits>(_Strbuf, false, true), basic_ostream<_Elem, _Traits>(_Strbuf) { // construct from stream buffer pointer } virtual ~basic_iostream() { // destroy the object } }; // EXTRACTORS template inline basic_istream<_Elem, _Traits>& operator>>( basic_istream<_Elem, _Traits>& _Istr, _Elem *_Str) { // extract NTBS ; typedef basic_istream<_Elem, _Traits> _Myis; typedef ctype<_Elem> _Ctype; ios_base::iostate _State = ios_base::goodbit; _Elem *_Str0 = _Str; const typename _Myis::sentry _Ok(_Istr); if (_Ok) { // state okay, extract characters const _Ctype& _Ctype_fac = use_facet< _Ctype >(_Istr.getloc()); try { streamsize _Count = 0 < _Istr.width() ? _Istr.width() : 2147483647; typename _Myis::int_type _Meta = _Istr.rdbuf()->sgetc(); _Elem _Ch; for (; 0 < --_Count; _Meta = _Istr.rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else if (_Ctype_fac.is(_Ctype::space, _Ch = _Traits::to_char_type(_Meta)) || _Ch == _Elem()) break; // whitespace or nul, quit else *_Str++ = _Traits::to_char_type(_Meta); // add it to string } catch (...) { (_Istr). setstate(ios_base::badbit, true); } } *_Str = _Elem(); // add terminating null character _Istr.width(0); _Istr.setstate(_Str == _Str0 ? _State | ios_base::failbit : _State); return (_Istr); } template inline basic_istream<_Elem, _Traits>& operator>>( basic_istream<_Elem, _Traits>& _Istr, _Elem& _Ch) { // extract a character typedef basic_istream<_Elem, _Traits> _Myis; typename _Myis::int_type _Meta; ios_base::iostate _State = ios_base::goodbit; const typename _Myis::sentry _Ok(_Istr); if (_Ok) { // state okay, extract characters try { _Meta = _Istr.rdbuf()->sbumpc(); if (_Traits::eq_int_type(_Traits::eof(), _Meta)) _State |= ios_base::eofbit | ios_base::failbit; // end of file else _Ch = _Traits::to_char_type(_Meta); // got a character } catch (...) { (_Istr). setstate(ios_base::badbit, true); } } _Istr.setstate(_State); return (_Istr); } template inline basic_istream& operator>>( basic_istream& _Istr, signed char *_Str) { // extract a signed char NTBS return (_Istr >> (char *)_Str); } template inline basic_istream& operator>>( basic_istream& _Istr, signed char& _Ch) { // extract a signed char return (_Istr >> (char&)_Ch); } template inline basic_istream& operator>>( basic_istream& _Istr, unsigned char *_Str) { // extract an unsigned char NTBS return (_Istr >> (char *)_Str); } template inline basic_istream& operator>>( basic_istream& _Istr, unsigned char& _Ch) { // extract an unsigned char return (_Istr >> (char&)_Ch); } // MANIPULATORS template inline basic_istream<_Elem, _Traits>& ws(basic_istream<_Elem, _Traits>& _Istr) { // consume whitespace typedef basic_istream<_Elem, _Traits> _Myis; typedef ctype<_Elem> _Ctype; if (!_Istr.eof()) { // not at eof, okay to construct sentry and skip ios_base::iostate _State = ios_base::goodbit; const typename _Myis::sentry _Ok(_Istr, true); if (_Ok) { // state okay, extract characters const _Ctype& _Ctype_fac = use_facet< _Ctype >(_Istr.getloc()); try { for (typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ; _Meta = _Istr.rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else if (!_Ctype_fac.is(_Ctype::space, _Traits::to_char_type(_Meta))) break; // not whitespace, quit } catch (...) { (_Istr). setstate(ios_base::badbit, true); } } _Istr.setstate(_State); } return (_Istr); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // basic_string TEMPLATE OPERATORS template inline basic_string<_Elem, _Traits, _Alloc> operator+( const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // return string + string return (basic_string<_Elem, _Traits, _Alloc>(_Left) += _Right); } template inline basic_string<_Elem, _Traits, _Alloc> operator+( const _Elem *_Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // return NTCS + string return (basic_string<_Elem, _Traits, _Alloc>(_Left) += _Right); } template inline basic_string<_Elem, _Traits, _Alloc> operator+( const _Elem _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // return character + string return (basic_string<_Elem, _Traits, _Alloc>(1, _Left) += _Right); } template inline basic_string<_Elem, _Traits, _Alloc> operator+( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem *_Right) { // return string + NTCS return (basic_string<_Elem, _Traits, _Alloc>(_Left) += _Right); } template inline basic_string<_Elem, _Traits, _Alloc> operator+( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem _Right) { // return string + character return (basic_string<_Elem, _Traits, _Alloc>(_Left) += _Right); } template inline bool operator==( const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test for string equality return (_Left.compare(_Right) == 0); } template inline bool operator==( const _Elem * _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test for NTCS vs. string equality return (_Right.compare(_Left) == 0); } template inline bool operator==( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem *_Right) { // test for string vs. NTCS equality return (_Left.compare(_Right) == 0); } template inline bool operator!=( const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test for string inequality return (!(_Left == _Right)); } template inline bool operator!=( const _Elem *_Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test for NTCS vs. string inequality return (!(_Left == _Right)); } template inline bool operator!=( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem *_Right) { // test for string vs. NTCS inequality return (!(_Left == _Right)); } template inline bool operator<( const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if string < string return (_Left.compare(_Right) < 0); } template inline bool operator<( const _Elem * _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if NTCS < string return (_Right.compare(_Left) > 0); } template inline bool operator<( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem *_Right) { // test if string < NTCS return (_Left.compare(_Right) < 0); } template inline bool operator>( const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if string > string return (_Right < _Left); } template inline bool operator>( const _Elem * _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if NTCS > string return (_Right < _Left); } template inline bool operator>( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem *_Right) { // test if string > NTCS return (_Right < _Left); } template inline bool operator<=( const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if string <= string return (!(_Right < _Left)); } template inline bool operator<=( const _Elem * _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if NTCS <= string return (!(_Right < _Left)); } template inline bool operator<=( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem *_Right) { // test if string <= NTCS return (!(_Right < _Left)); } template inline bool operator>=( const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if string >= string return (!(_Left < _Right)); } template inline bool operator>=( const _Elem * _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { // test if NTCS >= string return (!(_Left < _Right)); } template inline bool operator>=( const basic_string<_Elem, _Traits, _Alloc>& _Left, const _Elem *_Right) { // test if string >= NTCS return (!(_Left < _Right)); } // basic_string INSERTERS AND EXTRACTORS template inline basic_istream<_Elem, _Traits>& operator>>( basic_istream<_Elem, _Traits>& _Istr, basic_string<_Elem, _Traits, _Alloc>& _Str) { // extract a string typedef ctype<_Elem> _Ctype; typedef basic_istream<_Elem, _Traits> _Myis; typedef basic_string<_Elem, _Traits, _Alloc> _Mystr; typedef typename _Mystr::size_type _Mysizt; ios_base::iostate _State = ios_base::goodbit; bool _Changed = false; const typename _Myis::sentry _Ok(_Istr); if (_Ok) { // state okay, extract characters const _Ctype& _Ctype_fac = use_facet< _Ctype >(_Istr.getloc()); _Str.erase(); try { _Mysizt _Size = 0 < _Istr.width() && (_Mysizt)_Istr.width() < _Str.max_size() ? (_Mysizt)_Istr.width() : _Str.max_size(); typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); for (; 0 < _Size; --_Size, _Meta = _Istr.rdbuf()->snextc()) if(_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else if (_Ctype_fac.is(_Ctype::space, _Traits::to_char_type(_Meta))) break; // whitespace, quit else { // add character to string _Str.append(1, _Traits::to_char_type(_Meta)); _Changed = true; } } catch (...) { (_Istr). setstate(ios_base::badbit, true); } } _Istr.width(0); if (!_Changed) _State |= ios_base::failbit; _Istr.setstate(_State); return (_Istr); } template inline basic_istream<_Elem, _Traits>& getline( basic_istream<_Elem, _Traits>& _Istr, basic_string<_Elem, _Traits, _Alloc>& _Str, const _Elem _Delim) { // get characters into string, discard delimiter typedef basic_istream<_Elem, _Traits> _Myis; ios_base::iostate _State = ios_base::goodbit; bool _Changed = false; const typename _Myis::sentry _Ok(_Istr, true); if (_Ok) { // state okay, extract characters try { _Str.erase(); const typename _Traits::int_type _Metadelim = _Traits::to_int_type(_Delim); typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); for (; ; _Meta = _Istr.rdbuf()->snextc()) if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else if (_Traits::eq_int_type(_Meta, _Metadelim)) { // got a delimiter, discard it and quit _Changed = true; _Istr.rdbuf()->sbumpc(); break; } else if (_Str.max_size() <= _Str.size()) { // string too large, quit _State |= ios_base::failbit; break; } else { // got a character, add it to string _Str += _Traits::to_char_type(_Meta); _Changed = true; } } catch (...) { (_Istr). setstate(ios_base::badbit, true); } } if (!_Changed) _State |= ios_base::failbit; _Istr.setstate(_State); return (_Istr); } template inline basic_istream<_Elem, _Traits>& getline( basic_istream<_Elem, _Traits>& _Istr, basic_string<_Elem, _Traits, _Alloc>& _Str) { // get characters into string, discard newline return (getline(_Istr, _Str, _Istr.widen('\n'))); } template inline basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const basic_string<_Elem, _Traits, _Alloc>& _Str) { // insert a string typedef basic_ostream<_Elem, _Traits> _Myos; typedef basic_string<_Elem, _Traits, _Alloc> _Mystr; typedef typename _Mystr::size_type _Mysizt; ios_base::iostate _State = ios_base::goodbit; _Mysizt _Size = _Str.size(); _Mysizt _Pad = _Ostr.width() <= 0 || (_Mysizt)_Ostr.width() <= _Size ? 0 : (_Mysizt)_Ostr.width() - _Size; const typename _Myos::sentry _Ok(_Ostr); if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert characters try { if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } if (_State == ios_base::goodbit) for (_Mysizt _Count = 0; _Count < _Size; ++_Count) if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Str[_Count]))) { // insertion failed, quit _State |= ios_base::badbit; break; } if (_State == ios_base::goodbit) for (; 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } _Ostr.width(0); } catch (...) { (_Ostr). setstate(ios_base::badbit, true); } } _Ostr.setstate(_State); return (_Ostr); } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ /// @endcond ////////////////////////////////////////////////////////////////////////////// // Containers ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { //vector class template > class vector; //vector class template > class stable_vector; //vector class template > class deque; //list class template > class list; //slist class template > class slist; //set class template ,class A = std::allocator > class set; //multiset class template ,class A = std::allocator > class multiset; //map class template ,class A = std::allocator > > class map; //multimap class template ,class A = std::allocator > > class multimap; //flat_set class template ,class A = std::allocator > class flat_set; //flat_multiset class template ,class A = std::allocator > class flat_multiset; //flat_map class template ,class A = std::allocator > > class flat_map; //flat_multimap class template ,class A = std::allocator > > class flat_multimap; //basic_string class template ,class A = std::allocator > class basic_string; //! Type used to tag that the input range is //! guaranteed to be ordered struct ordered_range_t {}; //! Type used to tag that the input range is //! guaranteed to be ordered and unique struct ordered_unique_range_t : public ordered_range_t {}; //! Value used to tag that the input range is //! guaranteed to be ordered static const ordered_range_t ordered_range = ordered_range_t(); //! Value used to tag that the input range is //! guaranteed to be ordered and unique static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t(); /// @cond namespace detail_really_deep_namespace { //Otherwise, gcc issues a warning of previously defined //anonymous_instance and unique_instance struct dummy { dummy() { (void)ordered_range; (void)ordered_unique_range; } }; } //detail_really_deep_namespace { /// @endcond }} //namespace boost { namespace container { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright David Abrahams, Vicente Botet 2009. // (C) Copyright Ion Gaztanaga 2009-2010. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// //! \file /// @cond // algorithm standard header namespace std { // COMMON SORT PARAMETERS const int _ISORT_MAX = 32; // maximum size for insertion sort // TEMPLATE FUNCTION for_each template inline _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func) { // perform function for each element ; ; for (; _First != _Last; ++_First) _Func(*_First); return (_Func); } // TEMPLATE FUNCTION find template inline _InIt find(_InIt _First, _InIt _Last, const _Ty& _Val) { // find first matching _Val ; for (; _First != _Last; ++_First) if (*_First == _Val) break; return (_First); } inline const char *find(const char *_First, const char *_Last, int _Val) { // find first char that matches _Val ; _First = (const char *)::std:: memchr(_First, _Val, _Last - _First); return (_First == 0 ? _Last : _First); } inline const signed char *find(const signed char *_First, const signed char *_Last, int _Val) { // find first signed char that matches _Val ; _First = (const signed char *)::std:: memchr(_First, _Val, _Last - _First); return (_First == 0 ? _Last : _First); } inline const unsigned char *find(const unsigned char *_First, const unsigned char *_Last, int _Val) { // find first unsigned char that matches _Val ; _First = (const unsigned char *)::std:: memchr(_First, _Val, _Last - _First); return (_First == 0 ? _Last : _First); } // TEMPLATE FUNCTION find_if template inline _InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred) { // find first satisfying _Pred ; ; for (; _First != _Last; ++_First) if (_Pred(*_First)) break; return (_First); } // TEMPLATE FUNCTION adjacent_find template inline _FwdIt adjacent_find(_FwdIt _First, _FwdIt _Last) { // find first matching successor ; for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; ) if (*_Firstb == *_First) return (_Firstb); return (_Last); } // TEMPLATE FUNCTION adjacent_find WITH PRED template inline _FwdIt adjacent_find(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // find first satisfying _Pred with successor ; ; for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; ) if (_Pred(*_Firstb, *_First)) return (_Firstb); return (_Last); } // TEMPLATE FUNCTION count template inline typename iterator_traits<_InIt>::difference_type count(_InIt _First, _InIt _Last, const _Ty& _Val) { // count elements that match _Val ; typename iterator_traits<_InIt>::difference_type _Count = 0; for (; _First != _Last; ++_First) if (*_First == _Val) ++_Count; return (_Count); } // TEMPLATE FUNCTION count_if template inline typename iterator_traits<_InIt>::difference_type count_if(_InIt _First, _InIt _Last, _Pr _Pred) { // count elements satisfying _Pred ; ; typename iterator_traits<_InIt>::difference_type _Count = 0; for (; _First != _Last; ++_First) if (_Pred(*_First)) ++_Count; return (_Count); } // TEMPLATE FUNCTION count template inline void count(_InIt _First, _InIt _Last, const _Ty& _Val, _Diff &_Ans) { // count elements that match _Val ; _Diff _Count = 0; for (; _First != _Last; ++_First) if (*_First == _Val) ++_Count; _Ans = _Count; } // TEMPLATE FUNCTION count_if template inline void count_if(_InIt _First, _InIt _Last, _Pr _Pred, _Diff &_Ans) { // count elements satisfying _Pred ; ; _Diff _Count = 0; for (; _First != _Last; ++_First) if (_Pred(*_First)) ++_Count; _Ans = _Count; } // TEMPLATE FUNCTION search template inline _FwdIt1 _Search(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Diff1 *, _Diff2 *) { // find first [_First2, _Last2) match ; ; _Diff1 _Count1 = 0; _Distance(_First1, _Last1, _Count1); _Diff2 _Count2 = 0; _Distance(_First2, _Last2, _Count2); for (; _Count2 <= _Count1; ++_First1, --_Count1) { // room for match, try it _FwdIt1 _Mid1 = _First1; for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1, ++_Mid2) if (_Mid2 == _Last2) return (_First1); else if (!(*_Mid1 == *_Mid2)) break; } return (_Last1); } template inline _FwdIt1 search(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2) { // find first [_First2, _Last2) match return (_Search(_First1, _Last1, _First2, _Last2, _Dist_type(_First1), _Dist_type(_First2))); } // TEMPLATE FUNCTION search WITH PRED template inline _FwdIt1 _Search(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred, _Diff1 *, _Diff2 *) { // find first [_First2, _Last2) satisfying _Pred ; ; ; _Diff1 _Count1 = 0; _Distance(_First1, _Last1, _Count1); _Diff2 _Count2 = 0; _Distance(_First2, _Last2, _Count2); for (; _Count2 <= _Count1; ++_First1, --_Count1) { // room for match, try it _FwdIt1 _Mid1 = _First1; for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1, ++_Mid2) if (_Mid2 == _Last2) return (_First1); else if (!_Pred(*_Mid1, *_Mid2)) break; } return (_Last1); } template inline _FwdIt1 search(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred) { // find first [_First2, _Last2) satisfying _Pred return (_Search(_First1, _Last1, _First2, _Last2, _Pred, _Dist_type(_First1), _Dist_type(_First2))); } // TEMPLATE FUNCTION search_n template inline _FwdIt1 _Search_n(_FwdIt1 _First1, _FwdIt1 _Last1, _Diff2 _Count, const _Ty& _Val, _Diff1 *) { // find first _Count * _Val match ; _Diff1 _Count1 = 0; _Distance(_First1, _Last1, _Count1); for (; _Count <= _Count1; ++_First1, --_Count1) { // room for match, try it _FwdIt1 _Mid1 = _First1; for (_Diff2 _Count2 = _Count; ; ++_Mid1, --_Count2) if (_Count2 == 0) return (_First1); else if (!(*_Mid1 == _Val)) break; } return (_Last1); } template inline _FwdIt1 search_n(_FwdIt1 _First1, _FwdIt1 _Last1, _Diff2 _Count, const _Ty& _Val) { // find first _Count * _Val match return (_Search_n(_First1, _Last1, _Count, _Val, _Dist_type(_First1))); } // TEMPLATE FUNCTION search_n WITH PRED template inline _FwdIt1 _Search_n(_FwdIt1 _First1, _FwdIt1 _Last1, _Diff2 _Count, const _Ty& _Val, _Pr _Pred, _Diff1 *) { // find first _Count * _Val satisfying _Pred ; ; _Diff1 _Count1 = 0; _Distance(_First1, _Last1, _Count1); for (; _Count <= _Count1; ++_First1, --_Count1) { // room for match, try it _FwdIt1 _Mid1 = _First1; for (_Diff2 _Count2 = _Count; ; ++_Mid1, --_Count2) if (_Count2 == 0) return (_First1); else if (!_Pred(*_Mid1, _Val)) break; } return (_Last1); } template inline _FwdIt1 search_n(_FwdIt1 _First1, _FwdIt1 _Last1, _Diff2 _Count, const _Ty& _Val, _Pr _Pred) { // find first _Count * _Val satisfying _Pred return (_Search_n(_First1, _Last1, _Count, _Val, _Pred, _Dist_type(_First1))); } // TEMPLATE FUNCTION find_end template inline _FwdIt1 _Find_end(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Diff1 *, _Diff2 *) { // find last [_First2, _Last2) match ; ; _Diff1 _Count1 = 0; _Distance(_First1, _Last1, _Count1); _Diff2 _Count2 = 0; _Distance(_First2, _Last2, _Count2); _FwdIt1 _Ans = _Last1; if (0 < _Count2) for (; _Count2 <= _Count1; ++_First1, --_Count1) { // room for match, try it _FwdIt1 _Mid1 = _First1; for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1) if (!(*_Mid1 == *_Mid2)) break; else if (++_Mid2 == _Last2) { // potential answer, save it _Ans = _First1; break; } } return (_Ans); } template inline _FwdIt1 find_end(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2) { // find last [_First2, _Last2) match return (_Find_end(_First1, _Last1, _First2, _Last2, _Dist_type(_First1), _Dist_type(_First2))); } // TEMPLATE FUNCTION find_end WITH PRED template inline _FwdIt1 _Find_end(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred, _Diff1 *, _Diff2 *) { // find last [_First2, _Last2) satisfying _Pred ; ; ; _Diff1 _Count1 = 0; _Distance(_First1, _Last1, _Count1); _Diff2 _Count2 = 0; _Distance(_First2, _Last2, _Count2); _FwdIt1 _Ans = _Last1; if (0 < _Count2) for (; _Count2 <= _Count1; ++_First1, --_Count1) { // room for match, try it _FwdIt1 _Mid1 = _First1; for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1) if (!_Pred(*_Mid1, *_Mid2)) break; else if (++_Mid2 == _Last2) { // potential answer, save it _Ans = _First1; break; } } return (_Ans); } template inline _FwdIt1 find_end(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred) { // find last [_First2, _Last2) satisfying _Pred return (_Find_end(_First1, _Last1, _First2, _Last2, _Pred, _Dist_type(_First1), _Dist_type(_First2))); } // TEMPLATE FUNCTION find_first_of template inline _FwdIt1 find_first_of(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2) { // look for one of [_First2, _Last2) that matches element ; ; for (; _First1 != _Last1; ++_First1) for (_FwdIt2 _Mid2 = _First2; _Mid2 != _Last2; ++_Mid2) if (*_First1 == *_Mid2) return (_First1); return (_First1); } // TEMPLATE FUNCTION find_first_of WITH PRED template inline _FwdIt1 find_first_of(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred) { // look for one of [_First2, _Last2) satisfying _Pred with element ; ; ; for (; _First1 != _Last1; ++_First1) for (_FwdIt2 _Mid2 = _First2; _Mid2 != _Last2; ++_Mid2) if (_Pred(*_First1, *_Mid2)) return (_First1); return (_First1); } // TEMPLATE FUNCTION iter_swap template inline void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right) { // swap *_Left and *_Right ::std:: swap(*_Left, *_Right); } // TEMPLATE FUNCTION swap_ranges template inline _FwdIt2 swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2) { // swap [_First1, _Last1) with [_First2, ...) ; for (; _First1 != _Last1; ++_First1, ++_First2) ::std:: iter_swap(_First1, _First2); return (_First2); } // TEMPLATE FUNCTION transform WITH UNARY OP template inline _OutIt transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func) { // transform [_First, _Last) with _Func ; ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Func(*_First); return (_Dest); } // TEMPLATE FUNCTION transform WITH BINARY OP template inline _OutIt transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _OutIt _Dest, _Fn2 _Func) { // transform [_First1, _Last1) and [_First2, _Last2) with _Func ; ; ; for (; _First1 != _Last1; ++_First1, ++_First2, ++_Dest) *_Dest = _Func(*_First1, *_First2); return (_Dest); } // TEMPLATE FUNCTION replace template inline void replace(_FwdIt _First, _FwdIt _Last, const _Ty& _Oldval, const _Ty& _Newval) { // replace each matching _Oldval with _Newval ; for (; _First != _Last; ++_First) if (*_First == _Oldval) *_First = _Newval; } // TEMPLATE FUNCTION replace_if template inline void replace_if(_FwdIt _First, _FwdIt _Last, _Pr _Pred, const _Ty& _Val) { // replace each satisfying _Pred with _Val ; ; for (; _First != _Last; ++_First) if (_Pred(*_First)) *_First = _Val; } // TEMPLATE FUNCTION replace_copy template inline _OutIt replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest, const _Ty& _Oldval, const _Ty& _Newval) { // copy replacing each matching _Oldval with _Newval ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = *_First == _Oldval ? _Newval : *_First; return (_Dest); } // TEMPLATE FUNCTION replace_copy_if template inline _OutIt replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred, const _Ty& _Val) { // copy replacing each satisfying _Pred with _Val ; ; ; for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Pred(*_First) ? _Val : *_First; return (_Dest); } // TEMPLATE FUNCTION generate template inline void generate(_FwdIt _First, _FwdIt _Last, _Fn0 _Func) { // replace [_First, _Last) with _Func() ; ; for (; _First != _Last; ++_First) *_First = _Func(); } // TEMPLATE FUNCTION generate_n template inline void generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func) { // replace [_Dest, _Dest + _Count) with _Func() ; ; for (; 0 < _Count; --_Count, ++_Dest) *_Dest = _Func(); } // TEMPLATE FUNCTION remove_copy template inline _OutIt remove_copy(_InIt _First, _InIt _Last, _OutIt _Dest, const _Ty& _Val) { // copy omitting each matching _Val ; ; for (; _First != _Last; ++_First) if (!(*_First == _Val)) *_Dest++ = *_First; return (_Dest); } // TEMPLATE FUNCTION remove_copy_if template inline _OutIt remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred) { // copy omitting each element satisfying _Pred ; ; ; for (; _First != _Last; ++_First) if (!_Pred(*_First)) *_Dest++ = *_First; return (_Dest); } // TEMPLATE FUNCTION remove template inline _FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty& _Val) { // remove each matching _Val _First = find(_First, _Last, _Val); if (_First == _Last) return (_First); // empty sequence, all done else { // nonempty sequence, worth doing _FwdIt _First1 = _First; return (::std:: remove_copy(++_First1, _Last, _First, _Val)); } } // TEMPLATE FUNCTION remove_if template inline _FwdIt remove_if(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // remove each satisfying _Pred _First = ::std:: find_if(_First, _Last, _Pred); if (_First == _Last) return (_First); // empty sequence, all done else { // nonempty sequence, worth doing _FwdIt _First1 = _First; return (::std:: remove_copy_if(++_First1, _Last, _First, _Pred)); } } // TEMPLATE FUNCTION unique template inline _FwdIt unique(_FwdIt _First, _FwdIt _Last) { // remove each matching previous ; for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; ) if (*_Firstb == *_First) { // copy down for (; ++_First != _Last; ) if (!(*_Firstb == *_First)) *++_Firstb = *_First; return (++_Firstb); } return (_Last); } // TEMPLATE FUNCTION unique WITH PRED template inline _FwdIt unique(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // remove each satisfying _Pred with previous ; ; for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; ) if (_Pred(*_Firstb, *_First)) { // copy down for (; ++_First != _Last; ) if (!_Pred(*_Firstb, *_First)) *++_Firstb = *_First; return (++_Firstb); } return (_Last); } // TEMPLATE FUNCTION unique_copy template inline _OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Ty *) { // copy compressing pairs that match, input iterators ; _Ty _Val = *_First; for (*_Dest++ = _Val; ++_First != _Last; ) if (!(_Val == *_First)) _Val = *_First, *_Dest++ = _Val; return (_Dest); } template inline _OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, input_iterator_tag) { // copy compressing pairs that match, input iterators return (_Unique_copy(_First, _Last, _Dest, _Val_type(_First))); } template inline _OutIt _Unique_copy(_FwdIt _First, _FwdIt _Last, _OutIt _Dest, forward_iterator_tag) { // copy compressing pairs that match, forward iterators ; ; _FwdIt _Firstb = _First; for (*_Dest++ = *_Firstb; ++_First != _Last; ) if (!(*_Firstb == *_First)) _Firstb = _First, *_Dest++ = *_Firstb; return (_Dest); } template inline _OutIt _Unique_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest, bidirectional_iterator_tag) { // copy compressing pairs that match, bidirectional iterators return (_Unique_copy(_First, _Last, _Dest, forward_iterator_tag())); } template inline _OutIt _Unique_copy(_RanIt _First, _RanIt _Last, _OutIt _Dest, random_access_iterator_tag) { // copy compressing pairs that match, random-access iterators return (_Unique_copy(_First, _Last, _Dest, forward_iterator_tag())); } template inline _OutIt unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest) { // copy compressing pairs that match return (_First == _Last ? _Dest : _Unique_copy(_First, _Last, _Dest, _Iter_cat(_First))); } // TEMPLATE FUNCTION unique_copy WITH PRED template inline _OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred, _Ty *) { // copy compressing pairs satisfying _Pred, input iterators ; ; _Ty _Val = *_First; for (*_Dest++ = _Val; ++_First != _Last; ) if (!_Pred(_Val, *_First)) _Val = *_First, *_Dest++ = _Val; return (_Dest); } template inline _OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred, input_iterator_tag) { // copy compressing pairs satisfying _Pred, input iterators return (_Unique_copy(_First, _Last, _Dest, _Pred, _Val_type(_First))); } template inline _OutIt _Unique_copy(_FwdIt _First, _FwdIt _Last, _OutIt _Dest, _Pr _Pred, forward_iterator_tag) { // copy compressing pairs satisfying _Pred, forward iterators ; ; ; _FwdIt _Firstb = _First; for (*_Dest++ = *_Firstb; ++_First != _Last; ) if (!_Pred(*_Firstb, *_First)) _Firstb = _First, *_Dest++ = *_Firstb; return (_Dest); } template inline _OutIt _Unique_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest, _Pr _Pred, bidirectional_iterator_tag) { // copy compressing pairs satisfying _Pred, bidirectional iterators return (_Unique_copy(_First, _Last, _Dest, _Pred, forward_iterator_tag())); } template inline _OutIt _Unique_copy(_RanIt _First, _RanIt _Last, _OutIt _Dest, _Pr _Pred, random_access_iterator_tag) { // copy compressing pairs satisfying _Pred, random-access iterators return (_Unique_copy(_First, _Last, _Dest, _Pred, forward_iterator_tag())); } template inline _OutIt unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred) { // copy compressing pairs satisfying _Pred return (_First == _Last ? _Dest : _Unique_copy(_First, _Last, _Dest, _Pred, _Iter_cat(_First))); } // TEMPLATE FUNCTION reverse template inline void _Reverse(_BidIt _First, _BidIt _Last, bidirectional_iterator_tag) { // reverse elements in [_First, _Last), bidirectional iterators for (; _First != _Last && _First != --_Last; ++_First) ::std:: iter_swap(_First, _Last); } template inline void _Reverse(_RanIt _First, _RanIt _Last, random_access_iterator_tag) { // reverse elements in [_First, _Last), random-access iterators ; for (; _First < _Last; ++_First) ::std:: iter_swap(_First, --_Last); } template inline void reverse(_BidIt _First, _BidIt _Last) { // reverse elements in [_First, _Last) _Reverse(_First, _Last, _Iter_cat(_First)); } // TEMPLATE FUNCTION reverse_copy template inline _OutIt reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest) { // copy reversing elements in [_First, _Last) ; ; for (; _First != _Last; ++_Dest) *_Dest = *--_Last; return (_Dest); } // TEMPLATE FUNCTION rotate template inline void _Rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, forward_iterator_tag) { // rotate [_First, _Last), forward iterators for (_FwdIt _Next = _Mid; ; ) { // swap [_First, ...) into place ::std:: iter_swap(_First, _Next); if (++_First == _Mid) if (++_Next == _Last) break; // done, quit else _Mid = _Next; // mark end of next interval else if (++_Next == _Last) _Next = _Mid; // wrap to last end } } template inline void _Rotate(_BidIt _First, _BidIt _Mid, _BidIt _Last, bidirectional_iterator_tag) { // rotate [_First, _Last), bidirectional iterators ::std:: reverse(_First, _Mid); ::std:: reverse(_Mid, _Last); ::std:: reverse(_First, _Last); } template inline void _Rotate(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Diff *, _Ty *) { // rotate [_First, _Last), random-access iterators ; ; _Diff _Shift = _Mid - _First; _Diff _Count = _Last - _First; for (_Diff _Factor = _Shift; _Factor != 0; ) { // find subcycle count as GCD of shift count and length _Diff _Tmp = _Count % _Factor; _Count = _Factor, _Factor = _Tmp; } if (_Count < _Last - _First) for (; 0 < _Count; --_Count) { // rotate each subcycle _RanIt _Hole = _First + _Count; _RanIt _Next = _Hole; _Ty _Holeval = *_Hole; _RanIt _Next1 = _Next + _Shift == _Last ? _First : _Next + _Shift; while (_Next1 != _Hole) { // percolate elements back around subcycle *_Next = *_Next1; _Next = _Next1; _Next1 = _Shift < _Last - _Next1 ? _Next1 + _Shift : _First + (_Shift - (_Last - _Next1)); } *_Next = _Holeval; } } template inline void _Rotate(_RanIt _First, _RanIt _Mid, _RanIt _Last, random_access_iterator_tag) { // rotate [_First, _Last), random-access iterators _Rotate(_First, _Mid, _Last, _Dist_type(_First), _Val_type(_First)); } template inline void rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last) { // rotate [_First, _Last) if (_First != _Mid && _Mid != _Last) _Rotate(_First, _Mid, _Last, _Iter_cat(_First)); } // TEMPLATE FUNCTION rotate_copy template inline _OutIt rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest) { // copy rotating [_First, _Last) _Dest = ::std:: copy(_Mid, _Last, _Dest); return (::std:: copy(_First, _Mid, _Dest)); } // TEMPLATE FUNCTION random_shuffle template inline void _Random_shuffle(_RanIt _First, _RanIt _Last, _Diff *) { // shuffle [_First, _Last) ; const int _RANDOM_BITS = 15; // minimum random bits from rand() const int _RANDOM_MAX = (1U << _RANDOM_BITS) - 1; _RanIt _Next = _First; for (unsigned long _Index = 2; ++_Next != _Last; ++_Index) { // assume unsigned long big enough for _Diff count unsigned long _Rm = _RANDOM_MAX; unsigned long _Rn = ::std:: rand() & _RANDOM_MAX; for (; _Rm < _Index && _Rm != ~0UL; _Rm = _Rm << _RANDOM_BITS | _RANDOM_MAX) _Rn = _Rn << _RANDOM_BITS | _RANDOM_MAX; // build random value ::std:: iter_swap(_Next, _First + _Diff(_Rn % _Index)); // swap a pair } } template inline void random_shuffle(_RanIt _First, _RanIt _Last) { // shuffle [_First, _Last) if (_First != _Last) _Random_shuffle(_First, _Last, _Dist_type(_First)); } // TEMPLATE FUNCTION random_shuffle WITH RANDOM FN template inline void _Random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func, _Diff *) { // shuffle nonempty [_First, _Last) using random function _Func ; ; _RanIt _Next = _First; for (_Diff _Index = 2; ++_Next != _Last; ++_Index) ::std:: iter_swap(_Next, _First + _Diff(_Func(_Index))); } template inline void random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func) { // shuffle [_First, _Last) using random function _Func if (_First != _Last) _Random_shuffle(_First, _Last, _Func, _Dist_type(_First)); } // TEMPLATE FUNCTION partition template inline _BidIt partition(_BidIt _First, _BidIt _Last, _Pr _Pred) { // move elements satisfying _Pred to beginning of sequence ; ; for (; ; ++_First) { // find any out-of-order pair for (; _First != _Last && _Pred(*_First); ++_First) ; // skip in-place elements at beginning if (_First == _Last) break; // done for (; _First != --_Last && !_Pred(*_Last); ) ; // skip in-place elements at end if (_First == _Last) break; // done ::std:: iter_swap(_First, _Last); // swap out-of-place pair and loop } return (_First); } // TEMPLATE FUNCTION stable_partition template inline _BidIt _Stable_partition(_BidIt _First, _BidIt _Last, _Pr _Pred, _Diff _Count, _Temp_iterator<_Ty>& _Tempbuf) { // partition preserving order of equivalents, using _Pred if (_Count == 1) return (_Pred(*_First) ? _Last : _First); else if (_Count <= _Tempbuf._Maxlen()) { // temp buffer big enough, copy right partition out and back _BidIt _Next = _First; for (_Tempbuf._Init(); _First != _Last; ++_First) if (_Pred(*_First)) *_Next++ = *_First; else *_Tempbuf++ = *_First; ::std:: copy(_Tempbuf._First(), _Tempbuf._Last(), _Next); // copy back return (_Next); } else { // temp buffer not big enough, divide and conquer _BidIt _Mid = _First; ::std:: advance(_Mid, _Count / 2); _BidIt _Left = _Stable_partition(_First, _Mid, _Pred, _Count / 2, _Tempbuf); // form L1R1 in left half _BidIt _Right = _Stable_partition(_Mid, _Last, _Pred, _Count - _Count / 2, _Tempbuf); // form L2R2 in right half _Diff _Count1 = 0; _Distance(_Left, _Mid, _Count1); _Diff _Count2 = 0; _Distance(_Mid, _Right, _Count2); return (_Buffered_rotate(_Left, _Mid, _Right, _Count1, _Count2, _Tempbuf)); // rotate L1R1L2R2 to L1L2R1R2 } } template inline _BidIt _Stable_partition(_BidIt _First, _BidIt _Last, _Pr _Pred, _Diff *, _Ty *) { // partition preserving order of equivalents, using _Pred _Diff _Count = 0; _Distance(_First, _Last, _Count); _Temp_iterator<_Ty> _Tempbuf(_Count); return (_Stable_partition(_First, _Last, _Pred, _Count, _Tempbuf)); } template inline _BidIt stable_partition(_BidIt _First, _BidIt _Last, _Pr _Pred) { // partition preserving order of equivalents, using _Pred return (_First == _Last ? _First : _Stable_partition(_First, _Last, _Pred, _Dist_type(_First), _Val_type(_First))); } // TEMPLATE FUNCTION push_heap template inline void _Push_heap(_RanIt _First, _Diff _Hole, _Diff _Top, _Ty _Val) { // percolate _Hole to _Top or where _Val belongs, using operator< for (_Diff _Idx = (_Hole - 1) / 2; _Top < _Hole && ((*(_First + _Idx)) < (_Val)); _Idx = (_Hole - 1) / 2) { // move _Hole up to parent *(_First + _Hole) = *(_First + _Idx); _Hole = _Idx; } *(_First + _Hole) = _Val; // drop _Val into final hole } template inline void _Push_heap_0(_RanIt _First, _RanIt _Last, _Diff *, _Ty *) { // push *_Last onto heap at [_First, _Last), using operator< ; _Diff _Count = _Last - _First; if (0 < _Count) _Push_heap(_First, _Count, _Diff(0), _Ty(*_Last)); } template inline void push_heap(_RanIt _First, _RanIt _Last) { // push *(_Last - 1) onto heap at [_First, _Last - 1), using operator< if (_First != _Last) _Push_heap_0(_First, --_Last, _Dist_type(_First), _Val_type(_First)); } // TEMPLATE FUNCTION push_heap WITH PRED template inline void _Push_heap(_RanIt _First, _Diff _Hole, _Diff _Top, _Ty _Val, _Pr _Pred) { // percolate _Hole to _Top or where _Val belongs, using operator< for (_Diff _Idx = (_Hole - 1) / 2; _Top < _Hole && _Pred(*(_First + _Idx), _Val); _Idx = (_Hole - 1) / 2) { // move _Hole up to parent *(_First + _Hole) = *(_First + _Idx); _Hole = _Idx; } *(_First + _Hole) = _Val; // drop _Val into final hole } template inline void _Push_heap_0(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *, _Ty *) { // push *_Last onto heap at [_First, _Last), using _Pred ; _Diff _Count = _Last - _First; if (0 < _Count) _Push_heap(_First, _Count, _Diff(0), _Ty(*_Last), _Pred); } template inline void push_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // push *(_Last - 1) onto heap at [_First, _Last - 1), using _Pred if (_First != _Last) _Push_heap_0(_First, --_Last, _Pred, _Dist_type(_First), _Val_type(_First)); } // TEMPLATE FUNCTION pop_heap template inline void _Adjust_heap(_RanIt _First, _Diff _Hole, _Diff _Bottom, _Ty _Val) { // percolate _Hole to _Bottom, then push _Val, using operator< _Diff _Top = _Hole; _Diff _Idx = 2 * _Hole + 2; for (; _Idx < _Bottom; _Idx = 2 * _Idx + 2) { // move _Hole down to larger child if (((*(_First + _Idx)) < (*(_First + (_Idx - 1))))) --_Idx; *(_First + _Hole) = *(_First + _Idx), _Hole = _Idx; } if (_Idx == _Bottom) { // only child at bottom, move _Hole down to it *(_First + _Hole) = *(_First + (_Bottom - 1)); _Hole = _Bottom - 1; } _Push_heap(_First, _Hole, _Top, _Val); } template inline void _Pop_heap(_RanIt _First, _RanIt _Last, _RanIt _Dest, _Ty _Val, _Diff *) { // pop *_First to *_Dest and reheap, using operator< *_Dest = *_First; _Adjust_heap(_First, _Diff(0), _Diff(_Last - _First), _Val); } template inline void _Pop_heap_0(_RanIt _First, _RanIt _Last, _Ty *) { // pop *_First to *(_Last - 1) and reheap, using operator< _Pop_heap(_First, _Last - 1, _Last - 1, _Ty(*(_Last - 1)), _Dist_type(_First)); } template inline void pop_heap(_RanIt _First, _RanIt _Last) { // pop *_First to *(_Last - 1) and reheap, using operator< ; if (1 < _Last - _First) _Pop_heap_0(_First, _Last, _Val_type(_First)); } // TEMPLATE FUNCTION pop_heap WITH PRED template inline void _Adjust_heap(_RanIt _First, _Diff _Hole, _Diff _Bottom, _Ty _Val, _Pr _Pred) { // percolate _Hole to _Bottom, then push _Val, using _Pred _Diff _Top = _Hole; _Diff _Idx = 2 * _Hole + 2; for (; _Idx < _Bottom; _Idx = 2 * _Idx + 2) { // move _Hole down to larger child if (_Pred(*(_First + _Idx), *(_First + (_Idx - 1)))) --_Idx; *(_First + _Hole) = *(_First + _Idx), _Hole = _Idx; } if (_Idx == _Bottom) { // only child at bottom, move _Hole down to it *(_First + _Hole) = *(_First + (_Bottom - 1)); _Hole = _Bottom - 1; } _Push_heap(_First, _Hole, _Top, _Val, _Pred); } template inline void _Pop_heap(_RanIt _First, _RanIt _Last, _RanIt _Dest, _Ty _Val, _Pr _Pred, _Diff *) { // pop *_First to *_Dest and reheap, using _Pred *_Dest = *_First; _Adjust_heap(_First, _Diff(0), _Diff(_Last - _First), _Val, _Pred); } template inline void _Pop_heap_0(_RanIt _First, _RanIt _Last, _Pr _Pred, _Ty *) { // pop *_First to *(_Last - 1) and reheap, using _Pred _Pop_heap(_First, _Last - 1, _Last - 1, _Ty(*(_Last - 1)), _Pred, _Dist_type(_First)); } template inline void pop_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // pop *_First to *(_Last - 1) and reheap, using _Pred ; if (1 < _Last - _First) _Pop_heap_0(_First, _Last, _Pred, _Val_type(_First)); } // TEMPLATE FUNCTION make_heap template inline void _Make_heap(_RanIt _First, _RanIt _Last, _Diff *, _Ty *) { // make nontrivial [_First, _Last) into a heap, using operator< _Diff _Bottom = _Last - _First; for (_Diff _Hole = _Bottom / 2; 0 < _Hole; ) { // reheap top half, bottom to top --_Hole; _Adjust_heap(_First, _Hole, _Bottom, _Ty(*(_First + _Hole))); } } template inline void make_heap(_RanIt _First, _RanIt _Last) { // make [_First, _Last) into a heap, using operator< if (1 < _Last - _First) _Make_heap(_First, _Last, _Dist_type(_First), _Val_type(_First)); } // TEMPLATE FUNCTION make_heap WITH PRED template inline void _Make_heap(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *, _Ty *) { // make nontrivial [_First, _Last) into a heap, using _Pred _Diff _Bottom = _Last - _First; for (_Diff _Hole = _Bottom / 2; 0 < _Hole; ) { // reheap top half, bottom to top --_Hole; _Adjust_heap(_First, _Hole, _Bottom, _Ty(*(_First + _Hole)), _Pred); } } template inline void make_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // make [_First, _Last) into a heap, using _Pred if (1 < _Last - _First) _Make_heap(_First, _Last, _Pred, _Dist_type(_First), _Val_type(_First)); } // TEMPLATE FUNCTION sort_heap template inline void sort_heap(_RanIt _First, _RanIt _Last) { // order heap by repeatedly popping, using operator< ; for (; 1 < _Last - _First; --_Last) ::std:: pop_heap(_First, _Last); } // TEMPLATE FUNCTION sort_heap WITH PRED template inline void sort_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // order heap by repeatedly popping, using _Pred ; for (; 1 < _Last - _First; --_Last) ::std:: pop_heap(_First, _Last, _Pred); } // TEMPLATE FUNCTION lower_bound template inline _FwdIt _Lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *) { // find first element not before _Val, using operator< ; _Diff _Count = 0; _Distance(_First, _Last, _Count); for (; 0 < _Count; ) { // divide and conquer, find half that contains answer _Diff _Count2 = _Count / 2; _FwdIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (((*_Mid) < (_Val))) _First = ++_Mid, _Count -= _Count2 + 1; else _Count = _Count2; } return (_First); } template inline _FwdIt lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val) { // find first element not before _Val, using operator< return (_Lower_bound(_First, _Last, _Val, _Dist_type(_First))); } // TEMPLATE FUNCTION lower_bound WITH PRED template inline _FwdIt _Lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred, _Diff *) { // find first element not before _Val, using _Pred ; _Diff _Count = 0; _Distance(_First, _Last, _Count); for (; 0 < _Count; ) { // divide and conquer, find half that contains answer _Diff _Count2 = _Count / 2; _FwdIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (_Pred(*_Mid, _Val)) _First = ++_Mid, _Count -= _Count2 + 1; else _Count = _Count2; } return (_First); } template inline _FwdIt lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred) { // find first element not before _Val, using _Pred return (_Lower_bound(_First, _Last, _Val, _Pred, _Dist_type(_First))); } // TEMPLATE FUNCTION upper_bound template inline _FwdIt _Upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *) { // find first element that _Val is before, using operator< ; _Diff _Count = 0; _Distance(_First, _Last, _Count); for (; 0 < _Count; ) { // divide and conquer, find half that contains answer _Diff _Count2 = _Count / 2; _FwdIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (!((_Val) < (*_Mid))) _First = ++_Mid, _Count -= _Count2 + 1; else _Count = _Count2; } return (_First); } template inline _FwdIt upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val) { // find first element that _Val is before, using operator< return (_Upper_bound(_First, _Last, _Val, _Dist_type(_First))); } // TEMPLATE FUNCTION upper_bound WITH PRED template inline _FwdIt _Upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred, _Diff *) { // find first element that _Val is before, using _Pred ; _Diff _Count = 0; _Distance(_First, _Last, _Count); for (; 0 < _Count; ) { // divide and conquer, find half that contains answer _Diff _Count2 = _Count / 2; _FwdIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (!_Pred(_Val, *_Mid)) _First = ++_Mid, _Count -= _Count2 + 1; else _Count = _Count2; } return (_First); } template inline _FwdIt upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred) { // find first element that _Val is before, using _Pred return (_Upper_bound(_First, _Last, _Val, _Pred, _Dist_type(_First))); } // TEMPLATE FUNCTION equal_range template inline pair<_FwdIt, _FwdIt> _Equal_range(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *) { // find range equivalent to _Val, using operator< ; _Diff _Count = 0; _Distance(_First, _Last, _Count); for (; 0 < _Count; ) { // divide and conquer, check midpoint _Diff _Count2 = _Count / 2; _FwdIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (((*_Mid) < (_Val))) { // range begins above _Mid, loop _First = ++_Mid; _Count -= _Count2 + 1; } else if (_Val < *_Mid) _Count = _Count2; // range in first half, loop else { // range straddles mid, find each end and return _FwdIt _First2 = lower_bound(_First, _Mid, _Val); ::std:: advance(_First, _Count); _FwdIt _Last2 = upper_bound(++_Mid, _First, _Val); return (pair<_FwdIt, _FwdIt>(_First2, _Last2)); } } return (pair<_FwdIt, _FwdIt>(_First, _First)); // empty range } template inline pair<_FwdIt, _FwdIt> equal_range(_FwdIt _First, _FwdIt _Last, const _Ty& _Val) { // find range equivalent to _Val, using operator< return (_Equal_range(_First, _Last, _Val, _Dist_type(_First))); } // TEMPLATE FUNCTION equal_range WITH PRED template inline pair<_FwdIt, _FwdIt> _Equal_range(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred, _Diff *) { // find range equivalent to _Val, using _Pred ; _Diff _Count = 0; _Distance(_First, _Last, _Count); for (; 0 < _Count; ) { // divide and conquer, check midpoint _Diff _Count2 = _Count / 2; _FwdIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (_Pred(*_Mid, _Val)) { // range begins above _Mid, loop _First = ++_Mid; _Count -= _Count2 + 1; } else if (_Pred(_Val, *_Mid)) _Count = _Count2; // range in first half, loop else { // range straddles _Mid, find each end and return _FwdIt _First2 = lower_bound(_First, _Mid, _Val, _Pred); ::std:: advance(_First, _Count); _FwdIt _Last2 = upper_bound(++_Mid, _First, _Val, _Pred); return (pair<_FwdIt, _FwdIt>(_First2, _Last2)); } } return (pair<_FwdIt, _FwdIt>(_First, _First)); // empty range } template inline pair<_FwdIt, _FwdIt> equal_range(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred) { // find range equivalent to _Val, using _Pred return (_Equal_range(_First, _Last, _Val, _Pred, _Dist_type(_First))); } // TEMPLATE FUNCTION binary_search template inline bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val) { // test if _Val equivalent to some element, using operator< _First = ::std:: lower_bound(_First, _Last, _Val); return (_First != _Last && !(_Val < *_First)); } // TEMPLATE FUNCTION binary_search WITH PRED template inline bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred) { // test if _Val equivalent to some element, using _Pred _First = ::std:: lower_bound(_First, _Last, _Val, _Pred); return (_First != _Last && !_Pred(_Val, *_First)); } // TEMPLATE FUNCTION merge template inline _OutIt merge(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest) { // copy merging ranges, both using operator< ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ++_Dest) if (((*_First2) < (*_First1))) *_Dest = *_First2, ++_First2; else *_Dest = *_First1, ++_First1; _Dest = ::std:: copy(_First1, _Last1, _Dest); // copy any tail return (::std:: copy(_First2, _Last2, _Dest)); } // TEMPLATE FUNCTION merge WITH PRED template inline _OutIt merge(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // copy merging ranges, both using _Pred ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ++_Dest) if (_Pred(*_First2, *_First1)) *_Dest = *_First2, ++_First2; else *_Dest = *_First1, ++_First1; _Dest = ::std:: copy(_First1, _Last1, _Dest); // copy any tail return (::std:: copy(_First2, _Last2, _Dest)); } // TEMPLATE FUNCTION inplace_merge template inline _BidIt _Buffered_rotate(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Diff _Count1, _Diff _Count2, _Temp_iterator<_Ty>& _Tempbuf) { // rotate [_First, _Last) using temp buffer if (_Count1 <= _Count2 && _Count1 <= _Tempbuf._Maxlen()) { // buffer left partition, then copy parts ::std:: copy(_First, _Mid, _Tempbuf._Init()); ::std:: copy(_Mid, _Last, _First); return (::std:: copy_backward(_Tempbuf._First(), _Tempbuf._Last(), _Last)); } else if (_Count2 <= _Tempbuf._Maxlen()) { // buffer right partition, then copy parts ::std:: copy(_Mid, _Last, _Tempbuf._Init()); ::std:: copy_backward(_First, _Mid, _Last); return (::std:: copy(_Tempbuf._First(), _Tempbuf._Last(), _First)); } else { // buffer too small, rotate in place ::std:: rotate(_First, _Mid, _Last); ::std:: advance(_First, _Count2); return (_First); } } template inline _BidIt3 _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1, _BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest) { // merge backwards to _Dest, using operator< for (; ; ) if (_First1 == _Last1) return (::std:: copy_backward(_First2, _Last2, _Dest)); else if (_First2 == _Last2) return (::std:: copy_backward(_First1, _Last1, _Dest)); else if (((* --_Last2) < (* --_Last1))) *--_Dest = *_Last1, ++_Last2; else *--_Dest = *_Last2, ++_Last1; } template inline void _Buffered_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Diff _Count1, _Diff _Count2, _Temp_iterator<_Ty>& _Tempbuf) { // merge [_First, _Mid) with [_Mid, _Last), using operator< if (_Count1 + _Count2 == 2) { // order two one-element partitions if (((*_Mid) < (*_First))) ::std:: iter_swap(_First, _Mid); } else if (_Count1 <= _Count2 && _Count1 <= _Tempbuf._Maxlen()) { // buffer left partition, then merge ::std:: copy(_First, _Mid, _Tempbuf._Init()); ::std:: merge(_Tempbuf._First(), _Tempbuf._Last(), _Mid, _Last, _First); } else if (_Count2 <= _Tempbuf._Maxlen()) { // buffer right partition, then merge ::std:: copy(_Mid, _Last, _Tempbuf._Init()); _Merge_backward(_First, _Mid, _Tempbuf._First(), _Tempbuf._Last(), _Last); } else { // buffer too small, divide and conquer _BidIt _Firstn, _Lastn; _Diff _Count1n, _Count2n; if (_Count2 < _Count1) { // left larger, cut it in half and partition right to match _Count1n = _Count1 / 2, _Count2n = 0; _Firstn = _First; ::std:: advance(_Firstn, _Count1n); _Lastn = ::std:: lower_bound(_Mid, _Last, *_Firstn); _Distance(_Mid, _Lastn, _Count2n); } else { // right larger, cut it in half and partition left to match _Count1n = 0, _Count2n = _Count2 / 2; _Lastn = _Mid; ::std:: advance(_Lastn, _Count2n); _Firstn = ::std:: upper_bound(_First, _Mid, *_Lastn); _Distance(_First, _Firstn, _Count1n); } _BidIt _Midn = _Buffered_rotate(_Firstn, _Mid, _Lastn, _Count1 - _Count1n, _Count2n, _Tempbuf); // rearrange middle _Buffered_merge(_First, _Firstn, _Midn, _Count1n, _Count2n, _Tempbuf); // merge each new part _Buffered_merge(_Midn, _Lastn, _Last, _Count1 - _Count1n, _Count2 - _Count2n, _Tempbuf); } } template inline void _Inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Diff *, _Ty *) { // merge [_First, _Mid) with [_Mid, _Last), using operator< ; ; _Diff _Count1 = 0; _Distance(_First, _Mid, _Count1); _Diff _Count2 = 0; _Distance(_Mid, _Last, _Count2); _Temp_iterator<_Ty> _Tempbuf(_Count1 < _Count2 ? _Count1 : _Count2); _Buffered_merge(_First, _Mid, _Last, _Count1, _Count2, _Tempbuf); } template inline void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last) { // merge [_First, _Mid) with [_Mid, _Last), using operator< if (_First != _Mid && _Mid != _Last) _Inplace_merge(_First, _Mid, _Last, _Dist_type(_First), _Val_type(_First)); } // TEMPLATE FUNCTION inplace_merge WITH PRED template inline _BidIt3 _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1, _BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred) { // merge backwards to _Dest, using _Pred for (; ; ) if (_First1 == _Last1) return (::std:: copy_backward(_First2, _Last2, _Dest)); else if (_First2 == _Last2) return (::std:: copy_backward(_First1, _Last1, _Dest)); else if (_Pred(* --_Last2, * --_Last1)) *--_Dest = *_Last1, ++_Last2; else *--_Dest = *_Last2, ++_Last1; } template inline void _Buffered_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Diff _Count1, _Diff _Count2, _Temp_iterator<_Ty>& _Tempbuf, _Pr _Pred) { // merge [_First, _Mid) with [_Mid, _Last), using _Pred if (_Count1 + _Count2 == 2) { // order two one-element partitions if (_Pred(*_Mid, *_First)) ::std:: iter_swap(_First, _Mid); } else if (_Count1 <= _Count2 && _Count1 <= _Tempbuf._Maxlen()) { // buffer left partition, then merge ::std:: copy(_First, _Mid, _Tempbuf._Init()); ::std:: merge(_Tempbuf._First(), _Tempbuf._Last(), _Mid, _Last, _First, _Pred); } else if (_Count2 <= _Tempbuf._Maxlen()) { // buffer right partition, then merge ::std:: copy(_Mid, _Last, _Tempbuf._Init()); _Merge_backward(_First, _Mid, _Tempbuf._First(), _Tempbuf._Last(), _Last, _Pred); } else { // buffer too small, divide and conquer _BidIt _Firstn, _Lastn; _Diff _Count1n, _Count2n; if (_Count2 < _Count1) { // left larger, cut it in half and partition right to match _Count1n = _Count1 / 2, _Count2n = 0; _Firstn = _First; ::std:: advance(_Firstn, _Count1n); _Lastn = lower_bound(_Mid, _Last, *_Firstn, _Pred); _Distance(_Mid, _Lastn, _Count2n); } else { // right larger, cut it in half and partition left to match _Count1n = 0, _Count2n = _Count2 / 2; _Lastn = _Mid; ::std:: advance(_Lastn, _Count2n); _Firstn = upper_bound(_First, _Mid, *_Lastn, _Pred); _Distance(_First, _Firstn, _Count1n); } _BidIt _Midn = _Buffered_rotate(_Firstn, _Mid, _Lastn, _Count1 - _Count1n, _Count2n, _Tempbuf); // rearrange middle _Buffered_merge(_First, _Firstn, _Midn, _Count1n, _Count2n, _Tempbuf, _Pred); // merge each new part _Buffered_merge(_Midn, _Lastn, _Last, _Count1 - _Count1n, _Count2 - _Count2n, _Tempbuf, _Pred); } } template inline void _Inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred, _Diff *, _Ty *) { // merge [_First, _Mid) with [_Mid, _Last), using _Pred ; ; _Diff _Count1 = 0; _Distance(_First, _Mid, _Count1); _Diff _Count2 = 0; _Distance(_Mid, _Last, _Count2); _Temp_iterator<_Ty> _Tempbuf(_Count1 < _Count2 ? _Count1 : _Count2); _Buffered_merge(_First, _Mid, _Last, _Count1, _Count2, _Tempbuf, _Pred); } template inline void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred) { // merge [_First, _Mid) with [_Mid, _Last), using _Pred if (_First != _Mid && _Mid != _Last) _Inplace_merge(_First, _Mid, _Last, _Pred, _Dist_type(_First), _Val_type(_First)); } // TEMPLATE FUNCTION sort template inline void _Insertion_sort(_BidIt _First, _BidIt _Last) { // insertion sort [_First, _Last), using operator< if (_First != _Last) for (_BidIt _Next = _First; ++_Next != _Last; ) if (((*_Next) < (*_First))) { // found new earliest element, rotate to front _BidIt _Next1 = _Next; ::std:: rotate(_First, _Next, ++_Next1); } else { // look for insertion point after first _BidIt _Dest = _Next; for (_BidIt _Dest0 = _Dest; ((*_Next) < (* --_Dest0)); ) _Dest = _Dest0; if (_Dest != _Next) { // rotate into place _BidIt _Next1 = _Next; ::std:: rotate(_Dest, _Next, ++_Next1); } } } template inline void _Med3(_RanIt _First, _RanIt _Mid, _RanIt _Last) { // sort median of three elements to middle if (((*_Mid) < (*_First))) ::std:: iter_swap(_Mid, _First); if (((*_Last) < (*_Mid))) ::std:: iter_swap(_Last, _Mid); if (((*_Mid) < (*_First))) ::std:: iter_swap(_Mid, _First); } template inline void _Median(_RanIt _First, _RanIt _Mid, _RanIt _Last) { // sort median element to middle if (40 < _Last - _First) { // median of nine int _Step = (_Last - _First + 1) / 8; _Med3(_First, _First + _Step, _First + 2 * _Step); _Med3(_Mid - _Step, _Mid, _Mid + _Step); _Med3(_Last - 2 * _Step, _Last - _Step, _Last); _Med3(_First + _Step, _Mid, _Last - _Step); } else _Med3(_First, _Mid, _Last); } template inline pair<_RanIt, _RanIt> _Unguarded_partition(_RanIt _First, _RanIt _Last) { // partition [_First, _Last), using operator< _RanIt _Mid = _First + (_Last - _First) / 2; // sort median to _Mid _Median(_First, _Mid, _Last - 1); _RanIt _Pfirst = _Mid; _RanIt _Plast = _Pfirst + 1; while (_First < _Pfirst && !((*(_Pfirst - 1)) < (*_Pfirst)) && !(*_Pfirst < *(_Pfirst - 1))) --_Pfirst; while (_Plast < _Last && !((*_Plast) < (*_Pfirst)) && !(*_Pfirst < *_Plast)) ++_Plast; _RanIt _Gfirst = _Plast; _RanIt _Glast = _Pfirst; for (; ; ) { // partition for (; _Gfirst < _Last; ++_Gfirst) if (((*_Pfirst) < (*_Gfirst))) ; else if (*_Gfirst < *_Pfirst) break; else ::std:: iter_swap(_Plast++, _Gfirst); for (; _First < _Glast; --_Glast) if (((*(_Glast - 1)) < (*_Pfirst))) ; else if (*_Pfirst < *(_Glast - 1)) break; else ::std:: iter_swap(--_Pfirst, _Glast - 1); if (_Glast == _First && _Gfirst == _Last) return (pair<_RanIt, _RanIt>(_Pfirst, _Plast)); if (_Glast == _First) { // no room at bottom, rotate pivot upward if (_Plast != _Gfirst) ::std:: iter_swap(_Pfirst, _Plast); ++_Plast; ::std:: iter_swap(_Pfirst++, _Gfirst++); } else if (_Gfirst == _Last) { // no room at top, rotate pivot downward if (--_Glast != --_Pfirst) ::std:: iter_swap(_Glast, _Pfirst); ::std:: iter_swap(_Pfirst, --_Plast); } else ::std:: iter_swap(_Gfirst++, --_Glast); } } template inline void _Sort(_RanIt _First, _RanIt _Last, _Diff _Ideal) { // order [_First, _Last), using operator< _Diff _Count; for (; _ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal; ) { // divide and conquer by quicksort pair<_RanIt, _RanIt> _Mid = _Unguarded_partition(_First, _Last); _Ideal /= 2, _Ideal += _Ideal / 2; // allow 1.5 log2(N) divisions if (_Mid.first - _First < _Last - _Mid.second) // loop on larger half _Sort(_First, _Mid.first, _Ideal), _First = _Mid.second; else _Sort(_Mid.second, _Last, _Ideal), _Last = _Mid.first; } if (_ISORT_MAX < _Count) { // heap sort if too many divisions ::std:: make_heap(_First, _Last); ::std:: sort_heap(_First, _Last); } else if (1 < _Count) _Insertion_sort(_First, _Last); // small, insertion sort } template inline void sort(_RanIt _First, _RanIt _Last) { // order [_First, _Last), using operator< ; _Sort(_First, _Last, _Last - _First); } // TEMPLATE FUNCTION sort WITH PRED template inline void _Insertion_sort(_BidIt _First, _BidIt _Last, _Pr _Pred) { // insertion sort [_First, _Last), using _Pred if (_First != _Last) for (_BidIt _Next = _First; ++_Next != _Last; ) if (_Pred(*_Next, *_First)) { // found new earliest element, rotate to front _BidIt _Next1 = _Next; ::std:: rotate(_First, _Next, ++_Next1); } else { // look for insertion point after first _BidIt _Dest = _Next; for (_BidIt _Dest0 = _Dest; _Pred(*_Next, * --_Dest0); ) _Dest = _Dest0; if (_Dest != _Next) { // rotate into place _BidIt _Next1 = _Next; ::std:: rotate(_Dest, _Next, ++_Next1); } } } template inline void _Med3(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred) { // sort median of three elements to middle if (_Pred(*_Mid, *_First)) ::std:: iter_swap(_Mid, _First); if (_Pred(*_Last, *_Mid)) ::std:: iter_swap(_Last, _Mid); if (_Pred(*_Mid, *_First)) ::std:: iter_swap(_Mid, _First); } template inline void _Median(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred) { // sort median element to middle if (40 < _Last - _First) { // median of nine int _Step = (_Last - _First + 1) / 8; _Med3(_First, _First + _Step, _First + 2 * _Step, _Pred); _Med3(_Mid - _Step, _Mid, _Mid + _Step, _Pred); _Med3(_Last - 2 * _Step, _Last - _Step, _Last, _Pred); _Med3(_First + _Step, _Mid, _Last - _Step, _Pred); } else _Med3(_First, _Mid, _Last, _Pred); } template inline pair<_RanIt, _RanIt> _Unguarded_partition(_RanIt _First, _RanIt _Last, _Pr _Pred) { // partition [_First, _Last), using _Pred _RanIt _Mid = _First + (_Last - _First) / 2; _Median(_First, _Mid, _Last - 1, _Pred); _RanIt _Pfirst = _Mid; _RanIt _Plast = _Pfirst + 1; while (_First < _Pfirst && !_Pred(*(_Pfirst - 1), *_Pfirst) && !_Pred(*_Pfirst, *(_Pfirst - 1))) --_Pfirst; while (_Plast < _Last && !_Pred(*_Plast, *_Pfirst) && !_Pred(*_Pfirst, *_Plast)) ++_Plast; _RanIt _Gfirst = _Plast; _RanIt _Glast = _Pfirst; for (; ; ) { // partition for (; _Gfirst < _Last; ++_Gfirst) if (_Pred(*_Pfirst, *_Gfirst)) ; else if (_Pred(*_Gfirst, *_Pfirst)) break; else ::std:: iter_swap(_Plast++, _Gfirst); for (; _First < _Glast; --_Glast) if (_Pred(*(_Glast - 1), *_Pfirst)) ; else if (_Pred(*_Pfirst, *(_Glast - 1))) break; else ::std:: iter_swap(--_Pfirst, _Glast - 1); if (_Glast == _First && _Gfirst == _Last) return (pair<_RanIt, _RanIt>(_Pfirst, _Plast)); if (_Glast == _First) { // no room at bottom, rotate pivot upward if (_Plast != _Gfirst) ::std:: iter_swap(_Pfirst, _Plast); ++_Plast; ::std:: iter_swap(_Pfirst++, _Gfirst++); } else if (_Gfirst == _Last) { // no room at top, rotate pivot downward if (--_Glast != --_Pfirst) ::std:: iter_swap(_Glast, _Pfirst); ::std:: iter_swap(_Pfirst, --_Plast); } else ::std:: iter_swap(_Gfirst++, --_Glast); } } template inline void _Sort(_RanIt _First, _RanIt _Last, _Diff _Ideal, _Pr _Pred) { // order [_First, _Last), using _Pred _Diff _Count; for (; _ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal; ) { // divide and conquer by quicksort pair<_RanIt, _RanIt> _Mid = _Unguarded_partition(_First, _Last, _Pred); _Ideal /= 2, _Ideal += _Ideal / 2; // allow 1.5 log2(N) divisions if (_Mid.first - _First < _Last - _Mid.second) // loop on larger half _Sort(_First, _Mid.first, _Ideal, _Pred), _First = _Mid.second; else _Sort(_Mid.second, _Last, _Ideal, _Pred), _Last = _Mid.first; } if (_ISORT_MAX < _Count) { // heap sort if too many divisions ::std:: make_heap(_First, _Last, _Pred); ::std:: sort_heap(_First, _Last, _Pred); } else if (1 < _Count) _Insertion_sort(_First, _Last, _Pred); // small, insertion sort } template inline void sort(_RanIt _First, _RanIt _Last, _Pr _Pred) { // order [_First, _Last), using _Pred ; ; _Sort(_First, _Last, _Last - _First, _Pred); } // TEMPLATE FUNCTION stable_sort template inline void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest, _Diff _Chunk, _Diff _Count) { // copy merging chunks, using operator< for (_Diff _Chunk2 = _Chunk * 2; _Chunk2 <= _Count; _Count -= _Chunk2) { // copy merging pairs of adjacent chunks _BidIt _Mid1 = _First; ::std:: advance(_Mid1, _Chunk); _BidIt _Mid2 = _Mid1; ::std:: advance(_Mid2, _Chunk); _Dest = ::std:: merge(_First, _Mid1, _Mid1, _Mid2, _Dest); _First = _Mid2; } if (_Count <= _Chunk) ::std:: copy(_First, _Last, _Dest); // copy partial last chunk else { // copy merging whole and partial last chunk _BidIt _Mid = _First; ::std:: advance(_Mid, _Chunk); ::std:: merge(_First, _Mid, _Mid, _Last, _Dest); } } template inline void _Buffered_merge_sort(_BidIt _First, _BidIt _Last, _Diff _Count, _Temp_iterator<_Ty>& _Tempbuf) { // sort using temp buffer for merges, using operator< _BidIt _Mid = _First; for (_Diff _Nleft = _Count; _ISORT_MAX <= _Nleft; _Nleft -= _ISORT_MAX) { // sort chunks _BidIt _Midend = _Mid; ::std:: advance(_Midend, (int)_ISORT_MAX); _Insertion_sort(_Mid, _Midend); _Mid = _Midend; } _Insertion_sort(_Mid, _Last); // sort partial last chunk for (_Diff _Chunk = _ISORT_MAX; _Chunk < _Count; _Chunk *= 2) { // merge adjacent pairs of chunks to and from temp buffer _Chunked_merge(_First, _Last, _Tempbuf._Init(), _Chunk, _Count); _Chunked_merge(_Tempbuf._First(), _Tempbuf._Last(), _First, _Chunk *= 2, _Count); } } template inline void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff _Count, _Temp_iterator<_Ty>& _Tempbuf) { // sort preserving order of equivalents, using operator< if (_Count <= _ISORT_MAX) _Insertion_sort(_First, _Last); // small, insertion sort else { // sort halves and merge _Diff _Count2 = (_Count + 1) / 2; _BidIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (_Count2 <= _Tempbuf._Maxlen()) { // temp buffer big enough, sort each half using buffer _Buffered_merge_sort(_First, _Mid, _Count2, _Tempbuf); _Buffered_merge_sort(_Mid, _Last, _Count - _Count2, _Tempbuf); } else { // temp buffer not big enough, divide and conquer _Stable_sort(_First, _Mid, _Count2, _Tempbuf); _Stable_sort(_Mid, _Last, _Count - _Count2, _Tempbuf); } _Buffered_merge(_First, _Mid, _Last, _Count2, _Count - _Count2, _Tempbuf); // merge sorted halves } } template inline void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff *, _Ty *) { // sort preserving order of equivalents, using operator< _Diff _Count = 0; _Distance(_First, _Last, _Count); _Temp_iterator<_Ty> _Tempbuf(_Count); _Stable_sort(_First, _Last, _Count, _Tempbuf); } template inline void stable_sort(_BidIt _First, _BidIt _Last) { // sort preserving order of equivalents, using operator< ; if (_First != _Last) _Stable_sort(_First, _Last, _Dist_type(_First), _Val_type(_First)); } // TEMPLATE FUNCTION stable_sort WITH PRED template inline void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest, _Diff _Chunk, _Diff _Count, _Pr _Pred) { // copy merging chunks, using _Pred for (_Diff _Chunk2 = _Chunk * 2; _Chunk2 <= _Count; _Count -= _Chunk2) { // copy merging pairs of adjacent chunks _BidIt _Mid1 = _First; ::std:: advance(_Mid1, _Chunk); _BidIt _Mid2 = _Mid1; ::std:: advance(_Mid2, _Chunk); _Dest = ::std:: merge(_First, _Mid1, _Mid1, _Mid2, _Dest, _Pred); _First = _Mid2; } if (_Count <= _Chunk) ::std:: copy(_First, _Last, _Dest); // copy partial last chunk else { // copy merging whole and partial last chunk _BidIt _Mid1 = _First; ::std:: advance(_Mid1, _Chunk); ::std:: merge(_First, _Mid1, _Mid1, _Last, _Dest, _Pred); } } template inline void _Buffered_merge_sort(_BidIt _First, _BidIt _Last, _Diff _Count, _Temp_iterator<_Ty>& _Tempbuf, _Pr _Pred) { // sort using temp buffer for merges, using _Pred _BidIt _Mid = _First; for (_Diff _Nleft = _Count; _ISORT_MAX <= _Nleft; _Nleft -= _ISORT_MAX) { // sort chunks _BidIt _Midn = _Mid; ::std:: advance(_Midn, (int)_ISORT_MAX); _Insertion_sort(_Mid, _Midn, _Pred); _Mid = _Midn; } _Insertion_sort(_Mid, _Last, _Pred); // sort partial last chunk for (_Diff _Chunk = _ISORT_MAX; _Chunk < _Count; _Chunk *= 2) { // merge adjacent pairs of chunks to and from temp buffer _Chunked_merge(_First, _Last, _Tempbuf._Init(), _Chunk, _Count, _Pred); _Chunked_merge(_Tempbuf._First(), _Tempbuf._Last(), _First, _Chunk *= 2, _Count, _Pred); } } template inline void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff _Count, _Temp_iterator<_Ty>& _Tempbuf, _Pr _Pred) { // sort preserving order of equivalents, using _Pred if (_Count <= _ISORT_MAX) _Insertion_sort(_First, _Last, _Pred); // small, insertion sort else { // sort halves and merge _Diff _Count2 = (_Count + 1) / 2; _BidIt _Mid = _First; ::std:: advance(_Mid, _Count2); if (_Count2 <= _Tempbuf._Maxlen()) { // temp buffer big enough, sort each half using buffer _Buffered_merge_sort(_First, _Mid, _Count2, _Tempbuf, _Pred); _Buffered_merge_sort(_Mid, _Last, _Count - _Count2, _Tempbuf, _Pred); } else { // temp buffer not big enough, divide and conquer _Stable_sort(_First, _Mid, _Count2, _Tempbuf, _Pred); _Stable_sort(_Mid, _Last, _Count - _Count2, _Tempbuf, _Pred); } _Buffered_merge(_First, _Mid, _Last, _Count2, _Count - _Count2, _Tempbuf, _Pred); // merge halves } } template inline void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff *, _Ty *, _Pr _Pred) { // sort preserving order of equivalents, using _Pred _Diff _Count = 0; _Distance(_First, _Last, _Count); _Temp_iterator<_Ty> _Tempbuf(_Count); _Stable_sort(_First, _Last, _Count, _Tempbuf, _Pred); } template inline void stable_sort(_BidIt _First, _BidIt _Last, _Pr _Pred) { // sort preserving order of equivalents, using _Pred ; ; if (_First != _Last) _Stable_sort(_First, _Last, _Dist_type(_First), _Val_type(_First), _Pred); } // TEMPLATE FUNCTION partial_sort template inline void _Partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Ty *) { // order [First, _Last) up to _Mid, using operator< ; ; ::std:: make_heap(_First, _Mid); for (_RanIt _Next = _Mid; _Next < _Last; ++_Next) if (((*_Next) < (*_First))) _Pop_heap(_First, _Mid, _Next, _Ty(*_Next), _Dist_type(_First)); // replace top with new largest ::std:: sort_heap(_First, _Mid); } template inline void partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last) { // order [First, _Last) up to _Mid, using operator< _Partial_sort(_First, _Mid, _Last, _Val_type(_First)); } // TEMPLATE FUNCTION partial_sort WITH PRED template inline void _Partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred, _Ty *) { // order [First, _Last) up to _Mid, using _Pred ; ; ; ::std:: make_heap(_First, _Mid, _Pred); for (_RanIt _Next = _Mid; _Next < _Last; ++_Next) if (_Pred(*_Next, *_First)) _Pop_heap(_First, _Mid, _Next, _Ty(*_Next), _Pred, _Dist_type(_First)); // replace top with new largest ::std:: sort_heap(_First, _Mid, _Pred); } template inline void partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred) { // order [First, _Last) up to _Mid, using _Pred _Partial_sort(_First, _Mid, _Last, _Pred, _Val_type(_First)); } // TEMPLATE FUNCTION partial_sort_copy template inline _RanIt _Partial_sort_copy(_InIt _First1, _InIt _Last1, _RanIt _First2, _RanIt _Last2, _Diff *, _Ty *) { // copy [First1, _Last1) into [_First2, _Last2), using operator< ; ; _RanIt _Mid2 = _First2; for (; _First1 != _Last1 && _Mid2 != _Last2; ++_First1, ++_Mid2) *_Mid2 = *_First1; // copy min(_Last1 - _First1, _Last2 - _First2) ::std:: make_heap(_First2, _Mid2); for (; _First1 != _Last1; ++_First1) if (((*_First1) < (*_First2))) _Adjust_heap(_First2, _Diff(0), _Diff(_Mid2 - _First2), _Ty(*_First1)); // replace top with new largest ::std:: sort_heap(_First2, _Mid2); return (_Mid2); } template inline _RanIt partial_sort_copy(_InIt _First1, _InIt _Last1, _RanIt _First2, _RanIt _Last2) { // copy [First1, _Last1) into [_First2, _Last2), using operator< return (_First1 == _Last1 || _First2 == _Last2 ? _First2 : _Partial_sort_copy(_First1, _Last1, _First2, _Last2, _Dist_type(_First2), _Val_type(_First1))); } // TEMPLATE FUNCTION partial_sort_copy WITH PRED template inline _RanIt _Partial_sort_copy(_InIt _First1, _InIt _Last1, _RanIt _First2, _RanIt _Last2, _Pr _Pred, _Diff *, _Ty *) { // copy [First1, _Last1) into [_First2, _Last2) using _Pred ; ; ; _RanIt _Mid2 = _First2; for (; _First1 != _Last1 && _Mid2 != _Last2; ++_First1, ++_Mid2) *_Mid2 = *_First1; // copy min(_Last1 - _First1, _Last2 - _First2) ::std:: make_heap(_First2, _Mid2, _Pred); for (; _First1 != _Last1; ++_First1) if (_Pred(*_First1, *_First2)) _Adjust_heap(_First2, _Diff(0), _Diff(_Mid2 - _First2), _Ty(*_First1), _Pred); // replace top with new largest ::std:: sort_heap(_First2, _Mid2, _Pred); return (_Mid2); } template inline _RanIt partial_sort_copy(_InIt _First1, _InIt _Last1, _RanIt _First2, _RanIt _Last2, _Pr _Pred) { // copy [First1, _Last1) into [_First2, _Last2) using _Pred return (_First1 == _Last1 || _First2 == _Last2 ? _First2 : _Partial_sort_copy(_First1, _Last1, _First2, _Last2, _Pred, _Dist_type(_First2), _Val_type(_First1))); } // TEMPLATE FUNCTION nth_element template inline void nth_element(_RanIt _First, _RanIt _Nth, _RanIt _Last) { // order Nth element, using operator< ; for (; _ISORT_MAX < _Last - _First; ) { // divide and conquer, ordering partition containing Nth pair<_RanIt, _RanIt> _Mid = _Unguarded_partition(_First, _Last); if (_Mid.second <= _Nth) _First = _Mid.second; else if (_Mid.first <= _Nth) return; // Nth inside fat pivot, done else _Last = _Mid.first; } _Insertion_sort(_First, _Last); // sort any remainder } // TEMPLATE FUNCTION nth_element WITH PRED template inline void nth_element(_RanIt _First, _RanIt _Nth, _RanIt _Last, _Pr _Pred) { // order Nth element, using _Pred ; ; for (; _ISORT_MAX < _Last - _First; ) { // divide and conquer, ordering partition containing Nth pair<_RanIt, _RanIt> _Mid = _Unguarded_partition(_First, _Last, _Pred); if (_Mid.second <= _Nth) _First = _Mid.second; else if (_Mid.first <= _Nth) return; // Nth inside fat pivot, done else _Last = _Mid.first; } _Insertion_sort(_First, _Last, _Pred); // sort any remainder } // TEMPLATE FUNCTION includes template inline bool includes(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2) { // test if all [_First1, _Last1) in [_First2, _Last2), using operator< ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (((*_First2) < (*_First1))) return (false); else if (*_First1 < *_First2) ++_First1; else ++_First1, ++_First2; return (_First2 == _Last2); } // TEMPLATE FUNCTION includes WITH PRED template inline bool includes(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _Pr _Pred) { // test if set [_First1, _Last1) in [_First2, _Last2), using _Pred ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (_Pred(*_First2, *_First1)) return (false); else if (_Pred(*_First1, *_First2)) ++_First1; else ++_First1, ++_First2; return (_First2 == _Last2); } // TEMPLATE FUNCTION set_union template inline _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest) { // OR sets [_First1, _Last1) and [_First2, _Last2), using operator< ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (((*_First1) < (*_First2))) *_Dest++ = *_First1, ++_First1; else if (*_First2 < *_First1) *_Dest++ = *_First2, ++_First2; else *_Dest++ = *_First1, ++_First1, ++_First2; _Dest = ::std:: copy(_First1, _Last1, _Dest); return (::std:: copy(_First2, _Last2, _Dest)); } // TEMPLATE FUNCTION set_union WITH PRED template inline _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (_Pred(*_First1, *_First2)) *_Dest++ = *_First1, ++_First1; else if (_Pred(*_First2, *_First1)) *_Dest++ = *_First2, ++_First2; else *_Dest++ = *_First1, ++_First1, ++_First2; _Dest = ::std:: copy(_First1, _Last1, _Dest); return (::std:: copy(_First2, _Last2, _Dest)); } // TEMPLATE FUNCTION set_intersection template inline _OutIt set_intersection(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest) { // AND sets [_First1, _Last1) and [_First2, _Last2), using operator< ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (((*_First1) < (*_First2))) ++_First1; else if (*_First2 < *_First1) ++_First2; else *_Dest++ = *_First1++, ++_First2; return (_Dest); } // TEMPLATE FUNCTION set_intersection WITH PRED template inline _OutIt set_intersection(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (_Pred(*_First1, *_First2)) ++_First1; else if (_Pred(*_First2, *_First1)) ++_First2; else *_Dest++ = *_First1++, ++_First2; return (_Dest); } // TEMPLATE FUNCTION set_difference template inline _OutIt set_difference(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest) { // take set [_First2, _Last2) from [_First1, _Last1), using operator< ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (((*_First1) < (*_First2))) *_Dest++ = *_First1, ++_First1; else if (*_First2 < *_First1) ++_First2; else ++_First1, ++_First2; return (::std:: copy(_First1, _Last1, _Dest)); } // TEMPLATE FUNCTION set_difference WITH PRED template inline _OutIt set_difference(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // take set [_First2, _Last2) from [_First1, _Last1), using _Pred ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (_Pred(*_First1, *_First2)) *_Dest++ = *_First1, ++_First1; else if (_Pred(*_First2, *_First1)) ++_First2; else ++_First1, ++_First2; return (::std:: copy(_First1, _Last1, _Dest)); } // TEMPLATE FUNCTION set_symmetric_difference template inline _OutIt set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest) { // XOR sets [_First1, _Last1) and [_First2, _Last2), using operator< ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (((*_First1) < (*_First2))) *_Dest++ = *_First1, ++_First1; else if (*_First2 < *_First1) *_Dest++ = *_First2, ++_First2; else ++_First1, ++_First2; _Dest = ::std:: copy(_First1, _Last1, _Dest); return (::std:: copy(_First2, _Last2, _Dest)); } // TEMPLATE FUNCTION set_symmetric_difference WITH PRED template inline _OutIt set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred ; ; ; for (; _First1 != _Last1 && _First2 != _Last2; ) if (_Pred(*_First1, *_First2)) *_Dest++ = *_First1, ++_First1; else if (_Pred(*_First2, *_First1)) *_Dest++ = *_First2, ++_First2; else ++_First1, ++_First2; _Dest = ::std:: copy(_First1, _Last1, _Dest); return (::std:: copy(_First2, _Last2, _Dest)); } // TEMPLATE FUNCTION max_element template inline _FwdIt max_element(_FwdIt _First, _FwdIt _Last) { // find largest element, using operator< ; _FwdIt _Found = _First; if (_First != _Last) for (; ++_First != _Last; ) if (((*_Found) < (*_First))) _Found = _First; return (_Found); } // TEMPLATE FUNCTION max_element WITH PRED template inline _FwdIt max_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // find largest element, using _Pred ; ; _FwdIt _Found = _First; if (_First != _Last) for (; ++_First != _Last; ) if (_Pred(*_Found, *_First)) _Found = _First; return (_Found); } // TEMPLATE FUNCTION min_element template inline _FwdIt min_element(_FwdIt _First, _FwdIt _Last) { // find smallest element, using operator< ; _FwdIt _Found = _First; if (_First != _Last) for (; ++_First != _Last; ) if (((*_First) < (*_Found))) _Found = _First; return (_Found); } // TEMPLATE FUNCTION min_element WITH PRED template inline _FwdIt min_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // find smallest element, using _Pred ; ; _FwdIt _Found = _First; if (_First != _Last) for (; ++_First != _Last; ) if (_Pred(*_First, *_Found)) _Found = _First; return (_Found); } // TEMPLATE FUNCTION next_permutation template inline bool next_permutation(_BidIt _First, _BidIt _Last) { // permute and test for pure ascending, using operator< ; _BidIt _Next = _Last; if (_First == _Last || _First == --_Next) return (false); for (; ; ) { // find rightmost element smaller than successor _BidIt _Next1 = _Next; if (((* --_Next) < (*_Next1))) { // swap with rightmost element that's smaller, flip suffix _BidIt _Mid = _Last; for (; !((*_Next) < (* --_Mid)); ) ; ::std:: iter_swap(_Next, _Mid); ::std:: reverse(_Next1, _Last); return (true); } if (_Next == _First) { // pure descending, flip all ::std:: reverse(_First, _Last); return (false); } } } // TEMPLATE FUNCTION next_permutation WITH PRED template inline bool next_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred) { // permute and test for pure ascending, using _Pred ; ; _BidIt _Next = _Last; if (_First == _Last || _First == --_Next) return (false); for (; ; ) { // find rightmost element smaller than successor _BidIt _Next1 = _Next; if (_Pred(* --_Next, *_Next1)) { // swap with rightmost element that's smaller, flip suffix _BidIt _Mid = _Last; for (; !_Pred(*_Next, * --_Mid); ) ; ::std:: iter_swap(_Next, _Mid); ::std:: reverse(_Next1, _Last); return (true); } if (_Next == _First) { // pure descending, flip all ::std:: reverse(_First, _Last); return (false); } } } // TEMPLATE FUNCTION prev_permutation template inline bool prev_permutation(_BidIt _First, _BidIt _Last) { // reverse permute and test for pure descending, using operator< ; _BidIt _Next = _Last; if (_First == _Last || _First == --_Next) return (false); for (; ; ) { // find rightmost element not smaller than successor _BidIt _Next1 = _Next; if (!((* --_Next) < (*_Next1))) { // swap with rightmost element that's not smaller, flip suffix _BidIt _Mid = _Last; for (; ((*_Next) < (* --_Mid)); ) ; ::std:: iter_swap(_Next, _Mid); ::std:: reverse(_Next1, _Last); return (true); } if (_Next == _First) { // pure ascending, flip all ::std:: reverse(_First, _Last); return (false); } } } // TEMPLATE FUNCTION prev_permutation WITH PRED template inline bool prev_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred) { // reverse permute and test for pure descending, using _Pred ; ; _BidIt _Next = _Last; if (_First == _Last || _First == --_Next) return (false); for (; ; ) { // find rightmost element not smaller than successor _BidIt _Next1 = _Next; if (!_Pred(* --_Next, *_Next1)) { // swap with rightmost element that's not smaller, flip suffix _BidIt _Mid = _Last; for (; _Pred(*_Next, * --_Mid); ) ; ::std:: iter_swap(_Next, _Mid); ::std:: reverse(_Next1, _Last); return (true); } if (_Next == _First) { // pure ascending, flip all ::std:: reverse(_First, _Last); return (false); } } } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */ /* * This file is derived from software bearing the following * restrictions: * * 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. V4.02:1476 */ // iterator standard header namespace std { // TEMPLATE CLASS back_insert_iterator template class back_insert_iterator : public _Outit { // wrap pushes to back of container as output iterator public: typedef _Container container_type; typedef typename _Container::reference reference; explicit back_insert_iterator(_Container& _Cont) : container(&_Cont) { // construct with container } back_insert_iterator<_Container>& operator=( typename _Container::const_reference _Val) { // push value into container container->push_back(_Val); return (*this); } back_insert_iterator<_Container>& operator*() { // pretend to return designated value return (*this); } back_insert_iterator<_Container>& operator++() { // pretend to preincrement return (*this); } back_insert_iterator<_Container> operator++(int) { // pretend to postincrement return (*this); } protected: _Container *container; // pointer to container }; // TEMPLATE FUNCTION back_inserter template inline back_insert_iterator<_Container> back_inserter(_Container& _Cont) { // return a back_insert_iterator return (::std:: back_insert_iterator<_Container>(_Cont)); } // TEMPLATE CLASS front_insert_iterator template class front_insert_iterator : public _Outit { // wrap pushes to front of container as output iterator public: typedef _Container container_type; typedef typename _Container::reference reference; explicit front_insert_iterator(_Container& _Cont) : container(&_Cont) { // construct with container } front_insert_iterator<_Container>& operator=( typename _Container::const_reference _Val) { // push value into container container->push_front(_Val); return (*this); } front_insert_iterator<_Container>& operator*() { // pretend to return designated value return (*this); } front_insert_iterator<_Container>& operator++() { // pretend to preincrement return (*this); } front_insert_iterator<_Container> operator++(int) { // pretend to postincrement return (*this); } protected: _Container *container; // pointer to container }; // TEMPLATE FUNCTION front_inserter template inline front_insert_iterator<_Container> front_inserter(_Container& _Cont) { // return front_insert_iterator return (::std:: front_insert_iterator<_Container>(_Cont)); } // TEMPLATE CLASS insert_iterator template class insert_iterator : public _Outit { // wrap inserts into container as output iterator public: typedef _Container container_type; typedef typename _Container::reference reference; insert_iterator(_Container& _Cont, typename _Container::iterator _Where) : container(&_Cont), iter(_Where) { // construct with container and iterator } insert_iterator<_Container>& operator=( typename _Container::const_reference _Val) { // insert into container and increment stored iterator iter = container->insert(iter, _Val); ++iter; return (*this); } insert_iterator<_Container>& operator*() { // pretend to return designated value return (*this); } insert_iterator<_Container>& operator++() { // pretend to preincrement return (*this); } insert_iterator<_Container>& operator++(int) { // pretend to postincrement return (*this); } protected: _Container *container; // pointer to container typename _Container::iterator iter; // iterator into container }; // TEMPLATE FUNCTION inserter template inline insert_iterator<_Container> inserter(_Container& _Cont, _Iter _Where) { // return insert_iterator return (::std:: insert_iterator<_Container>(_Cont, _Where)); } // TEMPLATE CLASS istream_iterator template, class _Diff = ptrdiff_t> class istream_iterator : public iterator { // wrap _Ty extracts from input stream as input iterator typedef istream_iterator<_Ty, _Elem, _Traits, _Diff> _Myt; public: typedef _Elem char_type; typedef _Traits traits_type; typedef basic_istream<_Elem, _Traits> istream_type; istream_iterator() : _Myistr(0) { // construct singular iterator } istream_iterator(istream_type& _Istr) : _Myistr(&_Istr) { // construct with input stream _Getval(); } const _Ty& operator*() const { // return designated value return (_Myval); } const _Ty *operator->() const { // return pointer to class object return (&**this); } _Myt& operator++() { // preincrement _Getval(); return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; ++*this; return (_Tmp); } bool _Equal(const _Myt& _Right) const { // test for iterator equality return (_Myistr == _Right._Myistr); } protected: void _Getval() { // get a _Ty value if possible if (_Myistr != 0 && !(*_Myistr >> _Myval)) _Myistr = 0; } istream_type *_Myistr; // pointer to input stream _Ty _Myval; // lookahead value (valid if _Myistr is not null) }; // istream_iterator TEMPLATE OPERATORS template inline bool operator==( const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Left, const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Right) { // test for istream_iterator equality return (_Left._Equal(_Right)); } template inline bool operator!=( const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Left, const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Right) { // test for istream_iterator inequality return (!(_Left == _Right)); } // TEMPLATE CLASS ostream_iterator template > class ostream_iterator : public _Outit { // wrap _Ty inserts to output stream as output iterator public: typedef _Elem char_type; typedef _Traits traits_type; typedef basic_ostream<_Elem, _Traits> ostream_type; ostream_iterator(ostream_type& _Ostr, const _Elem *_Delim = 0) : _Myostr(&_Ostr), _Mydelim(_Delim) { // construct from output stream and delimiter } ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val) { // insert value into output stream, followed by delimiter *_Myostr << _Val; if (_Mydelim != 0) *_Myostr << _Mydelim; return (*this); } ostream_iterator<_Ty, _Elem, _Traits>& operator*() { // pretend to return designated value return (*this); } ostream_iterator<_Ty, _Elem, _Traits>& operator++() { // pretend to preincrement return (*this); } ostream_iterator<_Ty, _Elem, _Traits> operator++(int) { // pretend to postincrement return (*this); } protected: const _Elem *_Mydelim; // pointer to delimiter string (NB: not freed) ostream_type *_Myostr; // pointer to output stream }; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */ /* * This file is derived from software bearing the following * restrictions: * * 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. V4.02:1476 */ //If boost dependencies are avoided include all machinery //Small meta-typetraits to support move namespace boost { namespace move_detail { //if_ template struct if_c { typedef T1 type; }; template struct if_c { typedef T2 type; }; template struct if_ { typedef typename if_c<0 != T1::value, T2, T3>::type type; }; //enable_if_ template struct enable_if_c { typedef T type; }; template struct enable_if_c {}; template struct enable_if : public enable_if_c {}; template struct disable_if : public enable_if_c {}; //integral_constant template struct integral_constant { static const T value = v; typedef T value_type; typedef integral_constant type; }; //identity template struct identity { typedef T type; }; //is_convertible template class is_convertible { typedef char true_t; class false_t { char dummy[2]; }; static true_t dispatch(U); static false_t dispatch(...); static T &trigger(); public: enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; }; //and_ not_ template > struct and_ : public integral_constant {}; template struct not_ : public integral_constant {}; //is_lvalue_reference template struct is_lvalue_reference : public integral_constant {}; template struct is_lvalue_reference : public integral_constant {}; //has_trivial_destructor template struct has_trivial_destructor : public integral_constant {}; //addressof template struct addr_impl_ref { T & v_; inline addr_impl_ref( T & v ): v_( v ) {} inline operator T& () const { return v_; } private: addr_impl_ref & operator=(const addr_impl_ref &); }; template struct addressof_impl { static inline T * f( T & v, long ) { return reinterpret_cast( &const_cast(reinterpret_cast(v))); } static inline T * f( T * v, int ) { return v; } }; template inline T * addressof( T & v ) { return ::boost::move_detail::addressof_impl::f ( ::boost::move_detail::addr_impl_ref( v ), 0 ); } } //namespace move_detail { } //namespace boost { //Compiler workaround detection /// @endcond //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers namespace boost { namespace move_detail { template struct is_class_or_union { struct twochar { char _[2]; }; template static char is_class_or_union_tester(void(U::*)(void)); template static twochar is_class_or_union_tester(...); static const bool value = sizeof(is_class_or_union_tester(0)) == sizeof(char); }; struct empty{}; } ////////////////////////////////////////////////////////////////////////////// // // struct rv // ////////////////////////////////////////////////////////////////////////////// template class rv : public ::boost::move_detail::if_c < ::boost::move_detail::is_class_or_union::value , T , ::boost::move_detail::empty >::type { rv(); ~rv(); rv(rv const&); void operator=(rv const&); } ; ////////////////////////////////////////////////////////////////////////////// // // move_detail::is_rv // ////////////////////////////////////////////////////////////////////////////// namespace move_detail { template struct is_rv : ::boost::move_detail::integral_constant {}; template struct is_rv< rv > : ::boost::move_detail::integral_constant {}; template struct is_rv< const rv > : ::boost::move_detail::integral_constant {}; } //namespace move_detail { ////////////////////////////////////////////////////////////////////////////// // // has_move_emulation_enabled // ////////////////////////////////////////////////////////////////////////////// template struct has_move_emulation_enabled : ::boost::move_detail::is_convertible< T, ::boost::rv& > {}; template struct has_move_emulation_enabled : ::boost::move_detail::integral_constant {}; template struct has_move_emulation_enabled< ::boost::rv > : ::boost::move_detail::integral_constant {}; template struct has_move_emulation_enabled_aux : has_move_emulation_enabled {}; template struct has_nothrow_move : public ::boost::move_detail::integral_constant {}; ////////////////////////////////////////////////////////////////////////////// // // move() // ////////////////////////////////////////////////////////////////////////////// template inline typename ::boost::move_detail::disable_if, T&>::type move(T& x) { return x; } template inline typename ::boost::move_detail::enable_if, rv&>::type move(T& x) { return *static_cast* >(::boost::move_detail::addressof(x)); } template inline typename ::boost::move_detail::enable_if, rv&>::type move(rv& x) { return x; } ////////////////////////////////////////////////////////////////////////////// // // forward() // ////////////////////////////////////////////////////////////////////////////// template inline typename ::boost::move_detail::enable_if< ::boost::move_detail::is_rv, T &>::type forward(const typename ::boost::move_detail::identity::type &x) { return const_cast(x); } template inline typename ::boost::move_detail::disable_if< ::boost::move_detail::is_rv, const T &>::type forward(const typename ::boost::move_detail::identity::type &x) { return x; } ////////////////////////////////////////////////////////////////////////////// // // BOOST_MOVABLE_BUT_NOT_COPYABLE // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // BOOST_COPYABLE_AND_MOVABLE // ////////////////////////////////////////////////////////////////////////////// } //namespace boost namespace boost { ////////////////////////////////////////////////////////////////////////////// // // move_iterator // ////////////////////////////////////////////////////////////////////////////// //! Class template move_iterator is an iterator adaptor with the same behavior //! as the underlying iterator except that its dereference operator implicitly //! converts the value returned by the underlying iterator's dereference operator //! to an rvalue reference. Some generic algorithms can be called with move //! iterators to replace copying with moving. template class move_iterator { public: typedef It iterator_type; typedef typename std::iterator_traits::value_type value_type; typedef typename ::boost::move_detail::if_ < ::boost::has_move_emulation_enabled , ::boost::rv& , value_type & >::type reference; typedef It pointer; typedef typename std::iterator_traits::difference_type difference_type; typedef typename std::iterator_traits::iterator_category iterator_category; move_iterator() {} explicit move_iterator(It i) : m_it(i) {} template move_iterator(const move_iterator& u) : m_it(u.base()) {} iterator_type base() const { return m_it; } reference operator*() const { return *m_it; } pointer operator->() const { return m_it; } move_iterator& operator++() { ++m_it; return *this; } move_iterator operator++(int) { move_iterator tmp(*this); ++(*this); return tmp; } move_iterator& operator--() { --m_it; return *this; } move_iterator operator--(int) { move_iterator tmp(*this); --(*this); return tmp; } move_iterator operator+ (difference_type n) const { return move_iterator(m_it + n); } move_iterator& operator+=(difference_type n) { m_it += n; return *this; } move_iterator operator- (difference_type n) const { return move_iterator(m_it - n); } move_iterator& operator-=(difference_type n) { m_it -= n; return *this; } reference operator[](difference_type n) const { return m_it[n]; } friend bool operator==(const move_iterator& x, const move_iterator& y) { return x.base() == y.base(); } friend bool operator!=(const move_iterator& x, const move_iterator& y) { return x.base() != y.base(); } friend bool operator< (const move_iterator& x, const move_iterator& y) { return x.base() < y.base(); } friend bool operator<=(const move_iterator& x, const move_iterator& y) { return x.base() <= y.base(); } friend bool operator> (const move_iterator& x, const move_iterator& y) { return x.base() > y.base(); } friend bool operator>=(const move_iterator& x, const move_iterator& y) { return x.base() >= y.base(); } friend difference_type operator-(const move_iterator& x, const move_iterator& y) { return x.base() - y.base(); } friend move_iterator operator+(difference_type n, const move_iterator& x) { return move_iterator(x.base() + n); } private: It m_it; }; //is_move_iterator namespace move_detail { template struct is_move_iterator : public ::boost::move_detail::integral_constant { }; template struct is_move_iterator< ::boost::move_iterator > : public ::boost::move_detail::integral_constant { }; } //namespace move_detail { ////////////////////////////////////////////////////////////////////////////// // // move_iterator // ////////////////////////////////////////////////////////////////////////////// //! //! Returns: move_iterator(i). template inline move_iterator make_move_iterator(const It &it) { return move_iterator(it); } ////////////////////////////////////////////////////////////////////////////// // // back_move_insert_iterator // ////////////////////////////////////////////////////////////////////////////// //! A move insert iterator that move constructs elements at the //! back of a container template // C models Container class back_move_insert_iterator : public std::iterator { C* container_m; public: typedef C container_type; explicit back_move_insert_iterator(C& x) : container_m(&x) { } back_move_insert_iterator& operator=(typename C::reference x) { container_m->push_back(boost::move(x)); return *this; } back_move_insert_iterator& operator*() { return *this; } back_move_insert_iterator& operator++() { return *this; } back_move_insert_iterator& operator++(int) { return *this; } }; //! //! Returns: back_move_insert_iterator(x). template // C models Container inline back_move_insert_iterator back_move_inserter(C& x) { return back_move_insert_iterator(x); } ////////////////////////////////////////////////////////////////////////////// // // front_move_insert_iterator // ////////////////////////////////////////////////////////////////////////////// //! A move insert iterator that move constructs elements int the //! front of a container template // C models Container class front_move_insert_iterator : public std::iterator { C* container_m; public: typedef C container_type; explicit front_move_insert_iterator(C& x) : container_m(&x) { } front_move_insert_iterator& operator=(typename C::reference x) { container_m->push_front(boost::move(x)); return *this; } front_move_insert_iterator& operator*() { return *this; } front_move_insert_iterator& operator++() { return *this; } front_move_insert_iterator& operator++(int) { return *this; } }; //! //! Returns: front_move_insert_iterator(x). template // C models Container inline front_move_insert_iterator front_move_inserter(C& x) { return front_move_insert_iterator(x); } ////////////////////////////////////////////////////////////////////////////// // // insert_move_iterator // ////////////////////////////////////////////////////////////////////////////// template // C models Container class move_insert_iterator : public std::iterator { C* container_m; typename C::iterator pos_; public: typedef C container_type; explicit move_insert_iterator(C& x, typename C::iterator pos) : container_m(&x), pos_(pos) {} move_insert_iterator& operator=(typename C::reference x) { pos_ = container_m->insert(pos_, ::boost::move(x)); ++pos_; return *this; } move_insert_iterator& operator*() { return *this; } move_insert_iterator& operator++() { return *this; } move_insert_iterator& operator++(int) { return *this; } }; //! //! Returns: move_insert_iterator(x, it). template // C models Container inline move_insert_iterator move_inserter(C& x, typename C::iterator it) { return move_insert_iterator(x, it); } ////////////////////////////////////////////////////////////////////////////// // // move // ////////////////////////////////////////////////////////////////////////////// //! Effects: Moves elements in the range [first,last) into the range [result,result + (last - //! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first), //! performs *(result + n) = ::boost::move (*(first + n)). //! //! Effects: result + (last - first). //! //! Requires: result shall not be in the range [first,last). //! //! Complexity: Exactly last - first move assignments. template // O models OutputIterator O move(I f, I l, O result) { while (f != l) { *result = ::boost::move(*f); ++f; ++result; } return result; } ////////////////////////////////////////////////////////////////////////////// // // move_backward // ////////////////////////////////////////////////////////////////////////////// //! Effects: Moves elements in the range [first,last) into the range //! [result - (last-first),result) starting from last - 1 and proceeding to //! first. For each positive integer n <= (last - first), //! performs *(result - n) = ::boost::move(*(last - n)). //! //! Requires: result shall not be in the range [first,last). //! //! Returns: result - (last - first). //! //! Complexity: Exactly last - first assignments. template // O models BidirectionalIterator O move_backward(I f, I l, O result) { while (f != l) { --l; --result; *result = ::boost::move(*l); } return result; } ////////////////////////////////////////////////////////////////////////////// // // uninitialized_move // ////////////////////////////////////////////////////////////////////////////// //! Effects: //! \code //! for (; first != last; ++result, ++first) //! new (static_cast(&*result)) //! typename iterator_traits::value_type(boost::move(*first)); //! \endcode //! //! Returns: result template // F models ForwardIterator F uninitialized_move(I f, I l, F r /// @cond // ,typename BOOST_MOVE_BOOST_NS::enable_if::value_type> >::type* = 0 /// @endcond ) { typedef typename std::iterator_traits::value_type input_value_type; while (f != l) { ::new(static_cast(&*r)) input_value_type(boost::move(*f)); ++f; ++r; } return r; } /// @cond /* template // F models ForwardIterator F uninitialized_move(I f, I l, F r, typename BOOST_MOVE_BOOST_NS::disable_if::value_type> >::type* = 0) { return std::uninitialized_copy(f, l, r); } */ ////////////////////////////////////////////////////////////////////////////// // // uninitialized_copy_or_move // ////////////////////////////////////////////////////////////////////////////// namespace move_detail { template // F models ForwardIterator inline F uninitialized_move_move_iterator(I f, I l, F r // ,typename BOOST_MOVE_BOOST_NS::enable_if< has_move_emulation_enabled >::type* = 0 ) { return ::boost::uninitialized_move(f, l, r); } /* template // F models ForwardIterator F uninitialized_move_move_iterator(I f, I l, F r, typename BOOST_MOVE_BOOST_NS::disable_if< has_move_emulation_enabled >::type* = 0) { return std::uninitialized_copy(f.base(), l.base(), r); } */ } //namespace move_detail { template // F models ForwardIterator inline F uninitialized_copy_or_move(I f, I l, F r, typename ::boost::move_detail::enable_if< move_detail::is_move_iterator >::type* = 0) { return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r); } ////////////////////////////////////////////////////////////////////////////// // // copy_or_move // ////////////////////////////////////////////////////////////////////////////// namespace move_detail { template // F models ForwardIterator inline F move_move_iterator(I f, I l, F r // ,typename BOOST_MOVE_BOOST_NS::enable_if< has_move_emulation_enabled >::type* = 0 ) { return ::boost::move(f, l, r); } /* template // F models ForwardIterator F move_move_iterator(I f, I l, F r, typename BOOST_MOVE_BOOST_NS::disable_if< has_move_emulation_enabled >::type* = 0) { return std::copy(f.base(), l.base(), r); } */ } //namespace move_detail { template // F models ForwardIterator inline F copy_or_move(I f, I l, F r, typename ::boost::move_detail::enable_if< move_detail::is_move_iterator >::type* = 0) { return ::boost::move_detail::move_move_iterator(f, l, r); } /// @endcond //! Effects: //! \code //! for (; first != last; ++result, ++first) //! new (static_cast(&*result)) //! typename iterator_traits::value_type(*first); //! \endcode //! //! Returns: result //! //! Note: This function is provided because //! std::uninitialized_copy from some STL implementations //! is not compatible with move_iterator template // F models ForwardIterator inline F uninitialized_copy_or_move(I f, I l, F r /// @cond ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator >::type* = 0 /// @endcond ) { return std::uninitialized_copy(f, l, r); } //! Effects: //! \code //! for (; first != last; ++result, ++first) //! *result = *first; //! \endcode //! //! Returns: result //! //! Note: This function is provided because //! std::uninitialized_copy from some STL implementations //! is not compatible with move_iterator template // F models ForwardIterator inline F copy_or_move(I f, I l, F r /// @cond ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator >::type* = 0 /// @endcond ) { return std::copy(f, l, r); } //! If this trait yields to true //! (has_trivial_destructor_after_move <T>::value == true) //! means that if T is used as argument of a move construction/assignment, //! there is no need to call T's destructor. //! This optimization tipically is used to improve containers' performance. //! //! By default this trait is true if the type has trivial destructor, //! every class should specialize this trait if it wants to improve performance //! when inserted in containers. template struct has_trivial_destructor_after_move : ::boost::move_detail::has_trivial_destructor {}; namespace move_detail { // Code from Jeffrey Lee Hellrung, many thanks template< class T> struct forward_type { typedef const T &type; }; template< class T> struct forward_type< boost::rv > { typedef T type; }; // Code from Jeffrey Lee Hellrung, many thanks template< class T > struct is_rvalue_reference : ::boost::move_detail::integral_constant { }; template< class T > struct is_rvalue_reference< boost::rv& > : ::boost::move_detail::integral_constant {}; template< class T > struct is_rvalue_reference< const boost::rv& > : ::boost::move_detail::integral_constant {}; namespace detail_add_rvalue_reference { template< class T , bool emulation = ::boost::has_move_emulation_enabled::value , bool rv = ::boost::move_detail::is_rv::value > struct add_rvalue_reference_impl { typedef T type; }; template< class T, bool emulation> struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; }; template< class T, bool rv > struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv& type; }; } // namespace detail_add_rvalue_reference template< class T > struct add_rvalue_reference : detail_add_rvalue_reference::add_rvalue_reference_impl { }; template< class T > struct add_rvalue_reference { typedef T & type; }; template< class T > struct remove_rvalue_reference { typedef T type; }; template< class T > struct remove_rvalue_reference< rv > { typedef T type; }; template< class T > struct remove_rvalue_reference< const rv > { typedef T type; }; template< class T > struct remove_rvalue_reference< volatile rv > { typedef T type; }; template< class T > struct remove_rvalue_reference< const volatile rv > { typedef T type; }; template< class T > struct remove_rvalue_reference< rv& > { typedef T type; }; template< class T > struct remove_rvalue_reference< const rv& > { typedef T type; }; template< class T > struct remove_rvalue_reference< volatile rv& > { typedef T type; }; template< class T > struct remove_rvalue_reference< const volatile rv& >{ typedef T type; }; template typename boost::move_detail::add_rvalue_reference::type declval(); } // Ideas from Boost.Move review, Jeffrey Lee Hellrung: // //- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ? // Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue // references the same as wrt real rvalue references, i.e., add_reference< rv& > -> T& rather than // rv& (since T&& & -> T&). // //- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...? // //- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated // rvalue references in C++03. This may be necessary to prevent "accidental moves". } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Pablo Halpern 2009. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/interprocess for documentation. // ////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Pablo Halpern 2009. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { namespace detail { typedef char one; struct two {one _[2];}; template< bool C_ > struct bool_ { static const bool value = C_; }; typedef bool_ true_; typedef bool_ false_; typedef true_ true_type; typedef false_ false_type; typedef char yes_type; struct no_type { char padding[8]; }; template struct enable_if_c { typedef T type; }; template struct enable_if_c {}; template struct enable_if : public enable_if_c{}; template struct apply { typedef typename F::template apply::type type; }; template class is_convertible { typedef char true_t; class false_t { char dummy[2]; }; static true_t dispatch(U); static false_t dispatch(...); static const T &trigger(); public: static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); }; template< bool C , typename T1 , typename T2 > struct if_c { typedef T1 type; }; template< typename T1 , typename T2 > struct if_c { typedef T2 type; }; template< typename C , typename T1 , typename T2 > struct if_ { typedef typename if_c<0 != C::value, T1, T2>::type type; }; template< bool C , typename F1 , typename F2 > struct eval_if_c : if_c::type {}; template< typename C , typename T1 , typename T2 > struct eval_if : if_::type {}; // identity is an extension: it is not part of the standard. template struct identity { typedef T type; }; template struct is_unary_or_binary_function_impl { static const bool value = false; }; // see boost ticket #4094 // avoid duplicate definitions of is_unary_or_binary_function_impl template struct is_unary_or_binary_function_impl { static const bool value = true; }; template struct is_unary_or_binary_function_impl { static const bool value = true; }; // see boost ticket #4094 // avoid duplicate definitions of is_unary_or_binary_function_impl template struct is_unary_or_binary_function_impl { static const bool value = true; }; template struct is_unary_or_binary_function_impl { static const bool value = true; }; // see boost ticket #4094 // avoid duplicate definitions of is_unary_or_binary_function_impl template struct is_unary_or_binary_function_impl { static const bool value = true; }; template struct is_unary_or_binary_function_impl { static const bool value = true; }; template struct is_unary_or_binary_function_impl { static const bool value = false; }; template struct is_unary_or_binary_function { static const bool value = is_unary_or_binary_function_impl::value; }; //boost::alignment_of yields to 10K lines of preprocessed code, so we //need an alternative template struct alignment_of; template struct alignment_of_hack { char c; T t; alignment_of_hack(); }; template struct alignment_logic { static const std::size_t value = A < S ? A : S; }; template< typename T > struct alignment_of { static const std::size_t value = alignment_logic < sizeof(alignment_of_hack) - sizeof(T) , sizeof(T) >::value; }; template struct is_same { typedef char yes_type; struct no_type { char padding[8]; }; template static yes_type is_same_tester(V*, V*); static no_type is_same_tester(...); static T *t; static U *u; static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u)); }; template struct add_const { typedef const T type; }; template struct remove_const { typedef T type; }; template struct remove_const { typedef T type; }; template struct remove_reference { typedef T type; }; template struct remove_reference { typedef T type; }; template class is_empty_class { template struct empty_helper_t1 : public T { empty_helper_t1(); int i[256]; }; struct empty_helper_t2 { int i[256]; }; public: static const bool value = sizeof(empty_helper_t1) == sizeof(empty_helper_t2); }; template struct ls_zeros { static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value); }; template<> struct ls_zeros<0> { static const std::size_t value = 0; }; template<> struct ls_zeros<1> { static const std::size_t value = 0; }; } //namespace detail } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// namespace boost { namespace intrusive { namespace detail { template inline T* addressof(T& obj) { return static_cast (static_cast (const_cast (&reinterpret_cast(obj)) ) ); } template struct unvoid { typedef T type; }; template <> struct unvoid { struct type { }; }; template <> struct unvoid { struct type { }; }; template struct LowPriorityConversion { // Convertible from T with user-defined-conversion rank. LowPriorityConversion(const T&) { } }; // Infrastructure for providing a default type for T::TNAME if absent. }}} //namespace boost::intrusive::detail ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE // (C) Copyright John Maddock 2000. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/static_assert for documentation. /* Revision history: 02 August 2000 Initial version. */ // Copyright David Abrahams 2002. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Compiler/library version workaround macro // // Usage: // // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // // workaround for eVC4 and VC6 // ... // workaround code here // #endif // // When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the // first argument must be undefined or expand to a numeric // value. The above expands to: // // (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 // // When used for workarounds that apply to the latest known version // and all earlier versions of a compiler, the following convention // should be observed: // // #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) // // The version number in this case corresponds to the last version in // which the workaround was known to have been required. When // BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro // BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates // the workaround for any version of the compiler. When // BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or // error will be issued if the compiler version exceeds the argument // to BOOST_TESTED_AT(). This can be used to locate workarounds which // may be obsoleted by newer versions. // Always define to zero, if it's used it'll be defined my MPL: // ^ ^ ^ ^ // The extra level of parenthesis nesting above, along with the // BOOST_OPEN_PAREN indirection below, is required to satisfy the // broken preprocessor in MWCW 8.3 and earlier. // // The basic mechanism works as follows: // (symbol test) + 1 => if (symbol test) then 2 else 1 // 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 // // The complication with % is for cooperation with BOOST_TESTED_AT(). // When "test" is BOOST_TESTED_AT(x) and // BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, // // symbol test => if (symbol <= x) then 1 else -1 // (symbol test) + 1 => if (symbol <= x) then 2 else 0 // 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero // // // If the compiler issues warnings about old C style casts, // then enable this: // namespace boost{ // HP aCC cannot deal with missing names for template value parameters template struct STATIC_ASSERTION_FAILURE; template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; // HP aCC cannot deal with missing names for template value parameters template struct static_assert_test{}; } // // Implicit instantiation requires that all member declarations be // instantiated, but that the definitions are *not* instantiated. // // It's not particularly clear how this applies to enum's or typedefs; // both are described as declarations [7.1.3] and [7.2] in the standard, // however some compilers use "delayed evaluation" of one or more of // these when implicitly instantiating templates. We use typedef declarations // by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum // version gets better results from your compiler... // // Implementation: // Both of these versions rely on sizeof(incomplete_type) generating an error // message containing the name of the incomplete type. We use // "STATIC_ASSERTION_FAILURE" as the type name here to generate // an eye catching error message. The result of the sizeof expression is either // used as an enum initialiser, or as a template argument depending which version // is in use... // Note that the argument to the assert is explicitly cast to bool using old- // style casts: too many compilers currently have problems with static_cast // when used inside integral constant expressions. // // generic version // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Copyright 2001-2003 Aleksey Gurtovoy. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: lambda_support.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: lambda.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: ttp.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: msvc.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // BOOST_MSVC is defined here: // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: gcc.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: workaround.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: ctps.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION is defined in // agurt, 15/jan/02: full-fledged implementation requires both // template template parameters _and_ partial specialization // these are needed regardless of BOOST_TT_NO_BROKEN_COMPILER_SPEC // agurt, 27/jun/03: disable the workaround if user defined // BOOST_TT_NO_BROKEN_COMPILER_SPEC //BOOST_TT_BROKEN_COMPILER_SPEC(long double) // for backward compatibility // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // implementation helper: namespace boost { namespace detail { template struct cv_traits_imp {}; template struct cv_traits_imp { static const bool is_const = false; static const bool is_volatile = false; typedef T unqualified_type; }; template struct cv_traits_imp { static const bool is_const = true; static const bool is_volatile = false; typedef T unqualified_type; }; template struct cv_traits_imp { static const bool is_const = false; static const bool is_volatile = true; typedef T unqualified_type; }; template struct cv_traits_imp { static const bool is_const = true; static const bool is_volatile = true; typedef T unqualified_type; }; } // namespace detail } // namespace boost // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-04-25 08:26:48 -0400 (Mon, 25 Apr 2011) $ // $Revision: 71481 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: int.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: int_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: adl_barrier.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: adl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: intel.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // BOOST_INTEL_CXX_VERSION is defined here: // agurt, 25/apr/04: technically, the ADL workaround is only needed for GCC, // but putting everything expect public, user-specializable metafunctions into // a separate global namespace has a nice side effect of reducing the length // of template instantiation symbols, so we apply the workaround on all // platforms that can handle it namespace mpl_ { namespace aux {} } namespace boost { namespace mpl { using namespace mpl_; namespace aux { using namespace mpl_::aux; } }} // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: nttp_decl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: nttp.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // MSVC 6.5 ICE-s on the code as simple as this (see "aux_/nttp_decl.hpp" // for a workaround): // // namespace std { // template< typename Char > struct string; // } // // void foo(std::string); // // namespace boost { namespace mpl { // template< int > struct arg; // }} namespace mpl_ { template< int N > struct int_; } namespace boost { namespace mpl { using ::mpl_::int_; } } // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: integral_wrapper.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: integral_c_tag.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: static_constant.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // BOOST_STATIC_CONSTANT is defined here: namespace mpl_ { struct integral_c_tag { static const int value = 0; }; } namespace boost { namespace mpl { using ::mpl_::integral_c_tag; } } // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: static_cast.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace mpl_ { template< int N > struct int_ { static const int value = N; // agurt, 08/mar/03: SGI MIPSpro C++ workaround, have to #ifdef because some // other compilers (e.g. MSVC) are not particulary happy about it typedef int_ type; typedef int value_type; typedef integral_c_tag tag; // have to #ifdef here: some compilers don't like the 'N + 1' form (MSVC), // while some other don't like 'value + 1' (Borland), and some don't like // either typedef mpl_::int_< static_cast((value + 1)) > next; typedef mpl_::int_< static_cast((value - 1)) > prior; // enables uniform function call syntax for families of overloaded // functions that return objects of both arithmetic ('int', 'long', // 'double', etc.) and wrapped integral types (for an example, see // "mpl/example/power.cpp") operator int() const { return static_cast(this->value); } }; template< int N > int const mpl_::int_< N > ::value; } // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: template_arity_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace boost { namespace mpl { namespace aux { template< typename F > struct template_arity; }}} // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: params.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: preprocessor.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // BOOST_MPL_PP_PARAMS(0,T): // BOOST_MPL_PP_PARAMS(1,T): T1 // BOOST_MPL_PP_PARAMS(2,T): T1, T2 // BOOST_MPL_PP_PARAMS(n,T): T1, T2, .., Tn // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: overload_resolution.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace boost { namespace detail{ template struct rvalue_ref_filter_rem_cv { typedef typename boost::detail::cv_traits_imp::unqualified_type type; }; } // convert a type T to a non-cv-qualified type - remove_cv template< typename T > struct remove_cv { public: typedef typename boost::detail::rvalue_ref_filter_rem_cv ::type type; }; template< typename T > struct remove_cv { public: typedef T& type; }; template< typename T, std::size_t N > struct remove_cv { public: typedef T type[N]; }; template< typename T, std::size_t N > struct remove_cv { public: typedef T type[N]; }; template< typename T, std::size_t N > struct remove_cv { public: typedef T type[N]; }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $ // $Revision: 24874 $ //Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and //wrong SFINAE for GCC 4.2/4.3 namespace boost_intrusive_has_member_function_callable_with { struct dont_care { dont_care(...); }; struct private_type { static private_type p; private_type const &operator,(int) const; }; typedef char yes_type; // sizeof(yes_type) == 1 struct no_type{ char dummy[2]; }; // sizeof(no_type) == 2 template no_type is_private_type(T const &); yes_type is_private_type(private_type const &); } //boost_intrusive_has_member_function_callable_with ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template class has_member_function_named_pointer_to { struct BaseMixin { void pointer_to(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_pointer_to_impl; //! template struct has_member_function_callable_with_pointer_to_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). pointer_to (), 0))> struct zeroarg_checker_pointer_to { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_pointer_to(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_pointer_to { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_pointer_to(int); }; template struct has_member_function_callable_with_pointer_to_impl { template static zeroarg_checker_pointer_to Test(zeroarg_checker_pointer_to*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template struct funwrap1_pointer_to : Fun { funwrap1_pointer_to(); using Fun::pointer_to; boost_intrusive_has_member_function_callable_with::private_type pointer_to ( boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_pointer_to_impl { typedef funwrap1_pointer_to FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). pointer_to ( boost::move_detail::declval< P0 >() ), 0 ) ) ) ); }; }}} namespace boost { namespace intrusive { namespace detail { template struct has_member_function_callable_with_pointer_to : public has_member_function_callable_with_pointer_to_impl ::value , P0 > {}; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template class has_member_function_named_static_cast_from { struct BaseMixin { void static_cast_from(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_static_cast_from_impl; //! template struct has_member_function_callable_with_static_cast_from_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). static_cast_from (), 0))> struct zeroarg_checker_static_cast_from { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_static_cast_from(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_static_cast_from { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_static_cast_from(int); }; template struct has_member_function_callable_with_static_cast_from_impl { template static zeroarg_checker_static_cast_from Test(zeroarg_checker_static_cast_from*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template struct funwrap1_static_cast_from : Fun { funwrap1_static_cast_from(); using Fun::static_cast_from; boost_intrusive_has_member_function_callable_with::private_type static_cast_from ( boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_static_cast_from_impl { typedef funwrap1_static_cast_from FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). static_cast_from ( boost::move_detail::declval< P0 >() ), 0 ) ) ) ); }; }}} namespace boost { namespace intrusive { namespace detail { template struct has_member_function_callable_with_static_cast_from : public has_member_function_callable_with_static_cast_from_impl ::value , P0 > {}; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template class has_member_function_named_const_cast_from { struct BaseMixin { void const_cast_from(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_const_cast_from_impl; //! template struct has_member_function_callable_with_const_cast_from_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). const_cast_from (), 0))> struct zeroarg_checker_const_cast_from { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_const_cast_from(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_const_cast_from { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_const_cast_from(int); }; template struct has_member_function_callable_with_const_cast_from_impl { template static zeroarg_checker_const_cast_from Test(zeroarg_checker_const_cast_from*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template struct funwrap1_const_cast_from : Fun { funwrap1_const_cast_from(); using Fun::const_cast_from; boost_intrusive_has_member_function_callable_with::private_type const_cast_from ( boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_const_cast_from_impl { typedef funwrap1_const_cast_from FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). const_cast_from ( boost::move_detail::declval< P0 >() ), 0 ) ) ) ); }; }}} namespace boost { namespace intrusive { namespace detail { template struct has_member_function_callable_with_const_cast_from : public has_member_function_callable_with_const_cast_from_impl ::value , P0 > {}; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template class has_member_function_named_dynamic_cast_from { struct BaseMixin { void dynamic_cast_from(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_dynamic_cast_from_impl; //! template struct has_member_function_callable_with_dynamic_cast_from_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). dynamic_cast_from (), 0))> struct zeroarg_checker_dynamic_cast_from { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_dynamic_cast_from(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_dynamic_cast_from { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_dynamic_cast_from(int); }; template struct has_member_function_callable_with_dynamic_cast_from_impl { template static zeroarg_checker_dynamic_cast_from Test(zeroarg_checker_dynamic_cast_from*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace intrusive { namespace detail { template struct funwrap1_dynamic_cast_from : Fun { funwrap1_dynamic_cast_from(); using Fun::dynamic_cast_from; boost_intrusive_has_member_function_callable_with::private_type dynamic_cast_from ( boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_dynamic_cast_from_impl { typedef funwrap1_dynamic_cast_from FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). dynamic_cast_from ( boost::move_detail::declval< P0 >() ), 0 ) ) ) ); }; }}} namespace boost { namespace intrusive { namespace detail { template struct has_member_function_callable_with_dynamic_cast_from : public has_member_function_callable_with_dynamic_cast_from_impl ::value , P0 > {}; }}} namespace boost { namespace intrusive { namespace detail { template struct boost_intrusive_default_type_element_type { template static char test(int, typename X::element_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType element_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::element_type type; }; template struct boost_intrusive_eval_default_type_element_type { template static char test(int, typename X::element_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type element_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::element_type type; }; template struct boost_intrusive_default_type_difference_type { template static char test(int, typename X::difference_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType difference_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::difference_type type; }; template struct boost_intrusive_eval_default_type_difference_type { template static char test(int, typename X::difference_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type difference_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::difference_type type; }; ////////////////////// //struct first_param ////////////////////// template struct first_param { typedef void type; }; template < template class TemplateClass , typename T > struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2 , class P3> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2 , class P3 , class P4> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8> struct first_param < TemplateClass > { typedef T type; }; template < template class TemplateClass , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9> struct first_param < TemplateClass > { typedef T type; }; /////////////////////////// //struct type_rebind_mode /////////////////////////// template struct type_has_rebind { template static char test(int, typename X::template rebind*); template static int test(boost::intrusive::detail::LowPriorityConversion, void*); static const bool value = (1 == sizeof(test(0, 0))); }; template struct type_has_rebind_other { template static char test(int, typename X::template rebind::other*); template static int test(boost::intrusive::detail::LowPriorityConversion, void*); static const bool value = (1 == sizeof(test(0, 0))); }; template struct type_rebind_mode { template static char test(int, typename X::template rebind::other*); template static int test(boost::intrusive::detail::LowPriorityConversion, void*); static const unsigned int rebind = (unsigned int)type_has_rebind::value; static const unsigned int rebind_other = (unsigned int)type_has_rebind_other::value; static const unsigned int mode = rebind + rebind*rebind_other; }; //////////////////////// //struct type_rebinder //////////////////////// template ::mode> struct type_rebinder; // Implementation of pointer_traits::rebind if Ptr has // its own rebind::other type (C++03) template struct type_rebinder< Ptr, U, 2u > { typedef typename Ptr::template rebind::other type; }; // Implementation of pointer_traits::rebind if Ptr has // its own rebind template. template struct type_rebinder< Ptr, U, 1u > { typedef typename Ptr::template rebind type; }; // Specialization of pointer_traits::rebind if Ptr does not // have its own rebind template but has a the form Ptr, where OtherArgs comprises zero or more type parameters. // Many pointers fit this form, hence many pointers will get a // reasonable default for rebind. template < template class Ptr , typename T , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class P3 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; template < template class Ptr , typename T , class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 , class U> struct type_rebinder < Ptr, U, 0u > { typedef Ptr type; }; } //namespace detail { } //namespace intrusive { } //namespace boost { ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: bool.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: bool_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace mpl_ { template< bool C_ > struct bool_; // shorcuts typedef bool_ true_; typedef bool_ false_; } namespace boost { namespace mpl { using ::mpl_::bool_; } } namespace boost { namespace mpl { using ::mpl_::true_; } } namespace boost { namespace mpl { using ::mpl_::false_; } } namespace mpl_ { template< bool C_ > struct bool_ { static const bool value = C_; typedef integral_c_tag tag; typedef bool_ type; typedef bool value_type; operator bool() const { return this->value; } }; template< bool C_ > bool const bool_::value; } // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: integral_c.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: integral_c_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace mpl_ { template< typename T, T N > struct integral_c; } namespace boost { namespace mpl { using ::mpl_::integral_c; } } // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: integral_wrapper.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! namespace mpl_ { template< typename T, T N > struct integral_c { static const T value = N; // agurt, 08/mar/03: SGI MIPSpro C++ workaround, have to #ifdef because some // other compilers (e.g. MSVC) are not particulary happy about it typedef integral_c type; typedef T value_type; typedef integral_c_tag tag; // have to #ifdef here: some compilers don't like the 'N + 1' form (MSVC), // while some other don't like 'value + 1' (Borland), and some don't like // either typedef integral_c< T, static_cast((value + 1)) > next; typedef integral_c< T, static_cast((value - 1)) > prior; // enables uniform function call syntax for families of overloaded // functions that return objects of both arithmetic ('int', 'long', // 'double', etc.) and wrapped integral types (for an example, see // "mpl/example/power.cpp") operator T() const { return static_cast(this->value); } }; template< typename T, T N > T const integral_c< T, N > ::value; } namespace mpl_ { // 'bool' constant doesn't have 'next'/'prior' members template< bool C > struct integral_c { static const bool value = C; typedef integral_c_tag tag; typedef integral_c type; typedef bool value_type; operator bool() const { return this->value; } }; } namespace boost{ template struct integral_constant : public mpl::integral_c { typedef integral_constant type; }; template<> struct integral_constant : public mpl::true_ { typedef integral_constant type; }; template<> struct integral_constant : public mpl::false_ { typedef integral_constant type; }; typedef integral_constant true_type; typedef integral_constant false_type; } namespace boost { namespace intrusive { //! pointer_traits is the implementation of C++11 std::pointer_traits class with some //! extensions like castings. //! //! pointer_traits supplies a uniform interface to certain attributes of pointer-like types. template struct pointer_traits { typedef Ptr pointer; // typedef typename boost::intrusive::detail:: boost_intrusive_eval_default_type_element_type< Ptr, boost::intrusive::detail::first_param > ::type element_type; // typedef typename boost::intrusive::detail:: boost_intrusive_default_type_difference_type< Ptr, std::ptrdiff_t > ::type difference_type; // typedef typename boost::intrusive::detail::unvoid::type& reference; // template struct rebind_pointer { typedef typename boost::intrusive::detail::type_rebinder::type type; }; //! Remark: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise, //! it is element_type &. //! //! Returns: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(r). //! Non-standard extension: If such function does not exist, returns pointer(addressof(r)); static pointer pointer_to(reference r) { //Non-standard extension, it does not require Ptr::pointer_to. If not present //tries to converts &r to pointer. const bool value = boost::intrusive::detail:: has_member_function_callable_with_pointer_to ::type>::value; ::boost::integral_constant flag; return pointer_traits::priv_pointer_to(flag, r); } //! Remark: Non-standard extension. //! //! Returns: A dereferenceable pointer to r obtained by calling Ptr::static_cast_from(r). //! If such function does not exist, returns pointer_to(static_cast(*uptr)) template static pointer static_cast_from(const UPtr &uptr) { const bool value = boost::intrusive::detail:: has_member_function_callable_with_static_cast_from ::value; ::boost::integral_constant flag; return pointer_traits::priv_static_cast_from(flag, uptr); } //! Remark: Non-standard extension. //! //! Returns: A dereferenceable pointer to r obtained by calling Ptr::const_cast_from(r). //! If such function does not exist, returns pointer_to(const_cast(*uptr)) template static pointer const_cast_from(const UPtr &uptr) { const bool value = boost::intrusive::detail:: has_member_function_callable_with_const_cast_from ::value; ::boost::integral_constant flag; return pointer_traits::priv_const_cast_from(flag, uptr); } //! Remark: Non-standard extension. //! //! Returns: A dereferenceable pointer to r obtained by calling Ptr::dynamic_cast_from(r). //! If such function does not exist, returns pointer_to(*dynamic_cast(&*uptr)) template static pointer dynamic_cast_from(const UPtr &uptr) { const bool value = boost::intrusive::detail:: has_member_function_callable_with_dynamic_cast_from ::value; ::boost::integral_constant flag; return pointer_traits::priv_dynamic_cast_from(flag, uptr); } ///@cond private: //priv_to_raw_pointer template static T* to_raw_pointer(T* p) { return p; } template static typename pointer_traits::element_type* to_raw_pointer(const Pointer &p) { return pointer_traits::to_raw_pointer(p.operator->()); } //priv_pointer_to static pointer priv_pointer_to(boost::true_type, typename boost::intrusive::detail::unvoid::type& r) { return Ptr::pointer_to(r); } static pointer priv_pointer_to(boost::false_type, typename boost::intrusive::detail::unvoid::type& r) { return pointer(boost::intrusive::detail::addressof(r)); } //priv_static_cast_from template static pointer priv_static_cast_from(boost::true_type, const UPtr &uptr) { return Ptr::static_cast_from(uptr); } template static pointer priv_static_cast_from(boost::false_type, const UPtr &uptr) { return pointer_to(static_cast(*uptr)); } //priv_const_cast_from template static pointer priv_const_cast_from(boost::true_type, const UPtr &uptr) { return Ptr::const_cast_from(uptr); } template static pointer priv_const_cast_from(boost::false_type, const UPtr &uptr) { return pointer_to(const_cast(*uptr)); } //priv_dynamic_cast_from template static pointer priv_dynamic_cast_from(boost::true_type, const UPtr &uptr) { return Ptr::dynamic_cast_from(uptr); } template static pointer priv_dynamic_cast_from(boost::false_type, const UPtr &uptr) { return pointer_to(*dynamic_cast(&*uptr)); } ///@endcond }; ///@cond // Remove cv qualification from Ptr parameter to pointer_traits: template struct pointer_traits : pointer_traits {}; template struct pointer_traits : pointer_traits { }; template struct pointer_traits : pointer_traits { }; // Remove reference from Ptr parameter to pointer_traits: template struct pointer_traits : pointer_traits { }; ///@endcond //! Specialization of pointer_traits for raw pointers //! template struct pointer_traits { typedef T element_type; typedef T* pointer; typedef std::ptrdiff_t difference_type; typedef typename boost::intrusive::detail::unvoid::type& reference; template struct rebind_pointer { typedef U* type; }; //! Returns: addressof(r) //! static pointer pointer_to(reference r) { return boost::intrusive::detail::addressof(r); } //! Returns: static_cast(uptr) //! template static pointer static_cast_from(U *uptr) { return static_cast(uptr); } //! Returns: const_cast(uptr) //! template static pointer const_cast_from(U *uptr) { return const_cast(uptr); } //! Returns: dynamic_cast(uptr) //! template static pointer dynamic_cast_from(U *uptr) { return dynamic_cast(uptr); } }; } //namespace container { } //namespace boost { ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // // whenever we have a conversion function with elipses // it needs to be declared __cdecl to suppress compiler // warnings from MS and Borland compilers (this *must* // appear before we include is_same.hpp below): // // Define BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING // when we can't test for function types with elipsis: // // // define BOOST_TT_TEST_MS_FUNC_SIGS // when we want to test __stdcall etc function types with is_function etc // (Note, does not work with Borland, even though it does support __stdcall etc): // // // define BOOST_TT_NO_CV_FUNC_TEST // if tests for cv-qualified member functions don't // work in is_member_function_pointer // // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // // Helper macros for builtin compiler support. // If your compiler has builtin support for any of the following // traits concepts, then redefine the appropriate macros to pick // up on the compiler support: // // (these should largely ignore cv-qualifiers) // BOOST_IS_UNION(T) should evaluate to true if T is a union type // BOOST_IS_POD(T) should evaluate to true if T is a POD type // BOOST_IS_EMPTY(T) should evaluate to true if T is an empty class type (and not a union) // BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect // BOOST_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy // BOOST_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy // BOOST_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect // BOOST_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw // BOOST_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw // BOOST_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw // BOOST_HAS_VIRTUAL_DESTRUCTOR(T) should evaluate to true T has a virtual destructor // // The following can also be defined: when detected our implementation is greatly simplified. // // BOOST_IS_ABSTRACT(T) true if T is an abstract type // BOOST_IS_BASE_OF(T,U) true if T is a base class of U // BOOST_IS_CLASS(T) true if T is a class type (and not a union) // BOOST_IS_CONVERTIBLE(T,U) true if T is convertible to U // BOOST_IS_ENUM(T) true is T is an enum // BOOST_IS_POLYMORPHIC(T) true if T is a polymorphic type // BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T. // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { //* is a type T void - is_void template< typename T > struct is_void : public ::boost::integral_constant { public: }; template< > struct is_void< void > : public ::boost::integral_constant { public: }; template< > struct is_void< void const > : public ::boost::integral_constant { public: }; template< > struct is_void< void volatile > : public ::boost::integral_constant { public: }; template< > struct is_void< void const volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { //* is a type T an [cv-qualified-] integral type described in the standard (3.9.1p3) // as an extention we include long long, as this is likely to be added to the // standard at a later date template< typename T > struct is_integral : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned char > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned char const > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned char volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned char const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned short > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned short const > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned short volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned short const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned int > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned int const > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned int volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned int const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned long > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned long const > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned long volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< unsigned long const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed char > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed char const > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed char volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed char const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed short > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed short const > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed short volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed short const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed int > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed int const > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed int volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed int const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed long > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed long const > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed long volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< signed long const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< bool > : public ::boost::integral_constant { public: }; template< > struct is_integral< bool const > : public ::boost::integral_constant { public: }; template< > struct is_integral< bool volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< bool const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< char > : public ::boost::integral_constant { public: }; template< > struct is_integral< char const > : public ::boost::integral_constant { public: }; template< > struct is_integral< char volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< char const volatile > : public ::boost::integral_constant { public: }; // If the following line fails to compile and you're using the Intel // compiler, see http://lists.boost.org/MailArchives/boost-users/msg06567.php, // and define BOOST_NO_INTRINSIC_WCHAR_T on the command line. template< > struct is_integral< wchar_t > : public ::boost::integral_constant { public: }; template< > struct is_integral< wchar_t const > : public ::boost::integral_constant { public: }; template< > struct is_integral< wchar_t volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< wchar_t const volatile > : public ::boost::integral_constant { public: }; // Same set of integral types as in boost/type_traits/integral_promotion.hpp. // Please, keep in sync. -- Alexander Nasonov template< > struct is_integral< ::boost::ulong_long_type > : public ::boost::integral_constant { public: }; template< > struct is_integral< ::boost::ulong_long_type const > : public ::boost::integral_constant { public: }; template< > struct is_integral< ::boost::ulong_long_type volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< ::boost::ulong_long_type const volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< ::boost::long_long_type > : public ::boost::integral_constant { public: }; template< > struct is_integral< ::boost::long_long_type const > : public ::boost::integral_constant { public: }; template< > struct is_integral< ::boost::long_long_type volatile > : public ::boost::integral_constant { public: }; template< > struct is_integral< ::boost::long_long_type const volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { //* is a type T a floating-point type described in the standard (3.9.1p8) template< typename T > struct is_float : public ::boost::integral_constant { public: }; template< > struct is_float< float > : public ::boost::integral_constant { public: }; template< > struct is_float< float const > : public ::boost::integral_constant { public: }; template< > struct is_float< float volatile > : public ::boost::integral_constant { public: }; template< > struct is_float< float const volatile > : public ::boost::integral_constant { public: }; template< > struct is_float< double > : public ::boost::integral_constant { public: }; template< > struct is_float< double const > : public ::boost::integral_constant { public: }; template< > struct is_float< double volatile > : public ::boost::integral_constant { public: }; template< > struct is_float< double const volatile > : public ::boost::integral_constant { public: }; template< > struct is_float< long double > : public ::boost::integral_constant { public: }; template< > struct is_float< long double const > : public ::boost::integral_constant { public: }; template< > struct is_float< long double volatile > : public ::boost::integral_constant { public: }; template< > struct is_float< long double const volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright John Maddock and Steve Cleary 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. namespace boost { namespace type_traits { template struct ice_or; template struct ice_or { static const bool value = true; }; template <> struct ice_or { static const bool value = false; }; } // namespace type_traits } // namespace boost // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template< typename T > struct is_arithmetic_impl { static const bool value = (::boost::type_traits::ice_or< ::boost::is_integral ::value, ::boost::is_float ::value > ::value); }; } // namespace detail //* is a type T an arithmetic type described in the standard (3.9.1p8) template< typename T > struct is_arithmetic : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000, 2010. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_lvalue_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { template< typename T > struct is_lvalue_reference : public ::boost::integral_constant { public: }; template< typename T > struct is_lvalue_reference< T& > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) John Maddock 2010. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { template< typename T > struct is_rvalue_reference : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright John Maddock and Steve Cleary 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // // macros and helpers for working with integral-constant-expressions. // (C) Copyright John Maddock and Steve Cleary 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // // macros and helpers for working with integral-constant-expressions. namespace boost { namespace type_traits { typedef char yes_type; struct no_type { char padding[8]; }; } // namespace type_traits } // namespace boost // (C) Copyright John Maddock and Steve Cleary 2000. // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. namespace boost { namespace type_traits { template struct ice_and; template struct ice_and { static const bool value = false; }; template <> struct ice_and { static const bool value = true; }; } // namespace type_traits } // namespace boost // (C) Copyright John Maddock and Steve Cleary 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. namespace boost { namespace type_traits { template struct ice_not { static const bool value = true; }; template <> struct ice_not { static const bool value = false; }; } // namespace type_traits } // namespace boost // (C) Copyright John Maddock and Steve Cleary 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. namespace boost { namespace type_traits { template struct ice_eq { static const bool value = (b1 == b2); }; template struct ice_ne { static const bool value = (b1 != b2); }; template bool const ice_eq::value; template bool const ice_ne::value; } // namespace type_traits } // namespace boost // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct is_reference_impl { static const bool value = (::boost::type_traits::ice_or< ::boost::is_lvalue_reference ::value, ::boost::is_rvalue_reference ::value > ::value); }; } // namespace detail template< typename T > struct is_reference : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-04-25 08:26:48 -0400 (Mon, 25 Apr 2011) $ // $Revision: 71481 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) namespace boost { namespace detail { // // We can't filter out rvalue_references at the same level as // references or we get ambiguities from msvc: // template struct add_reference_rvalue_layer { typedef T& type; }; template struct add_reference_impl { typedef typename add_reference_rvalue_layer::type type; }; template< typename T > struct add_reference_impl { public: typedef T& type; }; // these full specialisations are always required: template< > struct add_reference_impl { public: typedef void type; }; template< > struct add_reference_impl { public: typedef void const type; }; template< > struct add_reference_impl { public: typedef void volatile type; }; template< > struct add_reference_impl { public: typedef void const volatile type; }; } // namespace detail template< typename T > struct add_reference { public: typedef typename boost::detail::add_reference_impl ::type type; }; // agurt, 07/mar/03: workaround Borland's ill-formed sensitivity to an additional // level of indirection, here } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $ // $Revision: 24874 $ // Copyright 2000 John Maddock (john@johnmaddock.co.uk) // Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu) // Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Some fixes for is_array are based on a newgroup posting by Jonathan Lundquist. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { template< typename T > struct is_array : public ::boost::integral_constant { public: }; template< typename T, std::size_t N > struct is_array< T[N] > : public ::boost::integral_constant { public: }; template< typename T, std::size_t N > struct is_array< T const[N] > : public ::boost::integral_constant { public: }; template< typename T, std::size_t N > struct is_array< T volatile[N] > : public ::boost::integral_constant { public: }; template< typename T, std::size_t N > struct is_array< T const volatile[N] > : public ::boost::integral_constant { public: }; template< typename T > struct is_array< T[] > : public ::boost::integral_constant { public: }; template< typename T > struct is_array< T const[] > : public ::boost::integral_constant { public: }; template< typename T > struct is_array< T volatile[] > : public ::boost::integral_constant { public: }; template< typename T > struct is_array< T const volatile[] > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // is_abstract_class.hpp: // // (C) Copyright 2002 Rani Sharoni (rani_sharoni@hotmail.com) and Robert Ramey // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org for updates, documentation, and revision history. // // Compile type discovery whether given type is abstract class or not. // // Requires DR 337 to be supported by compiler // (http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#337). // // // Believed (Jan 2004) to work on: // - GCC 3.4 // - VC++ 7.1 // - compilers with new EDG frontend (Intel C++ 7, Comeau 4.3.2) // // Doesn't work on: // - VC++6, VC++7.0 and less // - GCC 3.3.X and less // - Borland C++ 6 and less // // // History: // - Originally written by Rani Sharoni, see // http://groups.google.com/groups?selm=df893da6.0207110613.75b2fe90%40posting.google.com // At this time supported by EDG (Intel C++ 7, Comeau 4.3.2) and VC7.1. // - Adapted and added into Boost.Serialization library by Robert Ramey // (starting with submission #10). // - Jan 2004: GCC 3.4 fixed to suport DR337 (Giovanni Bajo). // - Jan 2004: modified to be part of Boost.TypeTraits (Pavel Vozenilek). // - Nov 2004: Christoph Ludwig found that the implementation did not work with // template types and gcc-3.4 or VC7.1, fix due to Christoph Ludwig // and John Maddock. // - Dec 2004: Added new config macro BOOST_NO_IS_ABSTRACT which causes the template // to degrade gracefully, rather than trash the compiler (John Maddock). // // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000-2003. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { // // using remove_cv here generates a whole load of needless // warnings with gcc, since it doesn't do any good with gcc // in any case (at least at present), just remove it: // template struct is_union_impl { static const bool value = false; }; } // namespace detail template< typename T > struct is_union : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { // This is actually the conforming implementation which works with // abstract classes. However, enough compilers have trouble with // it that most will use the one in // boost/type_traits/object_traits.hpp. This implementation // actually works with VC7.0, but other interactions seem to fail // when we use it. // is_class<> metafunction due to Paul Mensonides // (leavings@attbi.com). For more details: // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 template struct is_class_impl { template static ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); template static ::boost::type_traits::no_type is_class_tester(...); static const bool value = (::boost::type_traits::ice_and< sizeof(is_class_tester(0)) == sizeof(::boost::type_traits::yes_type), ::boost::type_traits::ice_not< ::boost::is_union ::value > ::value > ::value); }; } // namespace detail template< typename T > struct is_class : public ::boost::integral_constant ::type> ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail{ template struct is_abstract_imp2 { // Deduction fails if T is void, function type, // reference type (14.8.2/2)or an abstract class type // according to review status issue #337 // template static type_traits::no_type check_sig(U (*)[1]); template static type_traits::yes_type check_sig(...); // // T must be a complete type, further if T is a template then // it must be instantiated in order for us to get the right answer: // typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)(sizeof(T) != 0) >)> boost_static_assert_typedef_90; // GCC2 won't even parse this template if we embed the computation // of s1 in the computation of value. static const std::size_t s1 = sizeof(is_abstract_imp2 ::template check_sig(0)); static const bool value = (s1 == sizeof(type_traits::yes_type)); }; template struct is_abstract_select { template struct rebind { typedef is_abstract_imp2 type; }; }; template <> struct is_abstract_select { template struct rebind { typedef false_type type; }; }; template struct is_abstract_imp { typedef is_abstract_select< ::boost::is_class::value> selector; typedef typename selector::template rebind binder; typedef typename binder::type type; static const bool value = type::value; }; } template< typename T > struct is_abstract : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // add_rvalue_reference.hpp ---------------------------------------------------------// // Copyright 2010 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt //----------------------------------------------------------------------------// // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-04-25 08:26:48 -0400 (Mon, 25 Apr 2011) $ // $Revision: 71481 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //----------------------------------------------------------------------------// // // // C++03 implementation of // // 20.7.6.2 Reference modifications [meta.trans.ref] // // Written by Vicente J. Botet Escriba // // // // If T names an object or function type then the member typedef type // shall name T&&; otherwise, type shall name T. [ Note: This rule reflects // the semantics of reference collapsing. For example, when a type T names // a type T1&, the type add_rvalue_reference::type is not an rvalue // reference. -end note ] //----------------------------------------------------------------------------// namespace boost { namespace type_traits_detail { template struct add_rvalue_reference_helper { typedef T type; }; template struct add_rvalue_reference_imp { typedef typename boost::type_traits_detail::add_rvalue_reference_helper ::value && !is_reference::value) >::type type; }; } template< typename T > struct add_rvalue_reference { public: typedef typename boost::type_traits_detail::add_rvalue_reference_imp ::type type; }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $ // $Revision: 24874 $ // should be always the last #include directive // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { // is one type convertable to another? // // there are multiple versions of the is_convertible // template, almost every compiler seems to require its // own version. // // Thanks to Andrei Alexandrescu for the original version of the // conversion detection technique! // namespace detail { // MS specific version: // special version for gcc compiler + recent Borland versions // note that this does not pass UDT's through (...) struct any_conversion { template any_conversion(const volatile T&); template any_conversion(T&); }; template struct checker { static boost::type_traits::no_type _m_check(any_conversion ...); static boost::type_traits::yes_type _m_check(T, int); }; template struct is_convertible_basic_impl { static typename add_rvalue_reference::type _m_from; static bool const value = sizeof( boost::detail::checker::_m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type); }; template struct is_convertible_impl { typedef typename add_reference::type ref_type; static const bool value = (::boost::type_traits::ice_and< ::boost::type_traits::ice_or< ::boost::detail::is_convertible_basic_impl ::value, ::boost::is_void ::value > ::value, ::boost::type_traits::ice_not< ::boost::is_array ::value > ::value > ::value); }; template struct is_convertible_impl_select { template struct rebind { typedef is_convertible_impl type; }; }; template <> struct is_convertible_impl_select { template struct rebind { typedef true_type type; }; }; template <> struct is_convertible_impl_select { template struct rebind { typedef false_type type; }; }; template <> struct is_convertible_impl_select { template struct rebind { typedef false_type type; }; }; template struct is_convertible_impl_dispatch_base { typedef is_convertible_impl_select< ::boost::is_arithmetic::value, ::boost::is_arithmetic::value, ::boost::is_abstract::value > selector; typedef typename selector::template rebind isc_binder; typedef typename isc_binder::type type; }; template struct is_convertible_impl_dispatch : public is_convertible_impl_dispatch_base::type {}; // // Now add the full and partial specialisations // for void types, these are common to all the // implementation above: // template< > struct is_convertible_impl< void,void > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void,void const > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void,void volatile > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void,void const volatile > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const,void > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const,void const > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const,void volatile > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const,void const volatile > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void volatile,void > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void volatile,void const > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void volatile,void volatile > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void volatile,void const volatile > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const volatile,void > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const volatile,void const > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const volatile,void volatile > { public: static const bool value = (true); }; template< > struct is_convertible_impl< void const volatile,void const volatile > { public: static const bool value = (true); }; template< typename To > struct is_convertible_impl< void,To > { public: static const bool value = (false); }; template< typename From > struct is_convertible_impl< From,void > { public: static const bool value = (false); }; template< typename To > struct is_convertible_impl< void const,To > { public: static const bool value = (false); }; template< typename To > struct is_convertible_impl< void volatile,To > { public: static const bool value = (false); }; template< typename To > struct is_convertible_impl< void const volatile,To > { public: static const bool value = (false); }; template< typename From > struct is_convertible_impl< From,void const > { public: static const bool value = (false); }; template< typename From > struct is_convertible_impl< From,void volatile > { public: static const bool value = (false); }; template< typename From > struct is_convertible_impl< From,void const volatile > { public: static const bool value = (false); }; } // namespace detail template< typename From, typename To > struct is_convertible : public ::boost::integral_constant ::value)> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // Copyright 2000 John Maddock (john@johnmaddock.co.uk) // Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com) // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Copyright David Abrahams 2002. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. namespace boost { namespace type_traits { // Utility class which always "returns" false struct false_result { template struct result_ { static const bool value = false; }; }; }} // namespace boost::type_traits // Copyright 2000 John Maddock (john@johnmaddock.co.uk) // Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com) // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. ///// header body namespace boost { namespace type_traits { template struct is_function_ptr_helper { static const bool value = false; }; // preprocessor-generated part, don't edit by hand! template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; template struct is_function_ptr_helper { static const bool value = true; }; } // namespace type_traits } // namespace boost ///// iteration // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // // is a type a function? // Please note that this implementation is unnecessarily complex: // we could just use !is_convertible::value, // except that some compilers erroneously allow conversions from // function pointers to void*. namespace boost { namespace detail { template struct is_function_chooser : public ::boost::type_traits::false_result { }; template <> struct is_function_chooser { template< typename T > struct result_ : public ::boost::type_traits::is_function_ptr_helper { }; }; template struct is_function_impl : public is_function_chooser< ::boost::is_reference::value > ::template result_ { }; } // namespace detail template< typename T > struct is_function : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct is_class_or_union { static const bool value = (::boost::type_traits::ice_or< ::boost::is_class ::value , ::boost::is_union ::value > ::value); }; struct int_convertible { int_convertible(int); }; // Don't evaluate convertibility to int_convertible unless the type // is non-arithmetic. This suppresses warnings with GCC. template struct is_enum_helper { template struct type { static const bool value = false; }; }; template <> struct is_enum_helper { template struct type : public ::boost::is_convertible::type,::boost::detail::int_convertible> { }; }; template struct is_enum_impl { //typedef ::boost::add_reference ar_t; //typedef typename ar_t::type r_type; // We MUST check for is_class_or_union on conforming compilers in // order to correctly deduce that noncopyable types are not enums // (dwa 2002/04/15)... static const bool selector = (::boost::type_traits::ice_or< ::boost::is_arithmetic ::value , ::boost::is_reference ::value , ::boost::is_function ::value , is_class_or_union ::value , is_array ::value > ::value); typedef ::boost::detail::is_enum_helper se_t; typedef typename se_t::template type helper; static const bool value = helper::value; }; // these help on compilers with no partial specialization support: template< > struct is_enum_impl< void > { public: static const bool value = (false); }; template< > struct is_enum_impl< void const > { public: static const bool value = (false); }; template< > struct is_enum_impl< void volatile > { public: static const bool value = (false); }; template< > struct is_enum_impl< void const volatile > { public: static const bool value = (false); }; } // namespace detail template< typename T > struct is_enum : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // // Note: we use the "workaround" version for MSVC because it works for // __stdcall etc function types, where as the partial specialisation // version does not do so. // // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. ///// header body namespace boost { namespace type_traits { template struct is_mem_fun_pointer_impl { static const bool value = false; }; // pre-processed code, don't edit, try GNU cpp with // cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; template struct is_mem_fun_pointer_impl { static const bool value = true; }; } // namespace type_traits } // namespace boost ///// iteration // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { template< typename T > struct is_member_function_pointer : public ::boost::integral_constant ::type> ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { template< typename T > struct is_member_pointer : public ::boost::integral_constant ::value> { public: }; template< typename T, typename U > struct is_member_pointer< U T:: * > : public ::boost::integral_constant { public: }; template< typename T, typename U > struct is_member_pointer< U T:: *const > : public ::boost::integral_constant { public: }; template< typename T, typename U > struct is_member_pointer< U T:: *volatile > : public ::boost::integral_constant { public: }; template< typename T, typename U > struct is_member_pointer< U T:: *const volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template< typename T > struct is_pointer_helper { static const bool value = false; }; template< typename T > struct is_pointer_helper { static const bool value = true; }; template< typename T > struct is_pointer_impl { static const bool value = (::boost::type_traits::ice_and< ::boost::detail::is_pointer_helper ::type> ::value , ::boost::type_traits::ice_not< ::boost::is_member_pointer ::value > ::value > ::value); }; } // namespace detail template< typename T > struct is_pointer : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct is_scalar_impl { static const bool value = (::boost::type_traits::ice_or< ::boost::is_arithmetic ::value, ::boost::is_enum ::value, ::boost::is_pointer ::value, ::boost::is_member_pointer ::value > ::value); }; // these specializations are only really needed for compilers // without partial specialization support: template <> struct is_scalar_impl{ static const bool value = false; }; template <> struct is_scalar_impl{ static const bool value = false; }; template <> struct is_scalar_impl{ static const bool value = false; }; template <> struct is_scalar_impl{ static const bool value = false; }; } // namespace detail template< typename T > struct is_scalar : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { // forward declaration, needed by 'is_pod_array_helper' template below template< typename T > struct is_POD; namespace detail { template struct is_pod_impl { static const bool value = (::boost::type_traits::ice_or< ::boost::is_scalar ::value, ::boost::is_void ::value, false > ::value); }; template struct is_pod_impl : public is_pod_impl { }; // the following help compilers without partial specialization support: template< > struct is_pod_impl< void > { public: static const bool value = (true); }; template< > struct is_pod_impl< void const > { public: static const bool value = (true); }; template< > struct is_pod_impl< void volatile > { public: static const bool value = (true); }; template< > struct is_pod_impl< void const volatile > { public: static const bool value = (true); }; } // namespace detail template< typename T > struct is_POD : public ::boost::integral_constant ::value> { public: }; template< typename T > struct is_pod : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct has_trivial_dtor_impl { static const bool value = ::boost::is_pod ::value; }; } // namespace detail template< typename T > struct has_trivial_destructor : public ::boost::integral_constant ::value> { public: }; template< > struct has_trivial_destructor< void > : public ::boost::integral_constant { public: }; template< > struct has_trivial_destructor< void const > : public ::boost::integral_constant { public: }; template< > struct has_trivial_destructor< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_trivial_destructor< void volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ //---------------------------------------------------------------------- // (C) Copyright 2004 Pavel Vozenilek. // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // // // This file contains helper macros used when exception support may be // disabled (as indicated by macro BOOST_NO_EXCEPTIONS). // // Before picking up these macros you may consider using RAII techniques // to deal with exceptions - their syntax can be always the same with // or without exception support enabled. // /* Example of use: void foo() { BOOST_TRY { ... } BOOST_CATCH(const std::bad_alloc&) { ... BOOST_RETHROW } BOOST_CATCH(const std::exception& e) { ... } BOOST_CATCH_END } With exception support enabled it will expand into: void foo() { { try { ... } catch (const std::bad_alloc&) { ... throw; } catch (const std::exception& e) { ... } } } With exception support disabled it will expand into: void foo() { { if(true) { ... } else if (false) { ... } else if (false) { ... } } } */ //---------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// // // boost/assert.hpp - BOOST_ASSERT(expr) // BOOST_ASSERT_MSG(expr, msg) // BOOST_VERIFY(expr) // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2007 Peter Dimov // Copyright (c) Beman Dawes 2011 // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Note: There are no include guards. This is intentional. // // See http://www.boost.org/libs/utility/assert.html for documentation. // // // Stop inspect complaining about use of 'assert': // // boostinspect:naassert_macro // //--------------------------------------------------------------------------------------// // BOOST_ASSERT // //--------------------------------------------------------------------------------------// /*****************************************************************************/ /* assert.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ //---------------------------------------------------------------------------- // IS RECOMMENDED OVER . IS PROVIDED FOR // COMPATIBILITY WITH C AND THIS USAGE IS DEPRECATED IN C++ //---------------------------------------------------------------------------- extern "C" namespace std { /* this #ifndef can go away when C2000 uses extern C builtins */ extern void _nassert(int); extern void _assert(int, const char *); extern void _abort_msg(const char *); } /* extern "C" namespace std */ using std::_nassert; //--------------------------------------------------------------------------------------// // BOOST_ASSERT_MSG // //--------------------------------------------------------------------------------------// // iostream standard header namespace std { // OBJECTS static far ios_base::Init _Ios_init; // force initialization of byte streams extern far istream cin; extern far ostream cout; extern far ostream cerr; extern far ostream clog; // CLASS _Winit class _Winit { // controller for wide standard-stream initialization public: _Winit(); ~_Winit(); private: static far int _Init_cnt; }; // WIDE OBJECTS static far _Winit _Wios_init; // force initialization of wide streams extern far wistream wcin; extern far wostream wcout, wcerr, wclog; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // MS compatible compilers support #pragma once // // boost/current_function.hpp - BOOST_CURRENT_FUNCTION // // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // http://www.boost.org/libs/utility/current_function.html // namespace boost { namespace detail { inline void current_function_helper() { } } // namespace detail } // namespace boost // IDE's like Visual Studio perform better if output goes to std::cout or // some other stream, so allow user to configure output stream: namespace boost { namespace assertion { namespace detail { inline void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line) { std::cerr << "***** Internal Program Error - assertion (" << expr << ") failed in " << function << ":\n" << file << '(' << line << "): " << msg << std::endl; std::abort(); } } // detail } // assertion } // detail //--------------------------------------------------------------------------------------// // BOOST_VERIFY // //--------------------------------------------------------------------------------------// // // boost/assert.hpp - BOOST_ASSERT(expr) // BOOST_ASSERT_MSG(expr, msg) // BOOST_VERIFY(expr) // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2007 Peter Dimov // Copyright (c) Beman Dawes 2011 // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Note: There are no include guards. This is intentional. // // See http://www.boost.org/libs/utility/assert.html for documentation. // // // Stop inspect complaining about use of 'assert': // // boostinspect:naassert_macro // //--------------------------------------------------------------------------------------// // BOOST_ASSERT // //--------------------------------------------------------------------------------------// /*****************************************************************************/ /* assert.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ using std::_nassert; //--------------------------------------------------------------------------------------// // BOOST_ASSERT_MSG // //--------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------// // BOOST_VERIFY // //--------------------------------------------------------------------------------------// // // boost/assert.hpp - BOOST_ASSERT(expr) // BOOST_ASSERT_MSG(expr, msg) // BOOST_VERIFY(expr) // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2007 Peter Dimov // Copyright (c) Beman Dawes 2011 // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Note: There are no include guards. This is intentional. // // See http://www.boost.org/libs/utility/assert.html for documentation. // // // Stop inspect complaining about use of 'assert': // // boostinspect:naassert_macro // //--------------------------------------------------------------------------------------// // BOOST_ASSERT // //--------------------------------------------------------------------------------------// /*****************************************************************************/ /* assert.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ using std::_nassert; //--------------------------------------------------------------------------------------// // BOOST_ASSERT_MSG // //--------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------// // BOOST_VERIFY // //--------------------------------------------------------------------------------------// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2007-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// namespace boost { namespace intrusive { //!This enumeration defines the type of value_traits that can be defined //!for Boost.Intrusive containers enum link_mode_type{ //!If this linking policy is specified in a value_traits class //!as the link_mode, containers //!configured with such value_traits won't set the hooks //!of the erased values to a default state. Containers also won't //!check that the hooks of the new values are default initialized. normal_link, //!If this linking policy is specified in a value_traits class //!as the link_mode, containers //!configured with such value_traits will set the hooks //!of the erased values to a default state. Containers also will //!check that the hooks of the new values are default initialized. safe_link, //!Same as "safe_link" but the user type is an auto-unlink //!type, so the containers with constant-time size features won't be //!compatible with value_traits configured with this policy. //!Containers also know that the a value can be silently erased from //!the container without using any function provided by the containers. auto_unlink }; } //namespace intrusive } //namespace boost /// @cond namespace boost { namespace intrusive { struct none; } //namespace intrusive{ } //namespace boost{ namespace boost { namespace intrusive { //////////////////////////// // Node algorithms //////////////////////////// //Algorithms predeclarations template class circular_list_algorithms; template class circular_slist_algorithms; template class rbtree_algorithms; //////////////////////////// // Containers //////////////////////////// //slist template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none , class O5 = none > class slist; template < class O1 = none , class O2 = none , class O3 = none > class slist_base_hook; template < class O1 = none , class O2 = none , class O3 = none > class slist_member_hook; //list template < class T , class O1 = none , class O2 = none , class O3 = none > class list; template < class O1 = none , class O2 = none , class O3 = none > class list_base_hook; template < class O1 = none , class O2 = none , class O3 = none > class list_member_hook; template < class O1 = none , class O2 = none , class O3 = none > class list_hook; //rbtree/set/multiset template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class rbtree; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class set; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class multiset; template < class O1 = none , class O2 = none , class O3 = none , class O4 = none > class set_base_hook; template < class O1 = none , class O2 = none , class O3 = none , class O4 = none > class set_member_hook; //splaytree/splay_set/splay_multiset template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class splaytree; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class splay_set; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class splay_multiset; template < class O1 = none , class O2 = none , class O3 = none > class splay_set_base_hook; template < class O1 = none , class O2 = none , class O3 = none > class splay_set_member_hook; //avltree/avl_set/avl_multiset template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class avltree; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class avl_set; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class avl_multiset; template < class O1 = none , class O2 = none , class O3 = none , class O4 = none > class avl_set_base_hook; template < class O1 = none , class O2 = none , class O3 = none , class O4 = none > class avl_set_member_hook; //treap/treap_set/treap_multiset template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class treap; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class treap_set; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class treap_multiset; //Default priority comparison functor template struct priority_compare; //sgtree/sg_set/sg_multiset template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class sgtree; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class sg_set; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none > class sg_multiset; template < class O1 = none , class O2 = none , class O3 = none > class bs_set_base_hook; template < class O1 = none , class O2 = none , class O3 = none > class bs_set_member_hook; //hashtable/unordered_set/unordered_multiset template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none , class O5 = none , class O6 = none , class O7 = none , class O8 = none , class O9 = none , class O10 = none > class hashtable; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none , class O5 = none , class O6 = none , class O7 = none , class O8 = none , class O9 = none , class O10 = none > class unordered_set; template < class T , class O1 = none , class O2 = none , class O3 = none , class O4 = none , class O5 = none , class O6 = none , class O7 = none , class O8 = none , class O9 = none , class O10 = none > class unordered_multiset; template < class O1 = none , class O2 = none , class O3 = none , class O4 = none > class unordered_set_base_hook; template < class O1 = none , class O2 = none , class O3 = none , class O4 = none > class unordered_set_member_hook; template < class O1 = none , class O2 = none , class O3 = none > class any_base_hook; template < class O1 = none , class O2 = none , class O3 = none > class any_member_hook; } //namespace intrusive { } //namespace boost { /// @endcond ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2007-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { namespace detail { template inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member) { //The implementation of a pointer to member is compiler dependent. const Parent * const parent = 0; const char *const member = reinterpret_cast(&(parent->*ptr_to_member)); return std::ptrdiff_t(member - reinterpret_cast(parent)); } template inline Parent *parent_from_member(Member *member, const Member Parent::* ptr_to_member) { return static_cast ( static_cast ( static_cast(static_cast(member)) - offset_from_pointer_to_member(ptr_to_member) ) ); } template inline const Parent *parent_from_member(const Member *member, const Member Parent::* ptr_to_member) { return static_cast ( static_cast ( static_cast(static_cast(member)) - offset_from_pointer_to_member(ptr_to_member) ) ); } } //namespace detail { } //namespace intrusive { } //namespace boost { ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Joaquin M Lopez Munoz 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { namespace detail { template class ebo_functor_holder_impl { public: ebo_functor_holder_impl() {} ebo_functor_holder_impl(const T& t) : t_(t) {} template ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2) : t_(arg1, arg2) {} T& get(){return t_;} const T& get()const{return t_;} private: T t_; }; template class ebo_functor_holder_impl : public T { public: ebo_functor_holder_impl() {} ebo_functor_holder_impl(const T& t) : T(t) {} template ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2) : T(arg1, arg2) {} T& get(){return *this;} const T& get()const{return *this;} }; template class ebo_functor_holder : public ebo_functor_holder_impl::value> { private: typedef ebo_functor_holder_impl::value> super; public: ebo_functor_holder(){} ebo_functor_holder(const T& t) : super(t) {} template ebo_functor_holder(const Arg1& arg1, const Arg2& arg2) : super(arg1, arg2) {} ebo_functor_holder& operator=(const ebo_functor_holder& x) { this->get()=x.get(); return *this; } }; } //namespace detail { } //namespace intrusive { } //namespace boost { ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2009-2009. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2009-2009. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// // This code was modified from the code posted by Alexandre Courpron in his // article "Interface Detection" in The Code Project: // http://www.codeproject.com/KB/architecture/Detector.aspx /////////////////////////////////////////////////////////////////////////////// // Copyright 2007 Alexandre Courpron // // Permission to use, copy, modify, redistribute and sell this software, // provided that this copyright notice appears on all copies of the software. /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { namespace function_detector { typedef char NotFoundType; struct StaticFunctionType { NotFoundType x [2]; }; struct NonStaticFunctionType { NotFoundType x [3]; }; enum { NotFound = 0, StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ), NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType ) }; } //namespace boost { } //namespace intrusive { } //namespace function_detector { ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// namespace boost { namespace intrusive { namespace function_detector { template < class T, class NonStaticType, class NonStaticConstType, class StaticType > class DetectMember_InstantiationKey_to_node_ptr { template < NonStaticType > struct TestNonStaticNonConst ; template < NonStaticConstType > struct TestNonStaticConst ; template < StaticType > struct TestStatic ; template static NonStaticFunctionType Test( TestNonStaticNonConst< &U::to_node_ptr> *, int ); template static NonStaticFunctionType Test( TestNonStaticConst< &U::to_node_ptr> *, int ); template static StaticFunctionType Test( TestStatic< &U::to_node_ptr> *, int ); template static NotFoundType Test( ... ); public : static const int check = NotFound + (sizeof(Test(0, 0)) - sizeof(NotFoundType)); };}}} namespace boost { namespace intrusive { namespace function_detector { template < class T, class NonStaticType, class NonStaticConstType, class StaticType > class DetectMember_InstantiationKey_to_value_ptr { template < NonStaticType > struct TestNonStaticNonConst ; template < NonStaticConstType > struct TestNonStaticConst ; template < StaticType > struct TestStatic ; template static NonStaticFunctionType Test( TestNonStaticNonConst< &U::to_value_ptr> *, int ); template static NonStaticFunctionType Test( TestNonStaticConst< &U::to_value_ptr> *, int ); template static StaticFunctionType Test( TestStatic< &U::to_value_ptr> *, int ); template static NotFoundType Test( ... ); public : static const int check = NotFound + (sizeof(Test(0, 0)) - sizeof(NotFoundType)); };}}} namespace boost { namespace intrusive { namespace detail { template struct is_stateful_value_traits { typedef typename ValueTraits::node_ptr node_ptr; typedef typename ValueTraits::pointer pointer; typedef typename ValueTraits::value_type value_type; typedef typename ValueTraits::const_node_ptr const_node_ptr; typedef typename ValueTraits::const_pointer const_pointer; typedef ValueTraits value_traits; static const bool value = (boost::intrusive::function_detector::NonStaticFunction == (::boost::intrusive::function_detector::DetectMember_InstantiationKey_to_node_ptr< ValueTraits, node_ptr (ValueTraits:: *)(value_type&), node_ptr (ValueTraits:: *)(value_type&) const, node_ptr (*)(value_type&) > ::check)) || (boost::intrusive::function_detector::NonStaticFunction == (::boost::intrusive::function_detector::DetectMember_InstantiationKey_to_value_ptr< ValueTraits, pointer (ValueTraits:: *)(node_ptr), pointer (ValueTraits:: *)(node_ptr) const, pointer (*)(node_ptr) > ::check)) || (boost::intrusive::function_detector::NonStaticFunction == (::boost::intrusive::function_detector::DetectMember_InstantiationKey_to_node_ptr< ValueTraits, const_node_ptr (ValueTraits:: *)(const value_type&), const_node_ptr (ValueTraits:: *)(const value_type&) const, const_node_ptr (*)(const value_type&) > ::check)) || (boost::intrusive::function_detector::NonStaticFunction == (::boost::intrusive::function_detector::DetectMember_InstantiationKey_to_value_ptr< ValueTraits, const_pointer (ValueTraits:: *)(const_node_ptr), const_pointer (ValueTraits:: *)(const_node_ptr) const, const_pointer (*)(const_node_ptr) > ::check)) ; }; }}} ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// // boost cstdint.hpp header file ------------------------------------------// // (C) Copyright Beman Dawes 1999. // (C) Copyright Jens Mauer 2001 // (C) Copyright John Maddock 2001 // Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/integer for documentation. // Revision History // 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) // 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) // 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) // 12 Nov 00 Merged (Jens Maurer) // 23 Sep 00 Added INTXX_C macro support (John Maddock). // 22 Sep 00 Better 64-bit support (John Maddock) // 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost // 8 Aug 99 Initial version (Beman Dawes) // // Since we always define the INT#_C macros as per C++0x, // define __STDC_CONSTANT_MACROS so that does the right // thing if possible, and so that the user knows that the macros // are actually defined as per C99. // // // Note that GLIBC is a bit inconsistent about whether int64_t is defined or not // depending upon what headers happen to have been included first... // so we disable use of stdint.h when GLIBC does not define __GLIBC_HAVE_LONG_LONG. // See https://svn.boost.org/trac/boost/ticket/3548 and http://sources.redhat.com/bugzilla/show_bug.cgi?id=10990 // // The following #include is an implementation artifact; not part of interface. /*****************************************************************************/ /* STDINT.H v7.3.6 */ /* */ /* Copyright (c) 2002-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /* 7.18.1.1 Exact-width integer types */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef int int32_t; typedef unsigned int uint32_t; typedef __int40_t int40_t; typedef unsigned __int40_t uint40_t; typedef long long int64_t; typedef unsigned long long uint64_t; /* 7.18.1.2 Minimum-width integer types */ typedef int8_t int_least8_t; typedef uint8_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; typedef int40_t int_least40_t; typedef uint40_t uint_least40_t; typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; /* 7.18.1.3 Fastest minimum-width integer types */ typedef int32_t int_fast8_t; typedef uint32_t uint_fast8_t; typedef int32_t int_fast16_t; typedef uint32_t uint_fast16_t; typedef int32_t int_fast32_t; typedef uint32_t uint_fast32_t; typedef int40_t int_fast40_t; typedef uint40_t uint_fast40_t; typedef int64_t int_fast64_t; typedef uint64_t uint_fast64_t; /* 7.18.1.4 Integer types capable of holding object pointers */ typedef int intptr_t; typedef unsigned int uintptr_t; /* 7.18.1.5 Greatest-width integer types */ typedef long long intmax_t; typedef unsigned long long uintmax_t; /* According to footnotes in the 1999 C standard, "C++ implementations should define these macros only when __STDC_LIMIT_MACROS is defined before is included." */ // There is a bug in Cygwin two _C macros namespace boost { using ::int8_t; using ::int_least8_t; using ::int_fast8_t; using ::uint8_t; using ::uint_least8_t; using ::uint_fast8_t; using ::int16_t; using ::int_least16_t; using ::int_fast16_t; using ::uint16_t; using ::uint_least16_t; using ::uint_fast16_t; using ::int32_t; using ::int_least32_t; using ::int_fast32_t; using ::uint32_t; using ::uint_least32_t; using ::uint_fast32_t; using ::int64_t; using ::int_least64_t; using ::int_fast64_t; using ::uint64_t; using ::uint_least64_t; using ::uint_fast64_t; using ::intmax_t; using ::uintmax_t; } // namespace boost /**************************************************** Macro definition section: Added 23rd September 2000 (John Maddock). Modified 11th September 2001 to be excluded when BOOST_HAS_STDINT_H is defined (John Maddock). Modified 11th Dec 2009 to always define the INT#_C macros if they're not already defined (John Maddock). ******************************************************/ // // For the following code we get several warnings along the lines of: // // boost/cstdint.hpp:428:35: error: use of C99 long long integer constant // // So we declare this a system header to suppress these warnings. // // do it the old fashioned way: // 8-bit types ------------------------------------------------------------// // 16-bit types -----------------------------------------------------------// // 32-bit types -----------------------------------------------------------// // 64-bit types + intmax_t and uintmax_t ----------------------------------// // boost cstdint.hpp header file ------------------------------------------// // (C) Copyright Beman Dawes 1999. // (C) Copyright Jens Mauer 2001 // (C) Copyright John Maddock 2001 // Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/integer for documentation. // Revision History // 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) // 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) // 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) // 12 Nov 00 Merged (Jens Maurer) // 23 Sep 00 Added INTXX_C macro support (John Maddock). // 22 Sep 00 Better 64-bit support (John Maddock) // 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost // 8 Aug 99 Initial version (Beman Dawes) /**************************************************** Macro definition section: Added 23rd September 2000 (John Maddock). Modified 11th September 2001 to be excluded when BOOST_HAS_STDINT_H is defined (John Maddock). Modified 11th Dec 2009 to always define the INT#_C macros if they're not already defined (John Maddock). ******************************************************/ namespace boost { namespace intrusive { namespace detail { template struct internal_member_value_traits { template static detail::one test(...); template static detail::two test(typename U::member_value_traits* = 0); static const bool value = sizeof(test(0)) == sizeof(detail::two); }; template struct internal_base_hook_bool { template struct two_or_three {one _[2 + Add];}; template static one test(...); template static two_or_three test (int); static const std::size_t value = sizeof(test(0)); }; template struct internal_base_hook_bool_is_true { static const bool value = internal_base_hook_bool::value > sizeof(one)*2; }; template struct internal_any_hook_bool { template struct two_or_three {one _[2 + Add];}; template static one test(...); template static two_or_three test (int); static const std::size_t value = sizeof(test(0)); }; template struct internal_any_hook_bool_is_true { static const bool value = internal_any_hook_bool::value > sizeof(one)*2; }; template struct external_value_traits_bool { template struct two_or_three {one _[2 + Add];}; template static one test(...); template static two_or_three test (int); static const std::size_t value = sizeof(test(0)); }; template struct external_bucket_traits_bool { template struct two_or_three {one _[2 + Add];}; template static one test(...); template static two_or_three test (int); static const std::size_t value = sizeof(test(0)); }; template struct external_value_traits_is_true { static const bool value = external_value_traits_bool::value > sizeof(one)*2; }; template struct node_holder : public Node {}; template inline T* to_raw_pointer(T* p) { return p; } template inline typename boost::intrusive::pointer_traits::element_type* to_raw_pointer(const Pointer &p) { return boost::intrusive::detail::to_raw_pointer(p.operator->()); } //This functor compares a stored value //and the one passed as an argument template class equal_to_value { ConstReference t_; public: equal_to_value(ConstReference t) : t_(t) {} bool operator()(ConstReference t)const { return t_ == t; } }; class null_disposer { public: template void operator()(Pointer) {} }; template class init_disposer { typedef typename NodeAlgorithms::node_ptr node_ptr; public: void operator()(const node_ptr & p) { NodeAlgorithms::init(p); } }; template struct size_holder { static const bool constant_time_size = ConstantSize; typedef SizeType size_type; SizeType get_size() const { return size_; } void set_size(SizeType size) { size_ = size; } void decrement() { --size_; } void increment() { ++size_; } SizeType size_; }; template struct size_holder { static const bool constant_time_size = false; typedef SizeType size_type; size_type get_size() const { return 0; } void set_size(size_type) {} void decrement() {} void increment() {} }; template struct key_nodeptr_comp : private detail::ebo_functor_holder { typedef typename Container::real_value_traits real_value_traits; typedef typename Container::value_type value_type; typedef typename real_value_traits::node_ptr node_ptr; typedef typename real_value_traits::const_node_ptr const_node_ptr; typedef detail::ebo_functor_holder base_t; key_nodeptr_comp(KeyValueCompare kcomp, const Container *cont) : base_t(kcomp), cont_(cont) {} template struct is_node_ptr { static const bool value = is_same::value || is_same::value; }; template const value_type & key_forward (const T &node, typename enable_if_c::value>::type * = 0) const { return *cont_->get_real_value_traits().to_value_ptr(node); } template const T & key_forward(const T &key, typename enable_if_c::value>::type* = 0) const { return key; } template bool operator()(const KeyType &key1, const KeyType2 &key2) const { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); } const Container *cont_; }; template struct node_cloner : private detail::ebo_functor_holder { typedef typename Container::real_value_traits real_value_traits; typedef typename Container::node_algorithms node_algorithms; typedef typename real_value_traits::value_type value_type; typedef typename real_value_traits::pointer pointer; typedef typename real_value_traits::node_traits::node node; typedef typename real_value_traits::node_ptr node_ptr; typedef typename real_value_traits::const_node_ptr const_node_ptr; typedef detail::ebo_functor_holder base_t; enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || (int)real_value_traits::link_mode == (int)safe_link }; node_cloner(F f, const Container *cont) : base_t(f), cont_(cont) {} node_ptr operator()(const node_ptr & p) { return this->operator()(*p); } node_ptr operator()(const node &to_clone) { const value_type &v = *cont_->get_real_value_traits().to_value_ptr (pointer_traits::pointer_to(to_clone)); node_ptr n = cont_->get_real_value_traits().to_node_ptr(*base_t::get()(v)); //Cloned node must be in default mode if the linking mode requires it if(safemode_or_autounlink) std:: _assert((node_algorithms::unique(n)) != 0, "Assertion failed, (" "node_algorithms::unique(n)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/detail/utilities.hpp" ", line " "258" "\n"); return n; } const Container *cont_; }; template struct node_disposer : private detail::ebo_functor_holder { typedef typename Container::real_value_traits real_value_traits; typedef typename real_value_traits::node_ptr node_ptr; typedef detail::ebo_functor_holder base_t; typedef typename Container::node_algorithms node_algorithms; enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || (int)real_value_traits::link_mode == (int)safe_link }; node_disposer(F f, const Container *cont) : base_t(f), cont_(cont) {} void operator()(const node_ptr & p) { if(safemode_or_autounlink) node_algorithms::init(p); base_t::get()(cont_->get_real_value_traits().to_value_ptr(p)); } const Container *cont_; }; struct dummy_constptr { dummy_constptr(const void *) {} const void *get_ptr() const { return 0; } }; template struct constptr { typedef typename boost::intrusive::pointer_traits:: template rebind_pointer::type ConstVoidPtr; constptr(const void *ptr) : const_void_ptr_(ptr) {} const void *get_ptr() const { return boost::intrusive::detail::to_raw_pointer(const_void_ptr_); } ConstVoidPtr const_void_ptr_; }; template struct select_constptr { typedef typename detail::if_c < store_ptr , constptr , dummy_constptr >::type type; }; template struct add_const_if_c { typedef typename detail::if_c < Add , typename detail::add_const::type , T >::type type; }; template struct link_dispatch {}; template void destructor_impl(Hook &hook, detail::link_dispatch) { //If this assertion raises, you might have destroyed an object //while it was still inserted in a container that is alive. //If so, remove the object from the container before destroying it. (void)hook; std:: _assert((!hook . is_linked()) != 0, "Assertion failed, (" "!hook.is_linked()" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/detail/utilities.hpp" ", line " "344" "\n"); } template void destructor_impl(Hook &hook, detail::link_dispatch) { hook.unlink(); } template void destructor_impl(Hook &, detail::link_dispatch) {} template struct base_hook_traits { public: typedef detail::node_holder node_holder; typedef typename NodeTraits::node node; typedef NodeTraits node_traits; typedef T value_type; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename pointer_traits:: template rebind_pointer::type pointer; typedef typename pointer_traits:: template rebind_pointer::type const_pointer; //typedef typename pointer_traits::reference reference; //typedef typename pointer_traits::reference const_reference; typedef T & reference; typedef const T & const_reference; typedef node_holder & node_holder_reference; typedef const node_holder & const_node_holder_reference; typedef node& node_reference; typedef const node & const_node_reference; static const link_mode_type link_mode = LinkMode; static pointer to_value_ptr(const node_ptr & n) { return pointer_traits::pointer_to (static_cast(static_cast(*n))); } static const_pointer to_value_ptr(const const_node_ptr & n) { return pointer_traits::pointer_to (static_cast(static_cast(*n))); } static node_ptr to_node_ptr(reference value) { return pointer_traits::pointer_to (static_cast(static_cast(value))); } static const_node_ptr to_node_ptr(const_reference value) { return pointer_traits::pointer_to (static_cast(static_cast(value))); } }; template struct member_hook_traits { public: typedef Hook hook_type; typedef typename hook_type::boost_intrusive_tags::node_traits node_traits; typedef typename node_traits::node node; typedef T value_type; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename pointer_traits:: template rebind_pointer::type pointer; typedef typename pointer_traits:: template rebind_pointer::type const_pointer; typedef T & reference; typedef const T & const_reference; typedef node& node_reference; typedef const node & const_node_reference; typedef hook_type& hook_reference; typedef const hook_type & const_hook_reference; static const link_mode_type link_mode = Hook::boost_intrusive_tags::link_mode; static node_ptr to_node_ptr(reference value) { return pointer_traits::pointer_to (static_cast(static_cast(value.*P))); } static const_node_ptr to_node_ptr(const_reference value) { return pointer_traits::pointer_to (static_cast(static_cast(value.*P))); } static pointer to_value_ptr(const node_ptr & n) { return pointer_traits::pointer_to (*detail::parent_from_member (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); } static const_pointer to_value_ptr(const const_node_ptr & n) { return pointer_traits::pointer_to (*detail::parent_from_member (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); } }; template struct function_hook_traits { public: typedef typename Functor::hook_type hook_type; typedef typename Functor::hook_ptr hook_ptr; typedef typename Functor::const_hook_ptr const_hook_ptr; typedef typename hook_type::boost_intrusive_tags::node_traits node_traits; typedef typename node_traits::node node; typedef typename Functor::value_type value_type; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename pointer_traits:: template rebind_pointer::type pointer; typedef typename pointer_traits:: template rebind_pointer::type const_pointer; typedef value_type & reference; typedef const value_type & const_reference; static const link_mode_type link_mode = hook_type::boost_intrusive_tags::link_mode; static node_ptr to_node_ptr(reference value) { return static_cast(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); } static const_node_ptr to_node_ptr(const_reference value) { return static_cast(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); } static pointer to_value_ptr(const node_ptr & n) { return Functor::to_value_ptr(to_hook_ptr(n)); } static const_pointer to_value_ptr(const const_node_ptr & n) { return Functor::to_value_ptr(to_hook_ptr(n)); } private: static hook_ptr to_hook_ptr(const node_ptr & n) { return hook_ptr(&*static_cast(&*n)); } static const_hook_ptr to_hook_ptr(const const_node_ptr & n) { return const_hook_ptr(&*static_cast(&*n)); } }; //This function uses binary search to discover the //highest set bit of the integer inline std::size_t floor_log2 (std::size_t x) { const std::size_t Bits = sizeof(std::size_t)*8; const bool Size_t_Bits_Power_2= !(Bits & (Bits-1)); typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)(Size_t_Bits_Power_2) >)> boost_static_assert_typedef_503; std::size_t n = x; std::size_t log2 = 0; for(std::size_t shift = Bits >> 1; shift; shift >>= 1){ std::size_t tmp = n >> shift; if (tmp) log2 += shift, n = tmp; } return log2; } inline float fast_log2 (float val) { union caster_t { boost::uint32_t x; float val; } caster; caster.val = val; boost::uint32_t x = caster.x; const int log_2 = (int)(((x >> 23) & 255) - 128); x &= ~(255 << 23); x += 127 << 23; caster.x = x; val = caster.val; val = ((-1.0f/3) * val + 2) * val - 2.0f/3; return (val + log_2); } inline std::size_t ceil_log2 (std::size_t x) { return ((x & (x-1))!= 0) + floor_log2(x); } template struct numbits_eq { static const bool value = sizeof(SizeType)*8 == N; }; template struct sqrt2_pow_max; template struct sqrt2_pow_max >::type> { static const boost::uint32_t value = 0xb504f334; static const std::size_t pow = 31; }; template struct sqrt2_pow_max >::type> { static const boost::uint64_t value = 0xb504f333f9de6484ull; static const std::size_t pow = 63; }; // Returns floor(pow(sqrt(2), x * 2 + 1)). // Defined for X from 0 up to the number of bits in size_t minus 1. inline std::size_t sqrt2_pow_2xplus1 (std::size_t x) { const std::size_t value = (std::size_t)sqrt2_pow_max::value; const std::size_t pow = (std::size_t)sqrt2_pow_max::pow; return (value >> (pow - x)) + 1; } template class exception_disposer { Container *cont_; Disposer &disp_; exception_disposer(const exception_disposer&); exception_disposer &operator=(const exception_disposer&); public: exception_disposer(Container &cont, Disposer &disp) : cont_(&cont), disp_(disp) {} void release() { cont_ = 0; } ~exception_disposer() { if(cont_){ cont_->clear_and_dispose(disp_); } } }; template class exception_array_disposer { Container *cont_; Disposer &disp_; SizeType &constructed_; exception_array_disposer(const exception_array_disposer&); exception_array_disposer &operator=(const exception_array_disposer&); public: exception_array_disposer (Container &cont, Disposer &disp, SizeType &constructed) : cont_(&cont), disp_(disp), constructed_(constructed) {} void release() { cont_ = 0; } ~exception_array_disposer() { SizeType n = constructed_; if(cont_){ while(n--){ cont_[n].clear_and_dispose(disp_); } } } }; template struct store_cont_ptr_on_it_impl { static const bool value = is_stateful_value_traits::value; }; template struct store_cont_ptr_on_it_impl { static const bool value = true; }; template struct store_cont_ptr_on_it { typedef typename Container::value_traits value_traits; static const bool value = store_cont_ptr_on_it_impl ::value>::value; }; template struct node_to_value : public detail::select_constptr < typename pointer_traits ::template rebind_pointer::type , detail::store_cont_ptr_on_it::value >::type { static const bool store_container_ptr = detail::store_cont_ptr_on_it::value; typedef typename Container::real_value_traits real_value_traits; typedef typename real_value_traits::value_type value_type; typedef typename detail::select_constptr < typename pointer_traits ::template rebind_pointer::type , store_container_ptr >::type Base; typedef typename real_value_traits::node_traits::node node; typedef typename detail::add_const_if_c ::type vtype; typedef typename detail::add_const_if_c ::type ntype; typedef typename pointer_traits ::template rebind_pointer::type npointer; node_to_value(const Container *cont) : Base(cont) {} typedef vtype & result_type; typedef ntype & first_argument_type; const Container *get_container() const { if(store_container_ptr) return static_cast(Base::get_ptr()); else return 0; } const real_value_traits *get_real_value_traits() const { if(store_container_ptr) return &this->get_container()->get_real_value_traits(); else return 0; } result_type operator()(first_argument_type arg) const { return *(this->get_real_value_traits()->to_value_ptr (pointer_traits::pointer_to(arg))); } }; //This is not standard, but should work with all compilers union max_align { char char_; short short_; int int_; long long_; long long long_long_; float float_; double double_; long double long_double_; void * void_ptr_; }; template class array_initializer { public: template array_initializer(const CommonInitializer &init) { char *init_buf = (char*)rawbuf; std::size_t i = 0; try{ for(; i != N; ++i){ new(init_buf)T(init); init_buf += sizeof(T); } } catch(...){ while(i--){ init_buf -= sizeof(T); ((T*)init_buf)->~T(); } throw; } } operator T* () { return (T*)(rawbuf); } operator const T*() const { return (const T*)(rawbuf); } ~array_initializer() { char *init_buf = (char*)rawbuf + N*sizeof(T); for(std::size_t i = 0; i != N; ++i){ init_buf -= sizeof(T); ((T*)init_buf)->~T(); } } private: detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1]; }; template class reverse_iterator : public std::iterator< typename std::iterator_traits::iterator_category, typename std::iterator_traits::value_type, typename std::iterator_traits::difference_type, typename std::iterator_traits::pointer, typename std::iterator_traits::reference> { public: typedef typename std::iterator_traits::pointer pointer; typedef typename std::iterator_traits::reference reference; typedef typename std::iterator_traits::difference_type difference_type; typedef It iterator_type; reverse_iterator(){} explicit reverse_iterator(It r) : m_current(r) {} template reverse_iterator(const reverse_iterator& r) : m_current(r.base()) {} It base() const { return m_current; } reference operator*() const { It temp(m_current); --temp; return *temp; } pointer operator->() const { It temp(m_current); --temp; return temp.operator->(); } reference operator[](difference_type off) const { return this->m_current[-off]; } reverse_iterator& operator++() { --m_current; return *this; } reverse_iterator operator++(int) { reverse_iterator temp = *this; --m_current; return temp; } reverse_iterator& operator--() { ++m_current; return *this; } reverse_iterator operator--(int) { reverse_iterator temp(*this); ++m_current; return temp; } friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current == r.m_current; } friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current != r.m_current; } friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current < r.m_current; } friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current <= r.m_current; } friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current > r.m_current; } friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current >= r.m_current; } reverse_iterator& operator+=(difference_type off) { m_current -= off; return *this; } friend reverse_iterator operator+(const reverse_iterator & l, difference_type off) { reverse_iterator tmp(l.m_current); tmp.m_current -= off; return tmp; } reverse_iterator& operator-=(difference_type off) { m_current += off; return *this; } friend reverse_iterator operator-(const reverse_iterator & l, difference_type off) { reverse_iterator tmp(l.m_current); tmp.m_current += off; return tmp; } friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) { return r.m_current - l.m_current; } private: It m_current; // the wrapped iterator }; } //namespace detail } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. // (C) Copyright Ion Gaztanaga 2006-2009. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. // (C) Copyright Ion Gaztanaga 2006-2009. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// // The internal implementation of red-black trees is based on that of SGI STL // stl_tree.h file: // // 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. // // The tree destruction algorithm is based on Julienne Walker and The EC Team code: // // This code is in the public domain. Anyone may use it or change it in any way that // they see fit. The author assumes no responsibility for damages incurred through // use of the original code or any variations thereof. // // It is requested, but not required, that due credit is given to the original author // and anyone who has modified the code through a header comment, such as this one. ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2007. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { namespace detail { //! This is an implementation of a binary search tree. //! A node in the search tree has references to its children and its parent. This //! is to allow traversal of the whole tree from a given node making the //! implementation of iterator a pointer to a node. //! At the top of the tree a node is used specially. This node's parent pointer //! is pointing to the root of the tree. Its left pointer points to the //! leftmost node in the tree and the right pointer to the rightmost one. //! This node is used to represent the end-iterator. //! //! +---------+ //! header------------------------------>| | //! | | //! +----------(left)--------| |--------(right)---------+ //! | +---------+ | //! | | | //! | | (parent) | //! | | | //! | | | //! | +---------+ | //! root of tree ..|......................> | | | //! | | D | | //! | | | | //! | +-------+---------+-------+ | //! | | | | //! | | | | //! | | | | //! | | | | //! | | | | //! | +---------+ +---------+ | //! | | | | | | //! | | B | | F | | //! | | | | | | //! | +--+---------+--+ +--+---------+--+ | //! | | | | | | //! | | | | | | //! | | | | | | //! | +---+-----+ +-----+---+ +---+-----+ +-----+---+ | //! +-->| | | | | | | |<--+ //! | A | | C | | E | | G | //! | | | | | | | | //! +---------+ +---------+ +---------+ +---------+ //! //! tree_algorithms is configured with a NodeTraits class, which encapsulates the //! information about the node to be manipulated. NodeTraits must support the //! following interface: //! //! Typedefs: //! //! node: The type of the node that forms the circular list //! //! node_ptr: A pointer to a node //! //! const_node_ptr: A pointer to a const node //! //! Static functions: //! //! static node_ptr get_parent(const_node_ptr n); //! //! static void set_parent(node_ptr n, node_ptr parent); //! //! static node_ptr get_left(const_node_ptr n); //! //! static void set_left(node_ptr n, node_ptr left); //! //! static node_ptr get_right(const_node_ptr n); //! //! static void set_right(node_ptr n, node_ptr right); template class tree_algorithms { public: typedef typename NodeTraits::node node; typedef NodeTraits node_traits; typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; //! This type is the information that will be filled by insert_unique_check struct insert_commit_data { insert_commit_data() : link_left(false) , node() {} bool link_left; node_ptr node; }; struct nop_erase_fixup { void operator()(const node_ptr&, const node_ptr&){} }; /// @cond private: template struct dispose_subtree_disposer { dispose_subtree_disposer(Disposer &disp, const node_ptr & subtree) : disposer_(&disp), subtree_(subtree) {} void release() { disposer_ = 0; } ~dispose_subtree_disposer() { if(disposer_){ dispose_subtree(subtree_, *disposer_); } } Disposer *disposer_; node_ptr subtree_; }; static node_ptr uncast(const const_node_ptr & ptr) { return pointer_traits::const_cast_from(ptr); } /// @endcond public: static node_ptr begin_node(const const_node_ptr & header) { return node_traits::get_left(header); } static node_ptr end_node(const const_node_ptr & header) { return uncast(header); } //! Requires: 'node' is a node of the tree or an node initialized //! by init(...) or init_node. //! //! Effects: Returns true if the node is initialized by init() or init_node(). //! //! Complexity: Constant time. //! //! Throws: Nothing. static bool unique(const const_node_ptr & node) { return !NodeTraits::get_parent(node); } static node_ptr get_header(const const_node_ptr & node) { node_ptr h = uncast(node); if(NodeTraits::get_parent(node)){ h = NodeTraits::get_parent(node); while(!is_header(h)) h = NodeTraits::get_parent(h); } return h; } //! Requires: node1 and node2 can't be header nodes //! of two trees. //! //! Effects: Swaps two nodes. After the function node1 will be inserted //! in the position node2 before the function. node2 will be inserted in the //! position node1 had before the function. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function static void swap_nodes(const node_ptr & node1, const node_ptr & node2) { if(node1 == node2) return; node_ptr header1(get_header(node1)), header2(get_header(node2)); swap_nodes(node1, header1, node2, header2); } //! Requires: node1 and node2 can't be header nodes //! of two trees with header header1 and header2. //! //! Effects: Swaps two nodes. After the function node1 will be inserted //! in the position node2 before the function. node2 will be inserted in the //! position node1 had before the function. //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2) { if(node1 == node2) return; //node1 and node2 must not be header nodes //BOOST_INTRUSIVE_INVARIANT_ASSERT((header1 != node1 && header2 != node2)); if(header1 != header2){ //Update header1 if necessary if(node1 == NodeTraits::get_left(header1)){ NodeTraits::set_left(header1, node2); } if(node1 == NodeTraits::get_right(header1)){ NodeTraits::set_right(header1, node2); } if(node1 == NodeTraits::get_parent(header1)){ NodeTraits::set_parent(header1, node2); } //Update header2 if necessary if(node2 == NodeTraits::get_left(header2)){ NodeTraits::set_left(header2, node1); } if(node2 == NodeTraits::get_right(header2)){ NodeTraits::set_right(header2, node1); } if(node2 == NodeTraits::get_parent(header2)){ NodeTraits::set_parent(header2, node1); } } else{ //If both nodes are from the same tree //Update header if necessary if(node1 == NodeTraits::get_left(header1)){ NodeTraits::set_left(header1, node2); } else if(node2 == NodeTraits::get_left(header2)){ NodeTraits::set_left(header2, node1); } if(node1 == NodeTraits::get_right(header1)){ NodeTraits::set_right(header1, node2); } else if(node2 == NodeTraits::get_right(header2)){ NodeTraits::set_right(header2, node1); } if(node1 == NodeTraits::get_parent(header1)){ NodeTraits::set_parent(header1, node2); } else if(node2 == NodeTraits::get_parent(header2)){ NodeTraits::set_parent(header2, node1); } //Adjust data in nodes to be swapped //so that final link swap works as expected if(node1 == NodeTraits::get_parent(node2)){ NodeTraits::set_parent(node2, node2); if(node2 == NodeTraits::get_right(node1)){ NodeTraits::set_right(node1, node1); } else{ NodeTraits::set_left(node1, node1); } } else if(node2 == NodeTraits::get_parent(node1)){ NodeTraits::set_parent(node1, node1); if(node1 == NodeTraits::get_right(node2)){ NodeTraits::set_right(node2, node2); } else{ NodeTraits::set_left(node2, node2); } } } //Now swap all the links node_ptr temp; //swap left link temp = NodeTraits::get_left(node1); NodeTraits::set_left(node1, NodeTraits::get_left(node2)); NodeTraits::set_left(node2, temp); //swap right link temp = NodeTraits::get_right(node1); NodeTraits::set_right(node1, NodeTraits::get_right(node2)); NodeTraits::set_right(node2, temp); //swap parent link temp = NodeTraits::get_parent(node1); NodeTraits::set_parent(node1, NodeTraits::get_parent(node2)); NodeTraits::set_parent(node2, temp); //Now adjust adjacent nodes for newly inserted node 1 if((temp = NodeTraits::get_left(node1))){ NodeTraits::set_parent(temp, node1); } if((temp = NodeTraits::get_right(node1))){ NodeTraits::set_parent(temp, node1); } if((temp = NodeTraits::get_parent(node1)) && //The header has been already updated so avoid it temp != header2){ if(NodeTraits::get_left(temp) == node2){ NodeTraits::set_left(temp, node1); } if(NodeTraits::get_right(temp) == node2){ NodeTraits::set_right(temp, node1); } } //Now adjust adjacent nodes for newly inserted node 2 if((temp = NodeTraits::get_left(node2))){ NodeTraits::set_parent(temp, node2); } if((temp = NodeTraits::get_right(node2))){ NodeTraits::set_parent(temp, node2); } if((temp = NodeTraits::get_parent(node2)) && //The header has been already updated so avoid it temp != header1){ if(NodeTraits::get_left(temp) == node1){ NodeTraits::set_left(temp, node2); } if(NodeTraits::get_right(temp) == node1){ NodeTraits::set_right(temp, node2); } } } //! Requires: node_to_be_replaced must be inserted in a tree //! and new_node must not be inserted in a tree. //! //! Effects: Replaces node_to_be_replaced in its position in the //! tree with new_node. The tree does not need to be rebalanced //! //! Complexity: Logarithmic. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing and comparison is needed. //! //!Experimental function static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) { if(node_to_be_replaced == new_node) return; replace_node(node_to_be_replaced, get_header(node_to_be_replaced), new_node); } //! Requires: node_to_be_replaced must be inserted in a tree //! with header "header" and new_node must not be inserted in a tree. //! //! Effects: Replaces node_to_be_replaced in its position in the //! tree with new_node. The tree does not need to be rebalanced //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing or comparison is needed. //! //!Experimental function static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) { if(node_to_be_replaced == new_node) return; //Update header if necessary if(node_to_be_replaced == NodeTraits::get_left(header)){ NodeTraits::set_left(header, new_node); } if(node_to_be_replaced == NodeTraits::get_right(header)){ NodeTraits::set_right(header, new_node); } if(node_to_be_replaced == NodeTraits::get_parent(header)){ NodeTraits::set_parent(header, new_node); } //Now set data from the original node node_ptr temp; NodeTraits::set_left(new_node, NodeTraits::get_left(node_to_be_replaced)); NodeTraits::set_right(new_node, NodeTraits::get_right(node_to_be_replaced)); NodeTraits::set_parent(new_node, NodeTraits::get_parent(node_to_be_replaced)); //Now adjust adjacent nodes for newly inserted node if((temp = NodeTraits::get_left(new_node))){ NodeTraits::set_parent(temp, new_node); } if((temp = NodeTraits::get_right(new_node))){ NodeTraits::set_parent(temp, new_node); } if((temp = NodeTraits::get_parent(new_node)) && //The header has been already updated so avoid it temp != header){ if(NodeTraits::get_left(temp) == node_to_be_replaced){ NodeTraits::set_left(temp, new_node); } if(NodeTraits::get_right(temp) == node_to_be_replaced){ NodeTraits::set_right(temp, new_node); } } } //! Requires: 'node' is a node from the tree except the header. //! //! Effects: Returns the next node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. static node_ptr next_node(const node_ptr & node) { node_ptr p_right(NodeTraits::get_right(node)); if(p_right){ return minimum(p_right); } else { node_ptr p(node); node_ptr x = NodeTraits::get_parent(p); while(p == NodeTraits::get_right(x)){ p = x; x = NodeTraits::get_parent(x); } return NodeTraits::get_right(p) != x ? x : uncast(p); } } //! Requires: 'node' is a node from the tree except the leftmost node. //! //! Effects: Returns the previous node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. static node_ptr prev_node(const node_ptr & node) { if(is_header(node)){ return NodeTraits::get_right(node); //return maximum(NodeTraits::get_parent(node)); } else if(NodeTraits::get_left(node)){ return maximum(NodeTraits::get_left(node)); } else { node_ptr p(node); node_ptr x = NodeTraits::get_parent(p); while(p == NodeTraits::get_left(x)){ p = x; x = NodeTraits::get_parent(x); } return x; } } //! Requires: 'node' is a node of a tree but not the header. //! //! Effects: Returns the minimum node of the subtree starting at p. //! //! Complexity: Logarithmic to the size of the subtree. //! //! Throws: Nothing. static node_ptr minimum (const node_ptr & node) { node_ptr p(node); for(node_ptr p_left = NodeTraits::get_left(p) ;p_left ;p_left = NodeTraits::get_left(p)){ p = p_left; } return p; } //! Requires: 'node' is a node of a tree but not the header. //! //! Effects: Returns the maximum node of the subtree starting at p. //! //! Complexity: Logarithmic to the size of the subtree. //! //! Throws: Nothing. static node_ptr maximum(const node_ptr & node) { node_ptr p(node); for(node_ptr p_right = NodeTraits::get_right(p) ;p_right ;p_right = NodeTraits::get_right(p)){ p = p_right; } return p; } //! Requires: 'node' must not be part of any tree. //! //! Effects: After the function unique(node) == true. //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. static void init(const node_ptr & node) { NodeTraits::set_parent(node, node_ptr()); NodeTraits::set_left(node, node_ptr()); NodeTraits::set_right(node, node_ptr()); }; //! Effects: Returns true if node is in the same state as if called init(node) //! //! Complexity: Constant. //! //! Throws: Nothing. static bool inited(const const_node_ptr & node) { return !NodeTraits::get_parent(node) && !NodeTraits::get_left(node) && !NodeTraits::get_right(node) ; }; //! Requires: node must not be part of any tree. //! //! Effects: Initializes the header to represent an empty tree. //! unique(header) == true. //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. static void init_header(const node_ptr & header) { NodeTraits::set_parent(header, node_ptr()); NodeTraits::set_left(header, header); NodeTraits::set_right(header, header); } //! Requires: "disposer" must be an object function //! taking a node_ptr parameter and shouldn't throw. //! //! Effects: Empties the target tree calling //! void disposer::operator()(const node_ptr &) for every node of the tree //! except the header. //! //! Complexity: Linear to the number of element of the source tree plus the. //! number of elements of tree target tree when calling this function. //! //! Throws: If cloner functor throws. If this happens target nodes are disposed. template static void clear_and_dispose(const node_ptr & header, Disposer disposer) { node_ptr source_root = NodeTraits::get_parent(header); if(!source_root) return; dispose_subtree(source_root, disposer); init_header(header); } //! Requires: header is the header of a tree. //! //! Effects: Unlinks the leftmost node from the tree, and //! updates the header link to the new leftmost node. //! //! Complexity: Average complexity is constant time. //! //! Throws: Nothing. //! //! Notes: This function breaks the tree and the tree can //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the tree. static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header) { node_ptr leftmost = NodeTraits::get_left(header); if (leftmost == header) return node_ptr(); node_ptr leftmost_parent(NodeTraits::get_parent(leftmost)); node_ptr leftmost_right (NodeTraits::get_right(leftmost)); bool is_root = leftmost_parent == header; if (leftmost_right){ NodeTraits::set_parent(leftmost_right, leftmost_parent); NodeTraits::set_left(header, tree_algorithms::minimum(leftmost_right)); if (is_root) NodeTraits::set_parent(header, leftmost_right); else NodeTraits::set_left(NodeTraits::get_parent(header), leftmost_right); } else if (is_root){ NodeTraits::set_parent(header, node_ptr()); NodeTraits::set_left(header, header); NodeTraits::set_right(header, header); } else{ NodeTraits::set_left(leftmost_parent, node_ptr()); NodeTraits::set_left(header, leftmost_parent); } return leftmost; } //! Requires: node is a node of the tree but it's not the header. //! //! Effects: Returns the number of nodes of the subtree. //! //! Complexity: Linear time. //! //! Throws: Nothing. static std::size_t count(const const_node_ptr & subtree) { if(!subtree) return 0; std::size_t count = 0; node_ptr p = minimum(uncast(subtree)); bool continue_looping = true; while(continue_looping){ ++count; node_ptr p_right(NodeTraits::get_right(p)); if(p_right){ p = minimum(p_right); } else { for(;;){ node_ptr q; if (p == subtree){ continue_looping = false; break; } q = p; p = NodeTraits::get_parent(p); if (NodeTraits::get_left(p) == q) break; } } } return count; } //! Requires: node is a node of the tree but it's not the header. //! //! Effects: Returns the number of nodes of the subtree. //! //! Complexity: Linear time. //! //! Throws: Nothing. static std::size_t size(const const_node_ptr & header) { node_ptr beg(begin_node(header)); node_ptr end(end_node(header)); std::size_t i = 0; for(;beg != end; beg = next_node(beg)) ++i; return i; } //! Requires: header1 and header2 must be the header nodes //! of two trees. //! //! Effects: Swaps two trees. After the function header1 will contain //! links to the second tree and header2 will have links to the first tree. //! //! Complexity: Constant. //! //! Throws: Nothing. static void swap_tree(const node_ptr & header1, const node_ptr & header2) { if(header1 == header2) return; node_ptr tmp; //Parent swap tmp = NodeTraits::get_parent(header1); NodeTraits::set_parent(header1, NodeTraits::get_parent(header2)); NodeTraits::set_parent(header2, tmp); //Left swap tmp = NodeTraits::get_left(header1); NodeTraits::set_left(header1, NodeTraits::get_left(header2)); NodeTraits::set_left(header2, tmp); //Right swap tmp = NodeTraits::get_right(header1); NodeTraits::set_right(header1, NodeTraits::get_right(header2)); NodeTraits::set_right(header2, tmp); //Now test parent node_ptr h1_parent(NodeTraits::get_parent(header1)); if(h1_parent){ NodeTraits::set_parent(h1_parent, header1); } else{ NodeTraits::set_left(header1, header1); NodeTraits::set_right(header1, header1); } node_ptr h2_parent(NodeTraits::get_parent(header2)); if(h2_parent){ NodeTraits::set_parent(h2_parent, header2); } else{ NodeTraits::set_left(header2, header2); NodeTraits::set_right(header2, header2); } } static bool is_header(const const_node_ptr & p) { node_ptr p_left (NodeTraits::get_left(p)); node_ptr p_right(NodeTraits::get_right(p)); if(!NodeTraits::get_parent(p) || //Header condition when empty tree (p_left && p_right && //Header always has leftmost and rightmost (p_left == p_right || //Header condition when only node (NodeTraits::get_parent(p_left) != p || NodeTraits::get_parent(p_right) != p )) //When tree size > 1 headers can't be leftmost's //and rightmost's parent )){ return true; } return false; } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an node_ptr to the element that is equivalent to //! "key" according to "comp" or "header" if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static node_ptr find (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr end = uncast(header); node_ptr y = lower_bound(header, key, comp); return (y == end || comp(key, y)) ? end : y; } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an a pair of node_ptr delimiting a range containing //! all elements that are equivalent to "key" according to "comp" or an //! empty range that indicates the position where those elements would be //! if they there are no equivalent elements. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static std::pair equal_range (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr y = uncast(header); node_ptr x = NodeTraits::get_parent(header); while(x){ if(comp(x, key)){ x = NodeTraits::get_right(x); } else if(comp(key, x)){ y = x; x = NodeTraits::get_left(x); } else{ node_ptr xu(x), yu(y); y = x, x = NodeTraits::get_left(x); xu = NodeTraits::get_right(xu); while(x){ if(comp(x, key)){ x = NodeTraits::get_right(x); } else { y = x; x = NodeTraits::get_left(x); } } while(xu){ if(comp(key, xu)){ yu = xu; xu = NodeTraits::get_left(xu); } else { xu = NodeTraits::get_right(xu); } } return std::pair (y, yu); } } return std::pair (y, y); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an node_ptr to the first element that is //! not less than "key" according to "comp" or "header" if that element does //! not exist. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static node_ptr lower_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr y = uncast(header); node_ptr x = NodeTraits::get_parent(header); while(x){ if(comp(x, key)){ x = NodeTraits::get_right(x); } else { y = x; x = NodeTraits::get_left(x); } } return y; } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an node_ptr to the first element that is greater //! than "key" according to "comp" or "header" if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static node_ptr upper_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr y = uncast(header); node_ptr x = NodeTraits::get_parent(header); while(x){ if(comp(key, x)){ y = x; x = NodeTraits::get_left(x); } else { x = NodeTraits::get_right(x); } } return y; } //! Requires: "header" must be the header node of a tree. //! "commit_data" must have been obtained from a previous call to //! "insert_unique_check". No objects should have been inserted or erased //! from the set between the "insert_unique_check" that filled "commit_data" //! and the call to "insert_commit". //! //! //! Effects: Inserts new_node in the set using the information obtained //! from the "commit_data" that a previous "insert_check" filled. //! //! Complexity: Constant time. //! //! Throws: Nothing. //! //! Notes: This function has only sense if a "insert_unique_check" has been //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. static void insert_unique_commit (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) { return insert_commit(header, new_value, commit_data); } static void insert_commit (const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data) { //Check if commit_data has not been initialized by a insert_unique_check call. std:: _assert((commit_data . node != node_ptr()) != 0, "Assertion failed, (" "commit_data.node != node_ptr()" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/detail/tree_algorithms.hpp" ", line " "906" "\n"); node_ptr parent_node(commit_data.node); if(parent_node == header){ NodeTraits::set_parent(header, new_node); NodeTraits::set_right(header, new_node); NodeTraits::set_left(header, new_node); } else if(commit_data.link_left){ NodeTraits::set_left(parent_node, new_node); if(parent_node == NodeTraits::get_left(header)) NodeTraits::set_left(header, new_node); } else{ NodeTraits::set_right(parent_node, new_node); if(parent_node == NodeTraits::get_right(header)) NodeTraits::set_right(header, new_node); } NodeTraits::set_parent(new_node, parent_node); NodeTraits::set_right(new_node, node_ptr()); NodeTraits::set_left(new_node, node_ptr()); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. NodePtrCompare compares KeyType with a node_ptr. //! //! Effects: Checks if there is an equivalent node to "key" in the //! tree according to "comp" and obtains the needed information to realize //! a constant-time node insertion if there is no equivalent node. //! //! Returns: If there is an equivalent value //! returns a pair containing a node_ptr to the already present node //! and false. If there is not equivalent key can be inserted returns true //! in the returned pair's boolean and fills "commit_data" that is meant to //! be used with the "insert_commit" function to achieve a constant-time //! insertion function. //! //! Complexity: Average complexity is at most logarithmic. //! //! Throws: If "comp" throws. //! //! Notes: This function is used to improve performance when constructing //! a node is expensive and the user does not want to have two equivalent nodes //! in the tree: if there is an equivalent value //! the constructed object must be discarded. Many times, the part of the //! node that is used to impose the order is much cheaper to construct //! than the node and this function offers the possibility to use that part //! to check if the insertion will be successful. //! //! If the check is successful, the user can construct the node and use //! "insert_commit" to insert the node in constant-time. This gives a total //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). //! //! "commit_data" remains valid for a subsequent "insert_unique_commit" only //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check (const const_node_ptr & header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0) { std::size_t depth = 0; node_ptr h(uncast(header)); node_ptr y(h); node_ptr x(NodeTraits::get_parent(y)); node_ptr prev = node_ptr(); //Find the upper bound, cache the previous value and if we should //store it in the left or right node bool left_child = true; while(x){ ++depth; y = x; x = (left_child = comp(key, x)) ? NodeTraits::get_left(x) : (prev = y, NodeTraits::get_right(x)); } if(pdepth) *pdepth = depth; //Since we've found the upper bound there is no other value with the same key if: // - There is no previous node // - The previous node is less than the key if(!prev || comp(prev, key)){ commit_data.link_left = left_child; commit_data.node = y; return std::pair(node_ptr(), true); } //If the previous value was not less than key, it means that it's equal //(because we've checked the upper bound) else{ return std::pair(prev, false); } } template static std::pair insert_unique_check (const const_node_ptr & header, const node_ptr &hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0) { //hint must be bigger than the key if(hint == header || comp(key, hint)){ node_ptr prev(hint); //Previous value should be less than the key if(hint == begin_node(header)|| comp((prev = prev_node(hint)), key)){ commit_data.link_left = unique(header) || !NodeTraits::get_left(hint); commit_data.node = commit_data.link_left ? hint : prev; if(pdepth){ *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; } return std::pair(node_ptr(), true); } } //Hint was wrong, use hintless insertion return insert_unique_check(header, key, comp, commit_data, pdepth); } template static void insert_equal_check (const node_ptr &header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp , insert_commit_data &commit_data, std::size_t *pdepth = 0) { if(hint == header || !comp(hint, new_node)){ node_ptr prev(hint); if(hint == NodeTraits::get_left(header) || !comp(new_node, (prev = prev_node(hint)))){ bool link_left = unique(header) || !NodeTraits::get_left(hint); commit_data.link_left = link_left; commit_data.node = link_left ? hint : prev; if(pdepth){ *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; } } else{ insert_equal_upper_bound_check(header, new_node, comp, commit_data, pdepth); } } else{ insert_equal_lower_bound_check(header, new_node, comp, commit_data, pdepth); } } template static void insert_equal_upper_bound_check (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) { insert_equal_check_impl(true, h, new_node, comp, commit_data, pdepth); } template static void insert_equal_lower_bound_check (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) { insert_equal_check_impl(false, h, new_node, comp, commit_data, pdepth); } template static node_ptr insert_equal (const node_ptr & h, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0) { insert_commit_data commit_data; insert_equal_check(h, hint, new_node, comp, commit_data, pdepth); insert_commit(h, new_node, commit_data); return new_node; } template static node_ptr insert_equal_upper_bound (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0) { insert_commit_data commit_data; insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth); insert_commit(h, new_node, commit_data); return new_node; } template static node_ptr insert_equal_lower_bound (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0) { insert_commit_data commit_data; insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth); insert_commit(h, new_node, commit_data); return new_node; } static node_ptr insert_before (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node, std::size_t *pdepth = 0) { insert_commit_data commit_data; insert_before_check(header, pos, commit_data, pdepth); insert_commit(header, new_node, commit_data); return new_node; } static void insert_before_check (const node_ptr &header, const node_ptr & pos , insert_commit_data &commit_data, std::size_t *pdepth = 0) { node_ptr prev(pos); if(pos != NodeTraits::get_left(header)) prev = prev_node(pos); bool link_left = unique(header) || !NodeTraits::get_left(pos); commit_data.link_left = link_left; commit_data.node = link_left ? pos : prev; if(pdepth){ *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; } } static void push_back (const node_ptr & header, const node_ptr & new_node, std::size_t *pdepth = 0) { insert_commit_data commit_data; push_back_check(header, commit_data, pdepth); insert_commit(header, new_node, commit_data); } static void push_back_check (const node_ptr & header, insert_commit_data &commit_data, std::size_t *pdepth = 0) { node_ptr prev(NodeTraits::get_right(header)); if(pdepth){ *pdepth = prev == header ? 0 : depth(prev) + 1; } commit_data.link_left = false; commit_data.node = prev; } static void push_front (const node_ptr & header, const node_ptr & new_node, std::size_t *pdepth = 0) { insert_commit_data commit_data; push_front_check(header, commit_data, pdepth); insert_commit(header, new_node, commit_data); } static void push_front_check (const node_ptr & header, insert_commit_data &commit_data, std::size_t *pdepth = 0) { node_ptr pos(NodeTraits::get_left(header)); if(pdepth){ *pdepth = pos == header ? 0 : depth(pos) + 1; } commit_data.link_left = true; commit_data.node = pos; } //! Requires: 'node' can't be a header node. //! //! Effects: Calculates the depth of a node: the depth of a //! node is the length (number of edges) of the path from the root //! to that node. (The root node is at depth 0.) //! //! Complexity: Logarithmic to the number of nodes in the tree. //! //! Throws: Nothing. static std::size_t depth(const const_node_ptr & node) { const_node_ptr p(node); std::size_t depth = 0; node_ptr p_parent; while(p != NodeTraits::get_parent(p_parent = NodeTraits::get_parent(p))){ ++depth; p = p_parent; } return depth; } //! Requires: "cloner" must be a function //! object taking a node_ptr and returning a new cloned node of it. "disposer" must //! take a node_ptr and shouldn't throw. //! //! Effects: First empties target tree calling //! void disposer::operator()(const node_ptr &) for every node of the tree //! except the header. //! //! Then, duplicates the entire tree pointed by "source_header" cloning each //! source node with node_ptr Cloner::operator()(const node_ptr &) to obtain //! the nodes of the target tree. If "cloner" throws, the cloned target nodes //! are disposed using void disposer(const node_ptr &). //! //! Complexity: Linear to the number of element of the source tree plus the. //! number of elements of tree target tree when calling this function. //! //! Throws: If cloner functor throws. If this happens target nodes are disposed. template static void clone (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer) { if(!unique(target_header)){ clear_and_dispose(target_header, disposer); } node_ptr leftmost, rightmost; node_ptr new_root = clone_subtree (source_header, target_header, cloner, disposer, leftmost, rightmost); //Now update header node NodeTraits::set_parent(target_header, new_root); NodeTraits::set_left (target_header, leftmost); NodeTraits::set_right (target_header, rightmost); } template static node_ptr clone_subtree (const const_node_ptr &source_parent, const node_ptr &target_parent , Cloner cloner, Disposer disposer , node_ptr &leftmost_out, node_ptr &rightmost_out ) { node_ptr target_sub_root = target_parent; node_ptr source_root = NodeTraits::get_parent(source_parent); if(!source_root){ leftmost_out = rightmost_out = source_root; } else{ //We'll calculate leftmost and rightmost nodes while iterating node_ptr current = source_root; node_ptr insertion_point = target_sub_root = cloner(current); //We'll calculate leftmost and rightmost nodes while iterating node_ptr leftmost = target_sub_root; node_ptr rightmost = target_sub_root; //First set the subroot NodeTraits::set_left(target_sub_root, node_ptr()); NodeTraits::set_right(target_sub_root, node_ptr()); NodeTraits::set_parent(target_sub_root, target_parent); dispose_subtree_disposer rollback(disposer, target_sub_root); while(true) { //First clone left nodes if( NodeTraits::get_left(current) && !NodeTraits::get_left(insertion_point)) { current = NodeTraits::get_left(current); node_ptr temp = insertion_point; //Clone and mark as leaf insertion_point = cloner(current); NodeTraits::set_left (insertion_point, node_ptr()); NodeTraits::set_right (insertion_point, node_ptr()); //Insert left NodeTraits::set_parent(insertion_point, temp); NodeTraits::set_left (temp, insertion_point); //Update leftmost if(rightmost == target_sub_root) leftmost = insertion_point; } //Then clone right nodes else if( NodeTraits::get_right(current) && !NodeTraits::get_right(insertion_point)){ current = NodeTraits::get_right(current); node_ptr temp = insertion_point; //Clone and mark as leaf insertion_point = cloner(current); NodeTraits::set_left (insertion_point, node_ptr()); NodeTraits::set_right (insertion_point, node_ptr()); //Insert right NodeTraits::set_parent(insertion_point, temp); NodeTraits::set_right (temp, insertion_point); //Update rightmost rightmost = insertion_point; } //If not, go up else if(current == source_root){ break; } else{ //Branch completed, go up searching more nodes to clone current = NodeTraits::get_parent(current); insertion_point = NodeTraits::get_parent(insertion_point); } } rollback.release(); leftmost_out = leftmost; rightmost_out = rightmost; } return target_sub_root; } template static void dispose_subtree(const node_ptr & node, Disposer disposer) { node_ptr save; node_ptr x(node); while (x){ save = NodeTraits::get_left(x); if (save) { // Right rotation NodeTraits::set_left(x, NodeTraits::get_right(save)); NodeTraits::set_right(save, x); } else { save = NodeTraits::get_right(x); init(x); disposer(x); } x = save; } } //! Requires: p is a node of a tree. //! //! Effects: Returns true if p is a left child. //! //! Complexity: Constant. //! //! Throws: Nothing. static bool is_left_child(const node_ptr & p) { return NodeTraits::get_left(NodeTraits::get_parent(p)) == p; } //! Requires: p is a node of a tree. //! //! Effects: Returns true if p is a right child. //! //! Complexity: Constant. //! //! Throws: Nothing. static bool is_right_child(const node_ptr & p) { return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; } //Fix header and own's parent data when replacing x with own, providing own's old data with parent static void replace_own_impl(const node_ptr & own, const node_ptr & x, const node_ptr & header, const node_ptr & own_parent, bool own_was_left) { if(NodeTraits::get_parent(header) == own) NodeTraits::set_parent(header, x); else if(own_was_left) NodeTraits::set_left(own_parent, x); else NodeTraits::set_right(own_parent, x); } //Fix header and own's parent data when replacing x with own, supposing own //links with its parent are still ok static void replace_own(const node_ptr & own, const node_ptr & x, const node_ptr & header) { node_ptr own_parent(NodeTraits::get_parent(own)); bool own_is_left(NodeTraits::get_left(own_parent) == own); replace_own_impl(own, x, header, own_parent, own_is_left); } // rotate parent p to left (no header and p's parent fixup) static node_ptr rotate_left(const node_ptr & p) { node_ptr x(NodeTraits::get_right(p)); node_ptr x_left(NodeTraits::get_left(x)); NodeTraits::set_right(p, x_left); if(x_left){ NodeTraits::set_parent(x_left, p); } NodeTraits::set_left(x, p); NodeTraits::set_parent(p, x); return x; } // rotate parent p to left (with header and p's parent fixup) static void rotate_left(const node_ptr & p, const node_ptr & header) { bool p_was_left(is_left_child(p)); node_ptr p_old_parent(NodeTraits::get_parent(p)); node_ptr x(rotate_left(p)); NodeTraits::set_parent(x, p_old_parent); replace_own_impl(p, x, header, p_old_parent, p_was_left); } // rotate parent p to right (no header and p's parent fixup) static node_ptr rotate_right(const node_ptr & p) { node_ptr x(NodeTraits::get_left(p)); node_ptr x_right(NodeTraits::get_right(x)); NodeTraits::set_left(p, x_right); if(x_right){ NodeTraits::set_parent(x_right, p); } NodeTraits::set_right(x, p); NodeTraits::set_parent(p, x); return x; } // rotate parent p to right (with header and p's parent fixup) static void rotate_right(const node_ptr & p, const node_ptr & header) { bool p_was_left(is_left_child(p)); node_ptr p_old_parent(NodeTraits::get_parent(p)); node_ptr x(rotate_right(p)); NodeTraits::set_parent(x, p_old_parent); replace_own_impl(p, x, header, p_old_parent, p_was_left); } static void erase(const node_ptr & header, const node_ptr & z) { data_for_rebalance ignored; erase_impl(header, z, ignored); } struct data_for_rebalance { node_ptr x; node_ptr x_parent; node_ptr y; }; template static void erase(const node_ptr & header, const node_ptr & z, F z_and_successor_fixup, data_for_rebalance &info) { erase_impl(header, z, info); if(info.y != z){ z_and_successor_fixup(z, info.y); } } static void unlink(const node_ptr & node) { node_ptr x = NodeTraits::get_parent(node); if(x){ while(!is_header(x)) x = NodeTraits::get_parent(x); erase(x, node); } } static void tree_to_vine(const node_ptr & header) { subtree_to_vine(NodeTraits::get_parent(header)); } static void vine_to_tree(const node_ptr & header, std::size_t count) { vine_to_subtree(NodeTraits::get_parent(header), count); } static void rebalance(const node_ptr & header) { //Taken from: //"Tree rebalancing in optimal time and space" //Quentin F. Stout and Bette L. Warren std::size_t len = 0; subtree_to_vine(NodeTraits::get_parent(header), &len); vine_to_subtree(NodeTraits::get_parent(header), len); } static node_ptr rebalance_subtree(const node_ptr & old_root) { std::size_t len = 0; node_ptr new_root = subtree_to_vine(old_root, &len); return vine_to_subtree(new_root, len); } static node_ptr subtree_to_vine(const node_ptr & old_root, std::size_t *plen = 0) { std::size_t len; len = 0; if(!old_root) return node_ptr(); //To avoid irregularities in the algorithm (old_root can be a //left or right child or even the root of the tree) just put the //root as the right child of its parent. Before doing this backup //information to restore the original relationship after //the algorithm is applied. node_ptr super_root = NodeTraits::get_parent(old_root); std:: _assert((super_root) != 0, "Assertion failed, (" "super_root" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/detail/tree_algorithms.hpp" ", line " "1457" "\n"); //Get info node_ptr super_root_right_backup = NodeTraits::get_right(super_root); bool super_root_is_header = is_header(super_root); bool old_root_is_right = is_right_child(old_root); node_ptr x(old_root); node_ptr new_root(x); node_ptr save; bool moved_to_right = false; for( ; x; x = save){ save = NodeTraits::get_left(x); if(save){ // Right rotation node_ptr save_right = NodeTraits::get_right(save); node_ptr x_parent = NodeTraits::get_parent(x); NodeTraits::set_parent(save, x_parent); NodeTraits::set_right (x_parent, save); NodeTraits::set_parent(x, save); NodeTraits::set_right (save, x); NodeTraits::set_left(x, save_right); if(save_right) NodeTraits::set_parent(save_right, x); if(!moved_to_right) new_root = save; } else{ moved_to_right = true; save = NodeTraits::get_right(x); ++len; } } if(super_root_is_header){ NodeTraits::set_right(super_root, super_root_right_backup); NodeTraits::set_parent(super_root, new_root); } else if(old_root_is_right){ NodeTraits::set_right(super_root, new_root); } else{ NodeTraits::set_right(super_root, super_root_right_backup); NodeTraits::set_left(super_root, new_root); } if(plen) *plen = len; return new_root; } static node_ptr vine_to_subtree(const node_ptr & old_root, std::size_t count) { std::size_t leaf_nodes = count + 1 - ((std::size_t) 1 << floor_log2 (count + 1)); std::size_t vine_nodes = count - leaf_nodes; node_ptr new_root = compress_subtree(old_root, leaf_nodes); while(vine_nodes > 1){ vine_nodes /= 2; new_root = compress_subtree(new_root, vine_nodes); } return new_root; } static node_ptr compress_subtree(const node_ptr & old_root, std::size_t count) { if(!old_root) return old_root; //To avoid irregularities in the algorithm (old_root can be //left or right child or even the root of the tree) just put the //root as the right child of its parent. First obtain //information to restore the original relationship after //the algorithm is applied. node_ptr super_root = NodeTraits::get_parent(old_root); std:: _assert((super_root) != 0, "Assertion failed, (" "super_root" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/detail/tree_algorithms.hpp" ", line " "1529" "\n"); //Get info node_ptr super_root_right_backup = NodeTraits::get_right(super_root); bool super_root_is_header = is_header(super_root); bool old_root_is_right = is_right_child(old_root); //Put old_root as right child NodeTraits::set_right(super_root, old_root); //Start the compression algorithm node_ptr even_parent = super_root; node_ptr new_root = old_root; while(count--){ node_ptr even = NodeTraits::get_right(even_parent); node_ptr odd = NodeTraits::get_right(even); if(new_root == old_root) new_root = odd; node_ptr even_right = NodeTraits::get_left(odd); NodeTraits::set_right(even, even_right); if (even_right) NodeTraits::set_parent(even_right, even); NodeTraits::set_right(even_parent, odd); NodeTraits::set_parent(odd, even_parent); NodeTraits::set_left(odd, even); NodeTraits::set_parent(even, odd); even_parent = odd; } if(super_root_is_header){ NodeTraits::set_parent(super_root, new_root); NodeTraits::set_right(super_root, super_root_right_backup); } else if(old_root_is_right){ NodeTraits::set_right(super_root, new_root); } else{ NodeTraits::set_left(super_root, new_root); NodeTraits::set_right(super_root, super_root_right_backup); } return new_root; } //! Requires: "n" must be a node inserted in a tree. //! //! Effects: Returns a pointer to the header node of the tree. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. static node_ptr get_root(const node_ptr & node) { std:: _assert(((!inited(node))) != 0, "Assertion failed, (" "(!inited(node))" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/detail/tree_algorithms.hpp" ", line " "1585" "\n"); node_ptr x = NodeTraits::get_parent(node); if(x){ while(!is_header(x)){ x = NodeTraits::get_parent(x); } return x; } else{ return node; } } private: template static void insert_equal_check_impl (bool upper, const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) { std::size_t depth = 0; node_ptr y(h); node_ptr x(NodeTraits::get_parent(y)); bool link_left; if(upper){ while(x){ ++depth; y = x; x = comp(new_node, x) ? NodeTraits::get_left(x) : NodeTraits::get_right(x); } link_left = (y == h) || comp(new_node, y); } else{ while(x){ ++depth; y = x; x = !comp(x, new_node) ? NodeTraits::get_left(x) : NodeTraits::get_right(x); } link_left = (y == h) || !comp(y, new_node); } commit_data.link_left = link_left; commit_data.node = y; if(pdepth) *pdepth = depth; } static void erase_impl(const node_ptr & header, const node_ptr & z, data_for_rebalance &info) { node_ptr y(z); node_ptr x; node_ptr x_parent = node_ptr(); node_ptr z_left(NodeTraits::get_left(z)); node_ptr z_right(NodeTraits::get_right(z)); if(!z_left){ x = z_right; // x might be null. } else if(!z_right){ // z has exactly one non-null child. y == z. x = z_left; // x is not null. } else{ // find z's successor y = tree_algorithms::minimum (z_right); x = NodeTraits::get_right(y); // x might be null. } if(y != z){ // relink y in place of z. y is z's successor NodeTraits::set_parent(NodeTraits::get_left(z), y); NodeTraits::set_left(y, NodeTraits::get_left(z)); if(y != NodeTraits::get_right(z)){ x_parent = NodeTraits::get_parent(y); if(x) NodeTraits::set_parent(x, x_parent); NodeTraits::set_left(x_parent, x); // y must be a child of left_ NodeTraits::set_right(y, NodeTraits::get_right(z)); NodeTraits::set_parent(NodeTraits::get_right(z), y); } else x_parent = y; tree_algorithms::replace_own (z, y, header); NodeTraits::set_parent(y, NodeTraits::get_parent(z)); } else { // y == z --> z has only one child, or none x_parent = NodeTraits::get_parent(z); if(x) NodeTraits::set_parent(x, x_parent); tree_algorithms::replace_own (z, x, header); if(NodeTraits::get_left(header) == z){ NodeTraits::set_left(header, !NodeTraits::get_right(z) ? // z->get_left() must be null also NodeTraits::get_parent(z) : // makes leftmost == header if z == root tree_algorithms::minimum (x)); } if(NodeTraits::get_right(header) == z){ NodeTraits::set_right(header, !NodeTraits::get_left(z) ? // z->get_right() must be null also NodeTraits::get_parent(z) : // makes rightmost == header if z == root tree_algorithms::maximum(x)); } } info.x = x; info.x_parent = x_parent; info.y = y; } }; } //namespace detail { } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// namespace boost { namespace intrusive { //! rbtree_algorithms provides basic algorithms to manipulate //! nodes forming a red-black tree. 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 node 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 //! pointers invalidated are those referring to the deleted node. //! //! rbtree_algorithms is configured with a NodeTraits class, which encapsulates the //! information about the node to be manipulated. NodeTraits must support the //! following interface: //! //! Typedefs: //! //! node: The type of the node that forms the circular list //! //! node_ptr: A pointer to a node //! //! const_node_ptr: A pointer to a const node //! //! color: The type that can store the color of a node //! //! Static functions: //! //! static node_ptr get_parent(const_node_ptr n); //! //! static void set_parent(node_ptr n, node_ptr parent); //! //! static node_ptr get_left(const_node_ptr n); //! //! static void set_left(node_ptr n, node_ptr left); //! //! static node_ptr get_right(const_node_ptr n); //! //! static void set_right(node_ptr n, node_ptr right); //! //! static color get_color(const_node_ptr n); //! //! static void set_color(node_ptr n, color c); //! //! static color black(); //! //! static color red(); template class rbtree_algorithms { public: typedef NodeTraits node_traits; typedef typename NodeTraits::node node; typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef typename NodeTraits::color color; /// @cond private: typedef detail::tree_algorithms tree_algorithms; template struct rbtree_node_cloner : private detail::ebo_functor_holder { typedef detail::ebo_functor_holder base_t; rbtree_node_cloner(F f) : base_t(f) {} node_ptr operator()(const node_ptr & p) { node_ptr n = base_t::get()(p); NodeTraits::set_color(n, NodeTraits::get_color(p)); return n; } }; struct rbtree_erase_fixup { void operator()(const node_ptr & to_erase, const node_ptr & successor) { //Swap color of y and z color tmp(NodeTraits::get_color(successor)); NodeTraits::set_color(successor, NodeTraits::get_color(to_erase)); NodeTraits::set_color(to_erase, tmp); } }; static node_ptr uncast(const const_node_ptr & ptr) { return pointer_traits::const_cast_from(ptr); } /// @endcond public: static node_ptr begin_node(const const_node_ptr & header) { return tree_algorithms::begin_node(header); } static node_ptr end_node(const const_node_ptr & header) { return tree_algorithms::end_node(header); } //! This type is the information that will be //! filled by insert_unique_check typedef typename tree_algorithms::insert_commit_data insert_commit_data; //! Requires: header1 and header2 must be the header nodes //! of two trees. //! //! Effects: Swaps two trees. After the function header1 will contain //! links to the second tree and header2 will have links to the first tree. //! //! Complexity: Constant. //! //! Throws: Nothing. static void swap_tree(const node_ptr & header1, const node_ptr & header2) { return tree_algorithms::swap_tree(header1, header2); } //! Requires: node1 and node2 can't be header nodes //! of two trees. //! //! Effects: Swaps two nodes. After the function node1 will be inserted //! in the position node2 before the function. node2 will be inserted in the //! position node1 had before the function. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function static void swap_nodes(const node_ptr & node1, const node_ptr & node2) { if(node1 == node2) return; node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2)); swap_nodes(node1, header1, node2, header2); } //! Requires: node1 and node2 can't be header nodes //! of two trees with header header1 and header2. //! //! Effects: Swaps two nodes. After the function node1 will be inserted //! in the position node2 before the function. node2 will be inserted in the //! position node1 had before the function. //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2) { if(node1 == node2) return; tree_algorithms::swap_nodes(node1, header1, node2, header2); //Swap color color c = NodeTraits::get_color(node1); NodeTraits::set_color(node1, NodeTraits::get_color(node2)); NodeTraits::set_color(node2, c); } //! Requires: node_to_be_replaced must be inserted in a tree //! and new_node must not be inserted in a tree. //! //! Effects: Replaces node_to_be_replaced in its position in the //! tree with new_node. The tree does not need to be rebalanced //! //! Complexity: Logarithmic. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing and comparison is needed. //! //!Experimental function static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) { if(node_to_be_replaced == new_node) return; replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node); } //! Requires: node_to_be_replaced must be inserted in a tree //! with header "header" and new_node must not be inserted in a tree. //! //! Effects: Replaces node_to_be_replaced in its position in the //! tree with new_node. The tree does not need to be rebalanced //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing or comparison is needed. //! //!Experimental function static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) { tree_algorithms::replace_node(node_to_be_replaced, header, new_node); NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced)); } //! Requires: node is a tree node but not the header. //! //! Effects: Unlinks the node and rebalances the tree. //! //! Complexity: Average complexity is constant time. //! //! Throws: Nothing. static void unlink(const node_ptr & node) { node_ptr x = NodeTraits::get_parent(node); if(x){ while(!is_header(x)) x = NodeTraits::get_parent(x); erase(x, node); } } //! Requires: header is the header of a tree. //! //! Effects: Unlinks the leftmost node from the tree, and //! updates the header link to the new leftmost node. //! //! Complexity: Average complexity is constant time. //! //! Throws: Nothing. //! //! Notes: This function breaks the tree and the tree can //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the tree. static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header) { return tree_algorithms::unlink_leftmost_without_rebalance(header); } //! Requires: node is a node of the tree or an node initialized //! by init(...). //! //! Effects: Returns true if the node is initialized by init(). //! //! Complexity: Constant time. //! //! Throws: Nothing. static bool unique(const const_node_ptr & node) { return tree_algorithms::unique(node); } //! Requires: node is a node of the tree but it's not the header. //! //! Effects: Returns the number of nodes of the subtree. //! //! Complexity: Linear time. //! //! Throws: Nothing. static std::size_t count(const const_node_ptr & node) { return tree_algorithms::count(node); } //! Requires: header is the header node of the tree. //! //! Effects: Returns the number of nodes above the header. //! //! Complexity: Linear time. //! //! Throws: Nothing. static std::size_t size(const const_node_ptr & header) { return tree_algorithms::size(header); } //! Requires: p is a node from the tree except the header. //! //! Effects: Returns the next node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. static node_ptr next_node(const node_ptr & p) { return tree_algorithms::next_node(p); } //! Requires: p is a node from the tree except the leftmost node. //! //! Effects: Returns the previous node of the tree. //! //! Complexity: Average constant time. //! //! Throws: Nothing. static node_ptr prev_node(const node_ptr & p) { return tree_algorithms::prev_node(p); } //! Requires: node must not be part of any tree. //! //! Effects: After the function unique(node) == true. //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. static void init(const node_ptr & node) { tree_algorithms::init(node); } //! Requires: node must not be part of any tree. //! //! Effects: Initializes the header to represent an empty tree. //! unique(header) == true. //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. static void init_header(const node_ptr & header) { tree_algorithms::init_header(header); NodeTraits::set_color(header, NodeTraits::red()); } //! Requires: header must be the header of a tree, z a node //! of that tree and z != header. //! //! Effects: Erases node "z" from the tree with header "header". //! //! Complexity: Amortized constant time. //! //! Throws: Nothing. static node_ptr erase(const node_ptr & header, const node_ptr & z) { typename tree_algorithms::data_for_rebalance info; tree_algorithms::erase(header, z, rbtree_erase_fixup(), info); node_ptr x = info.x; node_ptr x_parent = info.x_parent; //Rebalance rbtree if(NodeTraits::get_color(z) != NodeTraits::red()){ rebalance_after_erasure(header, x, x_parent); } return z; } //! Requires: "cloner" must be a function //! object taking a node_ptr and returning a new cloned node of it. "disposer" must //! take a node_ptr and shouldn't throw. //! //! Effects: First empties target tree calling //! void disposer::operator()(const node_ptr &) for every node of the tree //! except the header. //! //! Then, duplicates the entire tree pointed by "source_header" cloning each //! source node with node_ptr Cloner::operator()(const node_ptr &) to obtain //! the nodes of the target tree. If "cloner" throws, the cloned target nodes //! are disposed using void disposer(const node_ptr &). //! //! Complexity: Linear to the number of element of the source tree plus the. //! number of elements of tree target tree when calling this function. //! //! Throws: If cloner functor throws. If this happens target nodes are disposed. template static void clone (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer) { rbtree_node_cloner new_cloner(cloner); tree_algorithms::clone(source_header, target_header, new_cloner, disposer); } //! Requires: "disposer" must be an object function //! taking a node_ptr parameter and shouldn't throw. //! //! Effects: Empties the target tree calling //! void disposer::operator()(const node_ptr &) for every node of the tree //! except the header. //! //! Complexity: Linear to the number of element of the source tree plus the. //! number of elements of tree target tree when calling this function. //! //! Throws: If cloner functor throws. If this happens target nodes are disposed. template static void clear_and_dispose(const node_ptr & header, Disposer disposer) { tree_algorithms::clear_and_dispose(header, disposer); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an node_ptr to the first element that is //! not less than "key" according to "comp" or "header" if that element does //! not exist. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static node_ptr lower_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::lower_bound(header, key, comp); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an node_ptr to the first element that is greater //! than "key" according to "comp" or "header" if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static node_ptr upper_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::upper_bound(header, key, comp); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an node_ptr to the element that is equivalent to //! "key" according to "comp" or "header" if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static node_ptr find (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::find(header, key, comp); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. //! //! Effects: Returns an a pair of node_ptr delimiting a range containing //! all elements that are equivalent to "key" according to "comp" or an //! empty range that indicates the position where those elements would be //! if they there are no equivalent elements. //! //! Complexity: Logarithmic. //! //! Throws: If "comp" throws. template static std::pair equal_range (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::equal_range(header, key, comp); } //! Requires: "h" must be the header node of a tree. //! NodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. NodePtrCompare compares two node_ptrs. //! //! Effects: Inserts new_node into the tree before the upper bound //! according to "comp". //! //! Complexity: Average complexity for insert element is at //! most logarithmic. //! //! Throws: If "comp" throws. template static node_ptr insert_equal_upper_bound (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) { tree_algorithms::insert_equal_upper_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } //! Requires: "h" must be the header node of a tree. //! NodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. NodePtrCompare compares two node_ptrs. //! //! Effects: Inserts new_node into the tree before the lower bound //! according to "comp". //! //! Complexity: Average complexity for insert element is at //! most logarithmic. //! //! Throws: If "comp" throws. template static node_ptr insert_equal_lower_bound (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) { tree_algorithms::insert_equal_lower_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } //! Requires: "header" must be the header node of a tree. //! NodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from //! the "header"'s tree. //! //! Effects: Inserts new_node into the tree, using "hint" as a hint to //! where it will be inserted. If "hint" is the upper_bound //! the insertion takes constant time (two comparisons in the worst case). //! //! Complexity: Logarithmic in general, but it is amortized //! constant time if new_node is inserted immediately before "hint". //! //! Throws: If "comp" throws. template static node_ptr insert_equal (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp) { tree_algorithms::insert_equal(header, hint, new_node, comp); rebalance_after_insertion(header, new_node); return new_node; } //! Requires: "header" must be the header node of a tree. //! "pos" must be a valid iterator or header (end) node. //! "pos" must be an iterator pointing to the successor to "new_node" //! once inserted according to the order of already inserted nodes. This function does not //! check "pos" and this precondition must be guaranteed by the caller. //! //! Effects: Inserts new_node into the tree before "pos". //! //! Complexity: Constant-time. //! //! Throws: Nothing. //! //! Note: If "pos" is not the successor of the newly inserted "new_node" //! tree invariants might be broken. static node_ptr insert_before (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node) { tree_algorithms::insert_before(header, pos, new_node); rebalance_after_insertion(header, new_node); return new_node; } //! Requires: "header" must be the header node of a tree. //! "new_node" must be, according to the used ordering no less than the //! greatest inserted key. //! //! Effects: Inserts new_node into the tree before "pos". //! //! Complexity: Constant-time. //! //! Throws: Nothing. //! //! Note: If "new_node" is less than the greatest inserted key //! tree invariants are broken. This function is slightly faster than //! using "insert_before". static void push_back(const node_ptr & header, const node_ptr & new_node) { tree_algorithms::push_back(header, new_node); rebalance_after_insertion(header, new_node); } //! Requires: "header" must be the header node of a tree. //! "new_node" must be, according to the used ordering, no greater than the //! lowest inserted key. //! //! Effects: Inserts new_node into the tree before "pos". //! //! Complexity: Constant-time. //! //! Throws: Nothing. //! //! Note: If "new_node" is greater than the lowest inserted key //! tree invariants are broken. This function is slightly faster than //! using "insert_before". static void push_front(const node_ptr & header, const node_ptr & new_node) { tree_algorithms::push_front(header, new_node); rebalance_after_insertion(header, new_node); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. NodePtrCompare compares KeyType with a node_ptr. //! //! Effects: Checks if there is an equivalent node to "key" in the //! tree according to "comp" and obtains the needed information to realize //! a constant-time node insertion if there is no equivalent node. //! //! Returns: If there is an equivalent value //! returns a pair containing a node_ptr to the already present node //! and false. If there is not equivalent key can be inserted returns true //! in the returned pair's boolean and fills "commit_data" that is meant to //! be used with the "insert_commit" function to achieve a constant-time //! insertion function. //! //! Complexity: Average complexity is at most logarithmic. //! //! Throws: If "comp" throws. //! //! Notes: This function is used to improve performance when constructing //! a node is expensive and the user does not want to have two equivalent nodes //! in the tree: if there is an equivalent value //! the constructed object must be discarded. Many times, the part of the //! node that is used to impose the order is much cheaper to construct //! than the node and this function offers the possibility to use that part //! to check if the insertion will be successful. //! //! If the check is successful, the user can construct the node and use //! "insert_commit" to insert the node in constant-time. This gives a total //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). //! //! "commit_data" remains valid for a subsequent "insert_unique_commit" only //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check (const const_node_ptr & header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { return tree_algorithms::insert_unique_check(header, key, comp, commit_data); } //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the //! the tree. NodePtrCompare compares KeyType with a node_ptr. //! "hint" is node from the "header"'s tree. //! //! Effects: Checks if there is an equivalent node to "key" in the //! tree according to "comp" using "hint" as a hint to where it should be //! inserted and obtains the needed information to realize //! a constant-time node insertion if there is no equivalent node. //! If "hint" is the upper_bound the function has constant time //! complexity (two comparisons in the worst case). //! //! Returns: If there is an equivalent value //! returns a pair containing a node_ptr to the already present node //! and false. If there is not equivalent key can be inserted returns true //! in the returned pair's boolean and fills "commit_data" that is meant to //! be used with the "insert_commit" function to achieve a constant-time //! insertion function. //! //! Complexity: Average complexity is at most logarithmic, but it is //! amortized constant time if new_node should be inserted immediately before "hint". //! //! Throws: If "comp" throws. //! //! Notes: This function is used to improve performance when constructing //! a node is expensive and the user does not want to have two equivalent nodes //! in the tree: if there is an equivalent value //! the constructed object must be discarded. Many times, the part of the //! node that is used to impose the order is much cheaper to construct //! than the node and this function offers the possibility to use that part //! to check if the insertion will be successful. //! //! If the check is successful, the user can construct the node and use //! "insert_commit" to insert the node in constant-time. This gives a total //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). //! //! "commit_data" remains valid for a subsequent "insert_unique_commit" only //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check (const const_node_ptr & header, const node_ptr &hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); } //! Requires: "header" must be the header node of a tree. //! "commit_data" must have been obtained from a previous call to //! "insert_unique_check". No objects should have been inserted or erased //! from the set between the "insert_unique_check" that filled "commit_data" //! and the call to "insert_commit". //! //! //! Effects: Inserts new_node in the set using the information obtained //! from the "commit_data" that a previous "insert_check" filled. //! //! Complexity: Constant time. //! //! Throws: Nothing. //! //! Notes: This function has only sense if a "insert_unique_check" has been //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. static void insert_unique_commit (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) { tree_algorithms::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(header, new_value); } //! Requires: "n" must be a node inserted in a tree. //! //! Effects: Returns a pointer to the header node of the tree. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. static node_ptr get_header(const node_ptr & n) { return tree_algorithms::get_header(n); } /// @cond private: //! Requires: p is a node of a tree. //! //! Effects: Returns true if p is the header of the tree. //! //! Complexity: Constant. //! //! Throws: Nothing. static bool is_header(const const_node_ptr & p) { return NodeTraits::get_color(p) == NodeTraits::red() && tree_algorithms::is_header(p); //return NodeTraits::get_color(p) == NodeTraits::red() && // NodeTraits::get_parent(NodeTraits::get_parent(p)) == p; } static void rebalance_after_erasure(const node_ptr & header, const node_ptr &xnode, const node_ptr &xnode_parent) { node_ptr x(xnode), x_parent(xnode_parent); while(x != NodeTraits::get_parent(header) && (x == node_ptr() || NodeTraits::get_color(x) == NodeTraits::black())){ if(x == NodeTraits::get_left(x_parent)){ node_ptr w = NodeTraits::get_right(x_parent); if(NodeTraits::get_color(w) == NodeTraits::red()){ NodeTraits::set_color(w, NodeTraits::black()); NodeTraits::set_color(x_parent, NodeTraits::red()); tree_algorithms::rotate_left(x_parent, header); w = NodeTraits::get_right(x_parent); } if((NodeTraits::get_left(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) && (NodeTraits::get_right(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){ NodeTraits::set_color(w, NodeTraits::red()); x = x_parent; x_parent = NodeTraits::get_parent(x_parent); } else { if(NodeTraits::get_right(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){ NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black()); NodeTraits::set_color(w, NodeTraits::red()); tree_algorithms::rotate_right(w, header); w = NodeTraits::get_right(x_parent); } NodeTraits::set_color(w, NodeTraits::get_color(x_parent)); NodeTraits::set_color(x_parent, NodeTraits::black()); if(NodeTraits::get_right(w)) NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black()); tree_algorithms::rotate_left(x_parent, header); break; } } else { // same as above, with right_ <-> left_. node_ptr w = NodeTraits::get_left(x_parent); if(NodeTraits::get_color(w) == NodeTraits::red()){ NodeTraits::set_color(w, NodeTraits::black()); NodeTraits::set_color(x_parent, NodeTraits::red()); tree_algorithms::rotate_right(x_parent, header); w = NodeTraits::get_left(x_parent); } if((NodeTraits::get_right(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) && (NodeTraits::get_left(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){ NodeTraits::set_color(w, NodeTraits::red()); x = x_parent; x_parent = NodeTraits::get_parent(x_parent); } else { if(NodeTraits::get_left(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){ NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black()); NodeTraits::set_color(w, NodeTraits::red()); tree_algorithms::rotate_left(w, header); w = NodeTraits::get_left(x_parent); } NodeTraits::set_color(w, NodeTraits::get_color(x_parent)); NodeTraits::set_color(x_parent, NodeTraits::black()); if(NodeTraits::get_left(w)) NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black()); tree_algorithms::rotate_right(x_parent, header); break; } } } if(x) NodeTraits::set_color(x, NodeTraits::black()); } static void rebalance_after_insertion(const node_ptr & header, const node_ptr &pnode) { node_ptr p(pnode); NodeTraits::set_color(p, NodeTraits::red()); while(p != NodeTraits::get_parent(header) && NodeTraits::get_color(NodeTraits::get_parent(p)) == NodeTraits::red()){ node_ptr p_parent(NodeTraits::get_parent(p)); node_ptr p_parent_parent(NodeTraits::get_parent(p_parent)); if(tree_algorithms::is_left_child(p_parent)){ node_ptr x = NodeTraits::get_right(p_parent_parent); if(x && NodeTraits::get_color(x) == NodeTraits::red()){ NodeTraits::set_color(p_parent, NodeTraits::black()); NodeTraits::set_color(p_parent_parent, NodeTraits::red()); NodeTraits::set_color(x, NodeTraits::black()); p = p_parent_parent; } else { if(!tree_algorithms::is_left_child(p)){ p = p_parent; tree_algorithms::rotate_left(p, header); } node_ptr new_p_parent(NodeTraits::get_parent(p)); node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent)); NodeTraits::set_color(new_p_parent, NodeTraits::black()); NodeTraits::set_color(new_p_parent_parent, NodeTraits::red()); tree_algorithms::rotate_right(new_p_parent_parent, header); } } else{ node_ptr x = NodeTraits::get_left(p_parent_parent); if(x && NodeTraits::get_color(x) == NodeTraits::red()){ NodeTraits::set_color(p_parent, NodeTraits::black()); NodeTraits::set_color(p_parent_parent, NodeTraits::red()); NodeTraits::set_color(x, NodeTraits::black()); p = p_parent_parent; } else{ if(tree_algorithms::is_left_child(p)){ p = p_parent; tree_algorithms::rotate_right(p, header); } node_ptr new_p_parent(NodeTraits::get_parent(p)); node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent)); NodeTraits::set_color(new_p_parent, NodeTraits::black()); NodeTraits::set_color(new_p_parent_parent, NodeTraits::red()); tree_algorithms::rotate_left(new_p_parent_parent, header); } } } NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black()); } /// @endcond }; } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2007-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// namespace boost { namespace intrusive { //!This trait class is used to know if a pointer //!can embed extra bits of information if //!it's going to be used to point to objects //!with an alignment of "Alignment" bytes. template struct max_pointer_plus_bits { static const std::size_t value = 0; }; //!This is a specialization for raw pointers. //!Raw pointers can embed extra bits in the lower bits //!if the alignment is multiple of 2pow(NumBits). template struct max_pointer_plus_bits { static const std::size_t value = detail::ls_zeros::value; }; //!This is class that is supposed to have static methods //!to embed extra bits of information in a pointer. //!This is a declaration and there is no default implementation, //!because operations to embed the bits change with every pointer type. //! //!An implementation that detects that a pointer type whose //!has_pointer_plus_bits<>::value is non-zero can make use of these //!operations to embed the bits in the pointer. template struct pointer_plus_bits; //!This is the specialization to embed extra bits of information //!in a raw pointer. The extra bits are stored in the lower bits of the pointer. template struct pointer_plus_bits { static const std::size_t Mask = ((std::size_t(1u) << NumBits) - 1); typedef T* pointer; static pointer get_pointer(pointer n) { return pointer(std::size_t(n) & ~Mask); } static void set_pointer(pointer &n, pointer p) { std:: _assert((0 == (std::size_t(p) & Mask)) != 0, "Assertion failed, (" "0 == (std::size_t(p) & Mask)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/pointer_plus_bits.hpp" ", line " "65" "\n"); n = pointer(std::size_t(p) | (std::size_t(n) & Mask)); } static std::size_t get_bits(pointer n) { return (std::size_t(n) & Mask); } static void set_bits(pointer &n, std::size_t c) { std:: _assert((c <= Mask) != 0, "Assertion failed, (" "c <= Mask" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/pointer_plus_bits.hpp" ", line " "74" "\n"); n = pointer(std::size_t(get_pointer(n)) | c); } }; } //namespace intrusive } //namespace boost namespace boost { namespace intrusive { ///////////////////////////////////////////////////////////////////////////// // // // Generic node_traits for any pointer type // // // ///////////////////////////////////////////////////////////////////////////// //This is the compact representation: 3 pointers template struct compact_rbtree_node { typedef typename pointer_traits ::template rebind_pointer >::type node_ptr; enum color { red_t, black_t }; node_ptr parent_, left_, right_; }; //This is the normal representation: 3 pointers + enum template struct rbtree_node { typedef typename pointer_traits ::template rebind_pointer >::type node_ptr; enum color { red_t, black_t }; node_ptr parent_, left_, right_; color color_; }; //This is the default node traits implementation //using a node with 3 generic pointers plus an enum template struct default_rbtree_node_traits_impl { typedef rbtree_node node; typedef typename pointer_traits ::template rebind_pointer::type node_ptr; typedef typename pointer_traits ::template rebind_pointer::type const_node_ptr; typedef typename node::color color; static const node_ptr & get_parent(const const_node_ptr & n) { return n->parent_; } static void set_parent(const node_ptr & n, const node_ptr & p) { n->parent_ = p; } static const node_ptr & get_left(const const_node_ptr & n) { return n->left_; } static void set_left(const node_ptr & n, const node_ptr & l) { n->left_ = l; } static const node_ptr & get_right(const const_node_ptr & n) { return n->right_; } static void set_right(const node_ptr & n, const node_ptr & r) { n->right_ = r; } static color get_color(const const_node_ptr & n) { return n->color_; } static void set_color(const node_ptr & n, color c) { n->color_ = c; } static color black() { return node::black_t; } static color red() { return node::red_t; } }; //This is the compact node traits implementation //using a node with 3 generic pointers template struct compact_rbtree_node_traits_impl { typedef compact_rbtree_node node; typedef typename pointer_traits ::template rebind_pointer::type node_ptr; typedef typename pointer_traits ::template rebind_pointer::type const_node_ptr; typedef pointer_plus_bits ptr_bit; typedef typename node::color color; static node_ptr get_parent(const const_node_ptr & n) { return ptr_bit::get_pointer(n->parent_); } static void set_parent(const node_ptr & n, const node_ptr & p) { ptr_bit::set_pointer(n->parent_, p); } static const node_ptr & get_left(const const_node_ptr & n) { return n->left_; } static void set_left(const node_ptr & n, const node_ptr & l) { n->left_ = l; } static const node_ptr & get_right(const const_node_ptr & n) { return n->right_; } static void set_right(const node_ptr & n, const node_ptr & r) { n->right_ = r; } static color get_color(const const_node_ptr & n) { return (color)ptr_bit::get_bits(n->parent_); } static void set_color(const node_ptr & n, color c) { ptr_bit::set_bits(n->parent_, c != 0); } static color black() { return node::black_t; } static color red() { return node::red_t; } }; //Dispatches the implementation based on the boolean template struct rbtree_node_traits_dispatch : public default_rbtree_node_traits_impl {}; template struct rbtree_node_traits_dispatch : public compact_rbtree_node_traits_impl {}; //Inherit from the detail::link_dispatch depending on the embedding capabilities template struct rbtree_node_traits : public rbtree_node_traits_dispatch < VoidPointer , OptimizeSize && (max_pointer_plus_bits < VoidPointer , detail::alignment_of >::value >::value >= 1) > {}; } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2007-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { /// @cond struct default_tag; struct member_tag; namespace detail{ struct default_hook_tag{}; struct default_list_hook : public default_hook_tag{ template struct apply { typedef typename T::default_list_hook type; };}; struct default_slist_hook : public default_hook_tag{ template struct apply { typedef typename T::default_slist_hook type; };}; struct default_set_hook : public default_hook_tag{ template struct apply { typedef typename T::default_set_hook type; };}; struct default_uset_hook : public default_hook_tag{ template struct apply { typedef typename T::default_uset_hook type; };}; struct default_avl_set_hook : public default_hook_tag{ template struct apply { typedef typename T::default_avl_set_hook type; };}; struct default_splay_set_hook : public default_hook_tag{ template struct apply { typedef typename T::default_splay_set_hook type; };}; struct default_bs_set_hook : public default_hook_tag{ template struct apply { typedef typename T::default_bs_set_hook type; };}; template struct eval_value_traits { typedef typename ValueTraits::value_traits type; }; template struct external_bucket_traits_is_true { static const bool value = external_bucket_traits_bool::value == 3; }; template struct eval_bucket_traits { typedef typename BucketTraits::bucket_traits type; }; template struct concrete_hook_base_value_traits { typedef typename BaseHook::boost_intrusive_tags tags; typedef detail::base_hook_traits < T , typename tags::node_traits , tags::link_mode , typename tags::tag , tags::hook_type> type; }; template struct concrete_hook_base_node_traits { typedef typename BaseHook::boost_intrusive_tags::node_traits type; }; template struct any_hook_base_value_traits { typedef typename BaseHook::boost_intrusive_tags tags; typedef detail::base_hook_traits < T , typename BaseHook::node_traits , tags::link_mode , typename tags::tag , tags::hook_type> type; }; template struct any_hook_base_node_traits { typedef typename BaseHook::node_traits type; }; template struct get_base_value_traits { typedef typename detail::eval_if_c < internal_any_hook_bool_is_true::value , any_hook_base_value_traits , concrete_hook_base_value_traits >::type type; }; template struct get_base_node_traits { typedef typename detail::eval_if_c < internal_any_hook_bool_is_true::value , any_hook_base_node_traits , concrete_hook_base_node_traits >::type type; }; template struct get_member_value_traits { typedef typename MemberHook::member_value_traits type; }; template struct get_member_node_traits { typedef typename MemberHook::member_value_traits::node_traits type; }; template struct get_value_traits { typedef typename detail::eval_if_c ::value ,detail::apply ,detail::identity >::type supposed_value_traits; //...if it's a default hook typedef typename detail::eval_if_c < internal_base_hook_bool_is_true::value //...get it's internal value traits using //the provided T value type. , get_base_value_traits //...else use it's internal value traits tag //(member hooks and custom value traits are in this group) , detail::eval_if_c < internal_member_value_traits::value , get_member_value_traits , detail::identity > >::type type; }; template struct get_explicit_node_traits { typedef typename ValueTraits::node_traits type; }; template struct get_node_traits { typedef SupposedValueTraits supposed_value_traits; //...if it's a base hook typedef typename detail::eval_if_c < internal_base_hook_bool_is_true::value //...get it's internal value traits using //the provided T value type. , get_base_node_traits //...else use it's internal value traits tag //(member hooks and custom value traits are in this group) , detail::eval_if_c < internal_member_value_traits::value , get_member_node_traits , get_explicit_node_traits > >::type type; }; } //namespace detail{ //!This type indicates that no option is being used //!and that the default options should be used struct none { template struct pack : Base { }; }; /// @endcond //!This option setter specifies if the intrusive //!container stores its size as a member to //!obtain constant-time size() member. template struct constant_time_size { /// @cond template struct pack : Base { static const bool constant_time_size = Enabled; }; /// @endcond }; //!This option setter specifies the type that //!the container will use to store its size. template struct size_type { /// @cond template struct pack : Base { typedef SizeType size_type; }; /// @endcond }; //!This option setter specifies the strict weak ordering //!comparison functor for the value type template struct compare { /// @cond template struct pack : Base { typedef Compare compare; }; /// @endcond }; //!This option setter for scapegoat containers specifies if //!the intrusive scapegoat container should use a non-variable //!alpha value that does not need floating-point operations. //! //!If activated, the fixed alpha value is 1/sqrt(2). This //!option also saves some space in the container since //!the alpha value and some additional data does not need //!to be stored in the container. //! //!If the user only needs an alpha value near 1/sqrt(2), this //!option also improves performance since avoids logarithm //!and division operations when rebalancing the tree. template struct floating_point { /// @cond template struct pack : Base { static const bool floating_point = Enabled; }; /// @endcond }; //!This option setter specifies the equality //!functor for the value type template struct equal { /// @cond template struct pack : Base { typedef Equal equal; }; /// @endcond }; //!This option setter specifies the equality //!functor for the value type template struct priority { /// @cond template struct pack : Base { typedef Priority priority; }; /// @endcond }; //!This option setter specifies the hash //!functor for the value type template struct hash { /// @cond template struct pack : Base { typedef Hash hash; }; /// @endcond }; //!This option setter specifies the relationship between the type //!to be managed by the container (the value type) and the node to be //!used in the node algorithms. It also specifies the linking policy. template struct value_traits { /// @cond template struct pack : Base { typedef ValueTraits value_traits; }; /// @endcond }; //!This option setter specifies the member hook the //!container must use. template< typename Parent , typename MemberHook , MemberHook Parent::* PtrToMember> struct member_hook { /// @cond typedef detail::member_hook_traits < Parent , MemberHook , PtrToMember > member_value_traits; template struct pack : Base { typedef member_value_traits value_traits; }; /// @endcond }; //!This option setter specifies the function object that will //!be used to convert between values to be inserted in a container //!and the hook to be used for that purpose. template< typename Functor> struct function_hook { /// @cond typedef detail::function_hook_traits function_value_traits; template struct pack : Base { typedef function_value_traits value_traits; }; /// @endcond }; //!This option setter specifies that the container //!must use the specified base hook template struct base_hook { /// @cond template struct pack : Base { typedef BaseHook value_traits; }; /// @endcond }; //!This option setter specifies the type of //!a void pointer. This will instruct the hook //!to use this type of pointer instead of the //!default one template struct void_pointer { /// @cond template struct pack : Base { typedef VoidPointer void_pointer; }; /// @endcond }; //!This option setter specifies the type of //!the tag of a base hook. A type cannot have two //!base hooks of the same type, so a tag can be used //!to differentiate two base hooks with otherwise same type template struct tag { /// @cond template struct pack : Base { typedef Tag tag; }; /// @endcond }; //!This option setter specifies the link mode //!(normal_link, safe_link or auto_unlink) template struct link_mode { /// @cond template struct pack : Base { static const link_mode_type link_mode = LinkType; }; /// @endcond }; //!This option setter specifies if the hook //!should be optimized for size instead of for speed. template struct optimize_size { /// @cond template struct pack : Base { static const bool optimize_size = Enabled; }; /// @endcond }; //!This option setter specifies if the list container should //!use a linear implementation instead of a circular one. template struct linear { /// @cond template struct pack : Base { static const bool linear = Enabled; }; /// @endcond }; //!This option setter specifies if the list container should //!use a linear implementation instead of a circular one. template struct cache_last { /// @cond template struct pack : Base { static const bool cache_last = Enabled; }; /// @endcond }; //!This option setter specifies the bucket traits //!class for unordered associative containers. When this option is specified, //!instead of using the default bucket traits, a user defined holder will be defined template struct bucket_traits { /// @cond template struct pack : Base { typedef BucketTraits bucket_traits; }; /// @endcond }; //!This option setter specifies if the unordered hook //!should offer room to store the hash value. //!Storing the hash in the hook will speed up rehashing //!processes in applications where rehashing is frequent, //!rehashing might throw or the value is heavy to hash. template struct store_hash { /// @cond template struct pack : Base { static const bool store_hash = Enabled; }; /// @endcond }; //!This option setter specifies if the unordered hook //!should offer room to store another link to another node //!with the same key. //!Storing this link will speed up lookups and insertions on //!unordered_multiset containers with a great number of elements //!with the same key. template struct optimize_multikey { /// @cond template struct pack : Base { static const bool optimize_multikey = Enabled; }; /// @endcond }; //!This option setter specifies if the bucket array will be always power of two. //!This allows using masks instead of the default modulo operation to determine //!the bucket number from the hash value, leading to better performance. //!In debug mode, if power of two buckets mode is activated, the bucket length //!will be checked to through assertions to assure the bucket length is power of two. template struct power_2_buckets { /// @cond template struct pack : Base { static const bool power_2_buckets = Enabled; }; /// @endcond }; //!This option setter specifies if the container will cache a pointer to the first //!non-empty bucket so that begin() is always constant-time. //!This is specially helpful when we can have containers with a few elements //!but with big bucket arrays (that is, hashtables with low load factors). template struct cache_begin { /// @cond template struct pack : Base { static const bool cache_begin = Enabled; }; /// @endcond }; //!This option setter specifies if the container will compare the hash value //!before comparing objects. This option can't be specified if store_hash<> //!is not true. //!This is specially helpful when we have containers with a high load factor. //!and the comparison function is much more expensive that comparing already //!stored hash values. template struct compare_hash { /// @cond template struct pack : Base { static const bool compare_hash = Enabled; }; /// @endcond }; //!This option setter specifies if the hash container will use incremental //!hashing. With incremental hashing the cost of hash table expansion is spread //!out across each hash table insertion operation, as opposed to be incurred all at once. //!Therefore linear hashing is well suited for interactive applications or real-time //!appplications where the worst-case insertion time of non-incremental hash containers //!(rehashing the whole bucket array) is not admisible. template struct incremental { /// @cond template struct pack : Base { static const bool incremental = Enabled; }; /// @endcond }; /// @cond //To-do: pass to variadic templates template struct do_pack { //Use "pack" member template to pack options typedef typename Next::template pack type; }; template struct do_pack { //Avoid packing "none" to shorten template names typedef Prev type; }; template < class DefaultOptions , class O1 = none , class O2 = none , class O3 = none , class O4 = none , class O5 = none , class O6 = none , class O7 = none , class O8 = none , class O9 = none , class O10 = none , class O11 = none > struct pack_options { // join options typedef typename do_pack < typename do_pack < typename do_pack < typename do_pack < typename do_pack < typename do_pack < typename do_pack < typename do_pack < typename do_pack < typename do_pack < typename do_pack < DefaultOptions , O1 >::type , O2 >::type , O3 >::type , O4 >::type , O5 >::type , O6 >::type , O7 >::type , O8 >::type , O9 >::type , O10 >::type , O11 >::type type; }; struct hook_defaults : public pack_options < none , void_pointer , link_mode , tag , optimize_size , store_hash , linear , optimize_multikey >::type {}; /// @endcond } //namespace intrusive { } //namespace boost { ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2007-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { namespace detail { /// @cond enum { NoBaseHook , ListBaseHook , SlistBaseHook , SetBaseHook , UsetBaseHook , SplaySetBaseHook , AvlSetBaseHook , BsSetBaseHook , AnyBaseHook }; struct no_default_definer{}; template struct default_definer; template struct default_definer { typedef Hook default_list_hook; }; template struct default_definer { typedef Hook default_slist_hook; }; template struct default_definer { typedef Hook default_set_hook; }; template struct default_definer { typedef Hook default_uset_hook; }; template struct default_definer { typedef Hook default_splay_set_hook; }; template struct default_definer { typedef Hook default_avl_set_hook; }; template struct default_definer { typedef Hook default_bs_set_hook; }; template struct default_definer { typedef Hook default_any_hook; }; template struct make_default_definer { typedef typename detail::if_c < BaseHookType != 0 , default_definer , no_default_definer>::type type; }; template < class GetNodeAlgorithms , class Tag , link_mode_type LinkMode , int HookType > struct make_node_holder { typedef typename detail::if_c ::value , detail::node_holder < typename GetNodeAlgorithms::type::node , Tag , LinkMode , HookType> , typename GetNodeAlgorithms::type::node >::type type; }; /// @endcond template < class GetNodeAlgorithms , class Tag , link_mode_type LinkMode , int HookType > class generic_hook /// @cond //If the hook is a base hook, derive generic hook from detail::node_holder //so that a unique base class is created to convert from the node //to the type. This mechanism will be used by base_hook_traits. // //If the hook is a member hook, generic hook will directly derive //from the hook. : public make_default_definer < generic_hook , detail::is_same::value*HookType >::type , public make_node_holder::type /// @endcond { /// @cond typedef typename GetNodeAlgorithms::type node_algorithms; typedef typename node_algorithms::node node; typedef typename node_algorithms::node_ptr node_ptr; typedef typename node_algorithms::const_node_ptr const_node_ptr; public: struct boost_intrusive_tags { static const int hook_type = HookType; static const link_mode_type link_mode = LinkMode; typedef Tag tag; typedef typename GetNodeAlgorithms::type::node_traits node_traits; static const bool is_base_hook = !detail::is_same::value; static const bool safemode_or_autounlink = (int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link; }; node_ptr this_ptr() { return pointer_traits::pointer_to(static_cast(*this)); } const_node_ptr this_ptr() const { return pointer_traits::pointer_to(static_cast(*this)); } public: /// @endcond generic_hook() { if(boost_intrusive_tags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } generic_hook(const generic_hook& ) { if(boost_intrusive_tags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } generic_hook& operator=(const generic_hook& ) { return *this; } ~generic_hook() { destructor_impl (*this, detail::link_dispatch()); } void swap_nodes(generic_hook &other) { node_algorithms::swap_nodes (this->this_ptr(), other.this_ptr()); } bool is_linked() const { //is_linked() can be only used in safe-mode or auto-unlink typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)(( boost_intrusive_tags::safemode_or_autounlink )) >)> boost_static_assert_typedef_191; return !node_algorithms::unique(this->this_ptr()); } void unlink() { typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink )) >)> boost_static_assert_typedef_197; node_algorithms::unlink(this->this_ptr()); node_algorithms::init(this->this_ptr()); } }; } //namespace detail } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// namespace boost { namespace intrusive { /// @cond template struct get_set_node_algo { typedef rbtree_algorithms > type; }; /// @endcond //! Helper metafunction to define a \c set_base_hook that yields to the same //! type when the same options (either explicitly or implicitly) are used. template struct make_set_base_hook { /// @cond typedef typename pack_options < hook_defaults, O1, O2, O3, O4 >::type packed_options; typedef detail::generic_hook < get_set_node_algo , typename packed_options::tag , packed_options::link_mode , detail::SetBaseHook > implementation_defined; /// @endcond typedef implementation_defined type; }; //! Derive a class from set_base_hook in order to store objects in //! in a set/multiset. set_base_hook holds the data necessary to maintain //! the set/multiset and provides an appropriate value_traits class for set/multiset. //! //! The hook admits the following options: \c tag<>, \c void_pointer<>, //! \c link_mode<> and \c optimize_size<>. //! //! \c tag<> defines a tag to identify the node. //! The same tag value can be used in different classes, but if a class is //! derived from more than one \c list_base_hook, then each \c list_base_hook needs its //! unique tag. //! //! \c void_pointer<> is the pointer type that will be used internally in the hook //! and the the container configured to use this hook. //! //! \c link_mode<> will specify the linking mode of the hook (\c normal_link, //! \c auto_unlink or \c safe_link). //! //! \c optimize_size<> will tell the hook to optimize the hook for size instead //! of speed. template class set_base_hook : public make_set_base_hook< O1, O2, O3, O4 >::type { }; //! Helper metafunction to define a \c set_member_hook that yields to the same //! type when the same options (either explicitly or implicitly) are used. template struct make_set_member_hook { /// @cond typedef typename pack_options < hook_defaults, O1, O2, O3, O4 >::type packed_options; typedef detail::generic_hook < get_set_node_algo , member_tag , packed_options::link_mode , detail::NoBaseHook > implementation_defined; /// @endcond typedef implementation_defined type; }; //! Put a public data member set_member_hook in order to store objects of this class in //! a set/multiset. set_member_hook holds the data necessary for maintaining the //! set/multiset and provides an appropriate value_traits class for set/multiset. //! //! The hook admits the following options: \c void_pointer<>, //! \c link_mode<> and \c optimize_size<>. //! //! \c void_pointer<> is the pointer type that will be used internally in the hook //! and the the container configured to use this hook. //! //! \c link_mode<> will specify the linking mode of the hook (\c normal_link, //! \c auto_unlink or \c safe_link). //! //! \c optimize_size<> will tell the hook to optimize the hook for size instead //! of speed. template class set_member_hook : public make_set_member_hook< O1, O2, O3, O4 >::type { }; } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2007. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { template struct tree_node { typedef typename pointer_traits ::template rebind_pointer >::type node_ptr; node_ptr parent_, left_, right_; }; template struct tree_node_traits { typedef tree_node node; typedef typename pointer_traits::template rebind_pointer::type node_ptr; typedef typename pointer_traits::template rebind_pointer::type const_node_ptr; static const node_ptr & get_parent(const const_node_ptr & n) { return n->parent_; } static void set_parent(const node_ptr & n, const node_ptr & p) { n->parent_ = p; } static const node_ptr & get_left(const const_node_ptr & n) { return n->left_; } static void set_left(const node_ptr & n, const node_ptr & l) { n->left_ = l; } static const node_ptr & get_right(const const_node_ptr & n) { return n->right_; } static void set_right(const node_ptr & n, const node_ptr & r) { n->right_ = r; } }; ///////////////////////////////////////////////////////////////////////////// // // // Implementation of the tree iterator // // // ///////////////////////////////////////////////////////////////////////////// // tree_iterator provides some basic functions for a // node oriented bidirectional iterator: template class tree_iterator : public std::iterator < std::bidirectional_iterator_tag , typename Container::value_type , typename Container::difference_type , typename detail::if_c::type , typename detail::if_c::type > { protected: typedef typename Container::real_value_traits real_value_traits; typedef typename Container::node_algorithms node_algorithms; typedef typename real_value_traits::node_traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename pointer_traits::template rebind_pointer::type void_pointer; static const bool store_container_ptr = detail::store_cont_ptr_on_it::value; public: typedef typename Container::value_type value_type; typedef typename detail::if_c::type pointer; typedef typename detail::if_c::type reference; tree_iterator() : members_ (node_ptr(), (const void *)0) {} explicit tree_iterator(const node_ptr & nodeptr, const Container *cont_ptr) : members_ (nodeptr, cont_ptr) {} tree_iterator(tree_iterator const& other) : members_(other.pointed_node(), other.get_container()) {} const node_ptr &pointed_node() const { return members_.nodeptr_; } tree_iterator &operator=(const node_ptr &nodeptr) { members_.nodeptr_ = nodeptr; return static_cast(*this); } public: tree_iterator& operator++() { members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_); return static_cast (*this); } tree_iterator operator++(int) { tree_iterator result (*this); members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_); return result; } tree_iterator& operator--() { members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_); return static_cast (*this); } tree_iterator operator--(int) { tree_iterator result (*this); members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_); return result; } friend bool operator== (const tree_iterator& l, const tree_iterator& r) { return l.pointed_node() == r.pointed_node(); } friend bool operator!= (const tree_iterator& l, const tree_iterator& r) { return !(l == r); } reference operator*() const { return *operator->(); } pointer operator->() const { return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); } const Container *get_container() const { return static_cast(members_.get_ptr()); } const real_value_traits *get_real_value_traits() const { return &this->get_container()->get_real_value_traits(); } tree_iterator end_iterator_from_it() const { return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_container()); } tree_iterator unconst() const { return tree_iterator(this->pointed_node(), this->get_container()); } private: struct members : public detail::select_constptr ::type { typedef typename detail::select_constptr ::type Base; members(const node_ptr &n_ptr, const void *cont) : Base(cont), nodeptr_(n_ptr) {} node_ptr nodeptr_; } members_; }; } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //////} // /////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE //#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE namespace boost { namespace intrusive { namespace detail { template class clear_on_destructor_base { protected: ~clear_on_destructor_base() { static_cast(this)->clear(); } }; } // namespace detail { } // namespace intrusive { } // namespace boost { ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// namespace boost { namespace intrusive { /// @cond template struct setopt { typedef ValueTraits value_traits; typedef Compare compare; typedef SizeType size_type; static const bool constant_time_size = ConstantTimeSize; }; template struct set_defaults : pack_options < none , base_hook , constant_time_size , size_type , compare > >::type {}; /// @endcond //! The class template rbtree is an intrusive red-black tree container, that //! is used to construct intrusive set and multiset containers. The no-throw //! guarantee holds only, if the value_compare object //! doesn't throw. //! //! The template parameter \c T is the type to be managed by the container. //! The user can specify additional options and if no options are provided //! default options are used. //! //! The container supports the following options: //! \c base_hook<>/member_hook<>/value_traits<>, //! \c constant_time_size<>, \c size_type<> and //! \c compare<>. template class rbtree_impl : private detail::clear_on_destructor_base > { template friend class detail::clear_on_destructor_base; public: typedef typename Config::value_traits value_traits; /// @cond static const bool external_value_traits = detail::external_value_traits_is_true::value; typedef typename detail::eval_if_c < external_value_traits , detail::eval_value_traits , detail::identity >::type real_value_traits; /// @endcond typedef typename real_value_traits::pointer pointer; typedef typename real_value_traits::const_pointer const_pointer; typedef typename pointer_traits::element_type value_type; typedef value_type key_type; typedef typename pointer_traits::reference reference; typedef typename pointer_traits::reference const_reference; typedef typename pointer_traits::difference_type difference_type; typedef typename Config::size_type size_type; typedef typename Config::compare value_compare; typedef value_compare key_compare; typedef tree_iterator iterator; typedef tree_iterator const_iterator; typedef boost::intrusive::detail::reverse_iterator reverse_iterator; typedef boost::intrusive::detail::reverse_iteratorconst_reverse_iterator; typedef typename real_value_traits::node_traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef rbtree_algorithms node_algorithms; static const bool constant_time_size = Config::constant_time_size; static const bool stateful_value_traits = detail::is_stateful_value_traits::value; /// @cond private: typedef detail::size_holder size_traits; //noncopyable private: rbtree_impl(rbtree_impl &); rbtree_impl& operator=(rbtree_impl &); public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || (int)real_value_traits::link_mode == (int)safe_link }; //Constant-time size is incompatible with auto-unlink hooks! typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))) >)> boost_static_assert_typedef_134; struct header_plus_size : public size_traits { node header_; }; struct node_plus_pred_t : public detail::ebo_functor_holder { node_plus_pred_t(const value_compare &comp) : detail::ebo_functor_holder(comp) {} header_plus_size header_plus_size_; }; struct data_t : public rbtree_impl::value_traits { typedef typename rbtree_impl::value_traits value_traits; data_t(const value_compare & comp, const value_traits &val_traits) : value_traits(val_traits), node_plus_pred_(comp) {} node_plus_pred_t node_plus_pred_; } data_; const value_compare &priv_comp() const { return data_.node_plus_pred_.get(); } value_compare &priv_comp() { return data_.node_plus_pred_.get(); } const value_traits &priv_value_traits() const { return data_; } value_traits &priv_value_traits() { return data_; } node_ptr priv_header_ptr() { return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); } const_node_ptr priv_header_ptr() const { return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); } static node_ptr uncast(const const_node_ptr & ptr) { return pointer_traits::const_cast_from(ptr); } size_traits &priv_size_traits() { return data_.node_plus_pred_.header_plus_size_; } const size_traits &priv_size_traits() const { return data_.node_plus_pred_.header_plus_size_; } const real_value_traits &get_real_value_traits(detail::bool_) const { return data_; } const real_value_traits &get_real_value_traits(detail::bool_) const { return data_.get_value_traits(*this); } real_value_traits &get_real_value_traits(detail::bool_) { return data_; } real_value_traits &get_real_value_traits(detail::bool_) { return data_.get_value_traits(*this); } protected: value_compare &prot_comp() { return priv_comp(); } const node &prot_header_node() const { return data_.node_plus_pred_.header_plus_size_.header_; } node &prot_header_node() { return data_.node_plus_pred_.header_plus_size_.header_; } void prot_set_size(size_type s) { this->priv_size_traits().set_size(s); } /// @endcond public: const real_value_traits &get_real_value_traits() const { return this->get_real_value_traits(detail::bool_()); } real_value_traits &get_real_value_traits() { return this->get_real_value_traits(detail::bool_()); } typedef typename node_algorithms::insert_commit_data insert_commit_data; //! Effects: Constructs an empty tree. //! //! Complexity: Constant. //! //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the copy constructorof the value_compare object throws. Basic guarantee. rbtree_impl( const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) : data_(cmp, v_traits) { node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(size_type(0)); } //! Requires: Dereferencing iterator must yield an lvalue of type value_type. //! cmp must be a comparison function that induces a strict weak ordering. //! //! Effects: Constructs an empty tree and inserts elements from //! [b, e). //! //! Complexity: Linear in N if [b, e) is already sorted using //! comp and otherwise N * log N, where N is the distance between first and last. //! //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee. template rbtree_impl( bool unique, Iterator b, Iterator e , const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) : data_(cmp, v_traits) { node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(size_type(0)); if(unique) this->insert_unique(b, e); else this->insert_equal(b, e); } //! Effects: to-do //! rbtree_impl(::boost::rv< rbtree_impl > & x) : data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits())) { node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(size_type(0)); this->swap(x); } //! Effects: to-do //! rbtree_impl& operator=(::boost::rv< rbtree_impl > & x) { this->swap(x); return *this; } //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called), but the nodes according to //! the value_traits template parameter are reinitialized and thus can be reused. //! //! Complexity: Linear to elements contained in *this. //! //! Throws: Nothing. ~rbtree_impl() {} //! Effects: Returns an iterator pointing to the beginning of the tree. //! //! Complexity: Constant. //! //! Throws: Nothing. iterator begin() { return iterator (node_traits::get_left(this->priv_header_ptr()), this); } //! Effects: Returns a const_iterator pointing to the beginning of the tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_iterator begin() const { return cbegin(); } //! Effects: Returns a const_iterator pointing to the beginning of the tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_iterator cbegin() const { return const_iterator (node_traits::get_left(this->priv_header_ptr()), this); } //! Effects: Returns an iterator pointing to the end of the tree. //! //! Complexity: Constant. //! //! Throws: Nothing. iterator end() { return iterator (this->priv_header_ptr(), this); } //! Effects: Returns a const_iterator pointing to the end of the tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_iterator end() const { return cend(); } //! Effects: Returns a const_iterator pointing to the end of the tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_iterator cend() const { return const_iterator (uncast(this->priv_header_ptr()), this); } //! Effects: Returns a reverse_iterator pointing to the beginning of the //! reversed tree. //! //! Complexity: Constant. //! //! Throws: Nothing. reverse_iterator rbegin() { return reverse_iterator(end()); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed tree. //! //! Complexity: Constant. //! //! Throws: Nothing. reverse_iterator rend() { return reverse_iterator(begin()); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed tree. //! //! Complexity: Constant. //! //! Throws: Nothing. const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } //! Precondition: end_iterator must be a valid end iterator //! of rbtree. //! //! Effects: Returns a const reference to the rbtree associated to the end iterator //! //! Throws: Nothing. //! //! Complexity: Constant. static rbtree_impl &container_from_end_iterator(iterator end_iterator) { return priv_container_from_end_iterator(end_iterator); } //! Precondition: end_iterator must be a valid end const_iterator //! of rbtree. //! //! Effects: Returns a const reference to the rbtree associated to the iterator //! //! Throws: Nothing. //! //! Complexity: Constant. static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator) { return priv_container_from_end_iterator(end_iterator); } //! Precondition: it must be a valid iterator //! of rbtree. //! //! Effects: Returns a const reference to the tree associated to the iterator //! //! Throws: Nothing. //! //! Complexity: Logarithmic. static rbtree_impl &container_from_iterator(iterator it) { return priv_container_from_iterator(it); } //! Precondition: it must be a valid end const_iterator //! of rbtree. //! //! Effects: Returns a const reference to the tree associated to the end iterator //! //! Throws: Nothing. //! //! Complexity: Logarithmic. static const rbtree_impl &container_from_iterator(const_iterator it) { return priv_container_from_iterator(it); } //! Effects: Returns the value_compare object used by the tree. //! //! Complexity: Constant. //! //! Throws: If value_compare copy-constructor throws. value_compare value_comp() const { return priv_comp(); } //! Effects: Returns true if the container is empty. //! //! Complexity: Constant. //! //! Throws: Nothing. bool empty() const { return node_algorithms::unique(this->priv_header_ptr()); } //! Effects: Returns the number of elements stored in the tree. //! //! Complexity: Linear to elements contained in *this //! if constant-time size option is disabled. Constant time otherwise. //! //! Throws: Nothing. size_type size() const { if(constant_time_size) return this->priv_size_traits().get_size(); else{ return (size_type)node_algorithms::size(this->priv_header_ptr()); } } //! Effects: Swaps the contents of two rbtrees. //! //! Complexity: Constant. //! //! Throws: If the comparison functor's swap call throws. void swap(rbtree_impl& other) { //This can throw using std::swap; swap(priv_comp(), priv_comp()); //These can't throw node_algorithms::swap_tree(this->priv_header_ptr(), node_ptr(other.priv_header_ptr())); if(constant_time_size){ size_type backup = this->priv_size_traits().get_size(); this->priv_size_traits().set_size(other.priv_size_traits().get_size()); other.priv_size_traits().set_size(backup); } } //! Requires: value must be an lvalue //! //! Effects: Inserts value into the tree before the upper bound. //! //! Complexity: Average complexity for insert element is at //! most logarithmic. //! //! Throws: If the internal value_compare ordering function throws. Strong guarantee. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. iterator insert_equal(reference value) { detail::key_nodeptr_comp key_node_comp(priv_comp(), this); node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) std:: _assert((node_algorithms::unique(to_insert)) != 0, "Assertion failed, (" "node_algorithms::unique(to_insert)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/rbtree.hpp" ", line " "499" "\n"); iterator ret(node_algorithms::insert_equal_upper_bound (this->priv_header_ptr(), to_insert, key_node_comp), this); this->priv_size_traits().increment(); return ret; } //! Requires: value must be an lvalue, and "hint" must be //! a valid iterator. //! //! Effects: Inserts x into the tree, using "hint" as a hint to //! where it will be inserted. If "hint" is the upper_bound //! the insertion takes constant time (two comparisons in the worst case) //! //! Complexity: Logarithmic in general, but it is amortized //! constant time if t is inserted immediately before hint. //! //! Throws: If the internal value_compare ordering function throws. Strong guarantee. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. iterator insert_equal(const_iterator hint, reference value) { detail::key_nodeptr_comp key_node_comp(priv_comp(), this); node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) std:: _assert((node_algorithms::unique(to_insert)) != 0, "Assertion failed, (" "node_algorithms::unique(to_insert)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/rbtree.hpp" ", line " "526" "\n"); iterator ret(node_algorithms::insert_equal (this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this); this->priv_size_traits().increment(); return ret; } //! Requires: Dereferencing iterator must yield an lvalue //! of type value_type. //! //! Effects: Inserts a each element of a range into the tree //! before the upper bound of the key of each element. //! //! Complexity: Insert range is in general O(N * log(N)), where N is the //! size of the range. However, it is linear in N if the range is already sorted //! by value_comp(). //! //! Throws: Nothing. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. template void insert_equal(Iterator b, Iterator e) { iterator iend(this->end()); for (; b != e; ++b) this->insert_equal(iend, *b); } //! Requires: value must be an lvalue //! //! Effects: Inserts value into the tree if the value //! is not already present. //! //! Complexity: Average complexity for insert element is at //! most logarithmic. //! //! Throws: Nothing. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. std::pair insert_unique(reference value) { insert_commit_data commit_data; std::pair ret = insert_unique_check(value, priv_comp(), commit_data); if(!ret.second) return ret; return std::pair (insert_unique_commit(value, commit_data), true); } //! Requires: value must be an lvalue, and "hint" must be //! a valid iterator //! //! Effects: Tries to insert x into the tree, using "hint" as a hint //! to where it will be inserted. //! //! Complexity: Logarithmic in general, but it is amortized //! constant time (two comparisons in the worst case) //! if t is inserted immediately before hint. //! //! Throws: Nothing. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. iterator insert_unique(const_iterator hint, reference value) { insert_commit_data commit_data; std::pair ret = insert_unique_check(hint, value, priv_comp(), commit_data); if(!ret.second) return ret.first; return insert_unique_commit(value, commit_data); } //! Requires: Dereferencing iterator must yield an lvalue //! of type value_type. //! //! Effects: Tries to insert each element of a range into the tree. //! //! Complexity: Insert range is in general O(N * log(N)), where N is the //! size of the range. However, it is linear in N if the range is already sorted //! by value_comp(). //! //! Throws: Nothing. //! //! Note: Does not affect the validity of iterators and references. //! No copy-constructors are called. template void insert_unique(Iterator b, Iterator e) { if(this->empty()){ iterator iend(this->end()); for (; b != e; ++b) this->insert_unique(iend, *b); } else{ for (; b != e; ++b) this->insert_unique(*b); } } //! Requires: key_value_comp must be a comparison function that induces //! the same strict weak ordering as value_compare. The difference is that //! key_value_comp compares an arbitrary key with the contained values. //! //! Effects: Checks if a value can be inserted in the container, using //! a user provided key instead of the value itself. //! //! Returns: If there is an equivalent value //! returns a pair containing an iterator to the already present value //! and false. If the value can be inserted returns true in the returned //! pair boolean and fills "commit_data" that is meant to be used with //! the "insert_commit" function. //! //! Complexity: Average complexity is at most logarithmic. //! //! Throws: If the key_value_comp ordering function throws. Strong guarantee. //! //! Notes: This function is used to improve performance when constructing //! a value_type is expensive: if there is an equivalent value //! the constructed object must be discarded. Many times, the part of the //! node that is used to impose the order is much cheaper to construct //! than the value_type and this function offers the possibility to use that //! part to check if the insertion will be successful. //! //! If the check is successful, the user can construct the value_type and use //! "insert_commit" to insert the object in constant-time. This gives a total //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). //! //! "commit_data" remains valid for a subsequent "insert_commit" only if no more //! objects are inserted or erased from the container. template std::pair insert_unique_check (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) { detail::key_nodeptr_comp comp(key_value_comp, this); std::pair ret = (node_algorithms::insert_unique_check (this->priv_header_ptr(), key, comp, commit_data)); return std::pair(iterator(ret.first, this), ret.second); } //! Requires: key_value_comp must be a comparison function that induces //! the same strict weak ordering as value_compare. The difference is that //! key_value_comp compares an arbitrary key with the contained values. //! //! Effects: Checks if a value can be inserted in the container, using //! a user provided key instead of the value itself, using "hint" //! as a hint to where it will be inserted. //! //! Returns: If there is an equivalent value //! returns a pair containing an iterator to the already present value //! and false. If the value can be inserted returns true in the returned //! pair boolean and fills "commit_data" that is meant to be used with //! the "insert_commit" function. //! //! Complexity: Logarithmic in general, but it's amortized //! constant time if t is inserted immediately before hint. //! //! Throws: If the key_value_comp ordering function throws. Strong guarantee. //! //! Notes: This function is used to improve performance when constructing //! a value_type is expensive: if there is an equivalent value //! the constructed object must be discarded. Many times, the part of the //! constructing that is used to impose the order is much cheaper to construct //! than the value_type and this function offers the possibility to use that key //! to check if the insertion will be successful. //! //! If the check is successful, the user can construct the value_type and use //! "insert_commit" to insert the object in constant-time. This can give a total //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). //! //! "commit_data" remains valid for a subsequent "insert_commit" only if no more //! objects are inserted or erased from the container. template std::pair insert_unique_check (const_iterator hint, const KeyType &key ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) { detail::key_nodeptr_comp comp(key_value_comp, this); std::pair ret = (node_algorithms::insert_unique_check (this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data)); return std::pair(iterator(ret.first, this), ret.second); } //! Requires: value must be an lvalue of type value_type. commit_data //! must have been obtained from a previous call to "insert_check". //! No objects should have been inserted or erased from the container between //! the "insert_check" that filled "commit_data" and the call to "insert_commit". //! //! Effects: Inserts the value in the avl_set using the information obtained //! from the "commit_data" that a previous "insert_check" filled. //! //! Returns: An iterator to the newly inserted object. //! //! Complexity: Constant time. //! //! Throws: Nothing. //! //! Notes: This function has only sense if a "insert_check" has been //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) { node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) std:: _assert((node_algorithms::unique(to_insert)) != 0, "Assertion failed, (" "node_algorithms::unique(to_insert)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/rbtree.hpp" ", line " "734" "\n"); node_algorithms::insert_unique_commit (this->priv_header_ptr(), to_insert, commit_data); this->priv_size_traits().increment(); return iterator(to_insert, this); } //! Requires: value must be an lvalue, "pos" must be //! a valid iterator (or end) and must be the succesor of value //! once inserted according to the predicate //! //! Effects: Inserts x into the tree before "pos". //! //! Complexity: Constant time. //! //! Throws: Nothing. //! //! Note: This function does not check preconditions so if "pos" is not //! the successor of "value" tree ordering invariant will be broken. //! This is a low-level function to be used only for performance reasons //! by advanced users. iterator insert_before(const_iterator pos, reference value) { node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) std:: _assert((node_algorithms::unique(to_insert)) != 0, "Assertion failed, (" "node_algorithms::unique(to_insert)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/rbtree.hpp" ", line " "759" "\n"); this->priv_size_traits().increment(); return iterator(node_algorithms::insert_before (this->priv_header_ptr(), pos.pointed_node(), to_insert), this); } //! Requires: value must be an lvalue, and it must be no less //! than the greatest inserted key //! //! Effects: Inserts x into the tree in the last position. //! //! Complexity: Constant time. //! //! Throws: Nothing. //! //! Note: This function does not check preconditions so if value is //! less than the greatest inserted key tree ordering invariant will be broken. //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. void push_back(reference value) { node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) std:: _assert((node_algorithms::unique(to_insert)) != 0, "Assertion failed, (" "node_algorithms::unique(to_insert)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/rbtree.hpp" ", line " "783" "\n"); this->priv_size_traits().increment(); node_algorithms::push_back(this->priv_header_ptr(), to_insert); } //! Requires: value must be an lvalue, and it must be no greater //! than the minimum inserted key //! //! Effects: Inserts x into the tree in the first position. //! //! Complexity: Constant time. //! //! Throws: Nothing. //! //! Note: This function does not check preconditions so if value is //! greater than the minimum inserted key tree ordering invariant will be broken. //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. void push_front(reference value) { node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) std:: _assert((node_algorithms::unique(to_insert)) != 0, "Assertion failed, (" "node_algorithms::unique(to_insert)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/rbtree.hpp" ", line " "806" "\n"); this->priv_size_traits().increment(); node_algorithms::push_front(this->priv_header_ptr(), to_insert); } //! Effects: Erases the element pointed to by pos. //! //! Complexity: Average complexity for erase element is constant time. //! //! Throws: Nothing. //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. iterator erase(const_iterator i) { const_iterator ret(i); ++ret; node_ptr to_erase(i.pointed_node()); if(safemode_or_autounlink) std:: _assert((!node_algorithms::unique(to_erase)) != 0, "Assertion failed, (" "!node_algorithms::unique(to_erase)" "), file " "E:/boost/include/boost-1_50_0_ti/boost/intrusive/rbtree.hpp" ", line " "825" "\n"); node_algorithms::erase(this->priv_header_ptr(), to_erase); this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); return ret.unconst(); } //! Effects: Erases the range pointed to by b end e. //! //! Complexity: Average complexity for erase range is at most //! O(log(size() + N)), where N is the number of elements in the range. //! //! Throws: Nothing. //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. iterator erase(const_iterator b, const_iterator e) { size_type n; return private_erase(b, e, n); } //! Effects: Erases all the elements with the given value. //! //! Returns: The number of erased elements. //! //! Complexity: O(log(size() + N). //! //! Throws: Nothing. //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. size_type erase(const_reference value) { return this->erase(value, priv_comp()); } //! Effects: Erases all the elements with the given key. //! according to the comparison functor "comp". //! //! Returns: The number of erased elements. //! //! Complexity: O(log(size() + N). //! //! Throws: Nothing. //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. template size_type erase(const KeyType& key, KeyValueCompare comp /// @cond , typename detail::enable_if_c::value >::type * = 0 /// @endcond ) { std::pair p = this->equal_range(key, comp); size_type n; private_erase(p.first, p.second, n); return n; } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! //! Effects: Erases the element pointed to by pos. //! Disposer::operator()(pointer) is called for the removed element. //! //! Complexity: Average complexity for erase element is constant time. //! //! Throws: Nothing. //! //! Note: Invalidates the iterators //! to the erased elements. template iterator erase_and_dispose(const_iterator i, Disposer disposer) { node_ptr to_erase(i.pointed_node()); iterator ret(this->erase(i)); disposer(get_real_value_traits().to_value_ptr(to_erase)); return ret; } template iterator erase_and_dispose(iterator i, Disposer disposer) { return this->erase_and_dispose(const_iterator(i), disposer); } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! //! Effects: Erases all the elements with the given value. //! Disposer::operator()(pointer) is called for the removed elements. //! //! Returns: The number of erased elements. //! //! Complexity: O(log(size() + N). //! //! Throws: Nothing. //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. template size_type erase_and_dispose(const_reference value, Disposer disposer) { std::pair p = this->equal_range(value); size_type n; private_erase(p.first, p.second, n, disposer); return n; } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! //! Effects: Erases the range pointed to by b end e. //! Disposer::operator()(pointer) is called for the removed elements. //! //! Complexity: Average complexity for erase range is at most //! O(log(size() + N)), where N is the number of elements in the range. //! //! Throws: Nothing. //! //! Note: Invalidates the iterators //! to the erased elements. template iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) { size_type n; return private_erase(b, e, n, disposer); } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! //! Effects: Erases all the elements with the given key. //! according to the comparison functor "comp". //! Disposer::operator()(pointer) is called for the removed elements. //! //! Returns: The number of erased elements. //! //! Complexity: O(log(size() + N). //! //! Throws: Nothing. //! //! Note: Invalidates the iterators //! to the erased elements. template size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer /// @cond , typename detail::enable_if_c::value >::type * = 0 /// @endcond ) { std::pair p = this->equal_range(key, comp); size_type n; private_erase(p.first, p.second, n, disposer); return n; } //! Effects: Erases all of the elements. //! //! Complexity: Linear to the number of elements on the container. //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. //! //! Throws: Nothing. //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. void clear() { if(safemode_or_autounlink){ this->clear_and_dispose(detail::null_disposer()); } else{ node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(0); } } //! Effects: Erases all of the elements calling disposer(p) for //! each node to be erased. //! Complexity: Average complexity for is at most O(log(size() + N)), //! where N is the number of elements in the container. //! //! Throws: Nothing. //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. Calls N times to disposer functor. template void clear_and_dispose(Disposer disposer) { node_algorithms::clear_and_dispose(this->priv_header_ptr() , detail::node_disposer(disposer, this)); node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(0); } //! Effects: Returns the number of contained elements with the given value //! //! Complexity: Logarithmic to the number of elements contained plus lineal //! to number of objects with the given value. //! //! Throws: Nothing. size_type count(const_reference value) const { return this->count(value, priv_comp()); } //! Effects: Returns the number of contained elements with the given key //! //! Complexity: Logarithmic to the number of elements contained plus lineal //! to number of objects with the given key. //! //! Throws: Nothing. template size_type count(const KeyType &key, KeyValueCompare comp) const { std::pair ret = this->equal_range(key, comp); return std::distance(ret.first, ret.second); } //! Effects: Returns an iterator to the first element whose //! key is not less than k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. iterator lower_bound(const_reference value) { return this->lower_bound(value, priv_comp()); } //! Effects: Returns an iterator to the first element whose //! key is not less than k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. const_iterator lower_bound(const_reference value) const { return this->lower_bound(value, priv_comp()); } //! Effects: Returns an iterator to the first element whose //! key is not less than k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template iterator lower_bound(const KeyType &key, KeyValueCompare comp) { detail::key_nodeptr_comp key_node_comp(comp, this); return iterator(node_algorithms::lower_bound (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Returns a const iterator to the first element whose //! key is not less than k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const { detail::key_nodeptr_comp key_node_comp(comp, this); return const_iterator(node_algorithms::lower_bound (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Returns an iterator to the first element whose //! key is greater than k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. iterator upper_bound(const_reference value) { return this->upper_bound(value, priv_comp()); } //! Effects: Returns an iterator to the first element whose //! key is greater than k according to comp or end() if that element //! does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template iterator upper_bound(const KeyType &key, KeyValueCompare comp) { detail::key_nodeptr_comp key_node_comp(comp, this); return iterator(node_algorithms::upper_bound (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Returns an iterator to the first element whose //! key is greater than k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. const_iterator upper_bound(const_reference value) const { return this->upper_bound(value, priv_comp()); } //! Effects: Returns an iterator to the first element whose //! key is greater than k according to comp or end() if that element //! does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const { detail::key_nodeptr_comp key_node_comp(comp, this); return const_iterator(node_algorithms::upper_bound (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Finds an iterator to the first element whose key is //! k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. iterator find(const_reference value) { return this->find(value, priv_comp()); } //! Effects: Finds an iterator to the first element whose key is //! k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template iterator find(const KeyType &key, KeyValueCompare comp) { detail::key_nodeptr_comp key_node_comp(comp, this); return iterator (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Finds a const_iterator to the first element whose key is //! k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. const_iterator find(const_reference value) const { return this->find(value, priv_comp()); } //! Effects: Finds a const_iterator to the first element whose key is //! k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template const_iterator find(const KeyType &key, KeyValueCompare comp) const { detail::key_nodeptr_comp key_node_comp(comp, this); return const_iterator (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Finds a range containing all elements whose key is k or //! an empty range that indicates the position where those elements would be //! if they there is no elements with key k. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. std::pair equal_range(const_reference value) { return this->equal_range(value, priv_comp()); } //! Effects: Finds a range containing all elements whose key is k or //! an empty range that indicates the position where those elements would be //! if they there is no elements with key k. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template std::pair equal_range(const KeyType &key, KeyValueCompare comp) { detail::key_nodeptr_comp key_node_comp(comp, this); std::pair ret (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp)); return std::pair(iterator(ret.first, this), iterator(ret.second, this)); } //! Effects: Finds a range containing all elements whose key is k or //! an empty range that indicates the position where those elements would be //! if they there is no elements with key k. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. std::pair equal_range(const_reference value) const { return this->equal_range(value, priv_comp()); } //! Effects: Finds a range containing all elements whose key is k or //! an empty range that indicates the position where those elements would be //! if they there is no elements with key k. //! //! Complexity: Logarithmic. //! //! Throws: Nothing. template std::pair equal_range(const KeyType &key, KeyValueCompare comp) const { detail::key_nodeptr_comp key_node_comp(comp, this); std::pair ret (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp)); return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! Cloner should yield to nodes equivalent to the original nodes. //! //! Effects: Erases all the elements from *this //! calling Disposer::operator()(pointer), clones all the //! elements from src calling Cloner::operator()(const_reference ) //! and inserts them on *this. Copies the predicate from the source container. //! //! If cloner throws, all cloned elements are unlinked and disposed //! calling Disposer::operator()(pointer). //! //! Complexity: Linear to erased plus inserted elements. //! //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee. template void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer) { this->clear_and_dispose(disposer); if(!src.empty()){ detail::exception_disposer rollback(*this, disposer); node_algorithms::clone (const_node_ptr(src.priv_header_ptr()) ,node_ptr(this->priv_header_ptr()) ,detail::node_cloner(cloner, this) ,detail::node_disposer(disposer, this)); this->priv_size_traits().set_size(src.priv_size_traits().get_size()); this->priv_comp() = src.priv_comp(); rollback.release(); } } //! Effects: Unlinks the leftmost node from the tree. //! //! Complexity: Average complexity is constant time. //! //! Throws: Nothing. //! //! Notes: This function breaks the tree and the tree can //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the tree. pointer unlink_leftmost_without_rebalance() { node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance (this->priv_header_ptr())); if(!to_be_disposed) return 0; this->priv_size_traits().decrement(); if(safemode_or_autounlink)//If this is commented does not work with normal_link node_algorithms::init(to_be_disposed); return get_real_value_traits().to_value_ptr(to_be_disposed); } //! Requires: replace_this must be a valid iterator of *this //! and with_this must not be inserted in any tree. //! //! Effects: Replaces replace_this in its position in the //! tree with with_this. The tree does not need to be rebalanced. //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Note: This function will break container ordering invariants if //! with_this is not equivalent to *replace_this according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing or comparison is needed. void replace_node(iterator replace_this, reference with_this) { node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) , this->priv_header_ptr() , get_real_value_traits().to_node_ptr(with_this)); if(safemode_or_autounlink) node_algorithms::init(replace_this.pointed_node()); } //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. //! //! Effects: Returns: a valid iterator i belonging to the set //! that points to the value //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Note: This static function is available only if the value traits //! is stateless. static iterator s_iterator_to(reference value) { typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((!stateful_value_traits)) >)> boost_static_assert_typedef_1326; return iterator (value_traits::to_node_ptr(value), 0); } //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. //! //! Effects: Returns: a valid const_iterator i belonging to the //! set that points to the value //! //! Complexity: Constant. //! //! Throws: Nothing. //! //! Note: This static function is available only if the value traits //! is stateless. static const_iterator s_iterator_to(const_reference value) { typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((!stateful_value_traits)) >)> boost_static_assert_typedef_1344; return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); } //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. //! //! Effects: Returns: a valid iterator i belonging to the set //! that points to the value //! //! Complexity: Constant. //! //! Throws: Nothing. iterator iterator_to(reference value) { return iterator (value_traits::to_node_ptr(value), this); } //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. //! //! Effects: Returns: a valid const_iterator i belonging to the //! set that points to the value //! //! Complexity: Constant. //! //! Throws: Nothing. const_iterator iterator_to(const_reference value) const { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); } //! Requires: value shall not be in a tree. //! //! Effects: init_node puts the hook of a value in a well-known default //! state. //! //! Throws: Nothing. //! //! Complexity: Constant time. //! //! Note: This function puts the hook in the well-known default state //! used by auto_unlink and safe hooks. static void init_node(reference value) { node_algorithms::init(value_traits::to_node_ptr(value)); } //! Effects: removes "value" from the container. //! //! Throws: Nothing. //! //! Complexity: Logarithmic time. //! //! Note: This static function is only usable with non-constant //! time size containers that have stateless comparison functors. //! //! If the user calls //! this function with a constant time size container or stateful comparison //! functor a compilation error will be issued. static void remove_node(reference value) { typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((!constant_time_size)) >)> boost_static_assert_typedef_1400; node_ptr to_remove(value_traits::to_node_ptr(value)); node_algorithms::unlink(to_remove); if(safemode_or_autounlink) node_algorithms::init(to_remove); } /// @cond private: template iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) { for(n = 0; b != e; ++n) this->erase_and_dispose(b++, disposer); return b.unconst(); } iterator private_erase(const_iterator b, const_iterator e, size_type &n) { for(n = 0; b != e; ++n) this->erase(b++); return b.unconst(); } /// @endcond private: static rbtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { header_plus_size *r = detail::parent_from_member ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_size::header_); node_plus_pred_t *n = detail::parent_from_member (r, &node_plus_pred_t::header_plus_size_); data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); rbtree_impl *rb = detail::parent_from_member(d, &rbtree_impl::data_); return *rb; } static rbtree_impl &priv_container_from_iterator(const const_iterator &it) { return priv_container_from_end_iterator(it.end_iterator_from_it()); } }; template inline bool operator< (const rbtree_impl &x, const rbtree_impl &y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } template bool operator== (const rbtree_impl &x, const rbtree_impl &y) { typedef rbtree_impl tree_type; typedef typename tree_type::const_iterator const_iterator; if(tree_type::constant_time_size && x.size() != y.size()){ return false; } const_iterator end1 = x.end(); const_iterator i1 = x.begin(); const_iterator i2 = y.begin(); if(tree_type::constant_time_size){ while (i1 != end1 && *i1 == *i2) { ++i1; ++i2; } return i1 == end1; } else{ const_iterator end2 = y.end(); while (i1 != end1 && i2 != end2 && *i1 == *i2) { ++i1; ++i2; } return i1 == end1 && i2 == end2; } } template inline bool operator!= (const rbtree_impl &x, const rbtree_impl &y) { return !(x == y); } template inline bool operator> (const rbtree_impl &x, const rbtree_impl &y) { return y < x; } template inline bool operator<= (const rbtree_impl &x, const rbtree_impl &y) { return !(y < x); } template inline bool operator>= (const rbtree_impl &x, const rbtree_impl &y) { return !(x < y); } template inline void swap (rbtree_impl &x, rbtree_impl &y) { x.swap(y); } /// @cond template struct make_rbtree_opt { typedef typename pack_options < set_defaults, O1, O2, O3, O4 >::type packed_options; typedef typename detail::get_value_traits ::type value_traits; typedef setopt < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size > type; }; /// @endcond //! Helper metafunction to define a \c rbtree that yields to the same type when the //! same options (either explicitly or implicitly) are used. template struct make_rbtree { /// @cond typedef rbtree_impl < typename make_rbtree_opt::type > implementation_defined; /// @endcond typedef implementation_defined type; }; template class rbtree : public make_rbtree::type { typedef typename make_rbtree ::type Base; private: rbtree(rbtree &); rbtree& operator=(rbtree &); public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: public: typedef typename Base::value_compare value_compare; typedef typename Base::value_traits value_traits; typedef typename Base::real_value_traits real_value_traits; typedef typename Base::iterator iterator; typedef typename Base::const_iterator const_iterator; //Assert if passed value traits are compatible with the type typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((detail::is_same ::value)) >)> boost_static_assert_typedef_1645; rbtree( const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template rbtree( bool unique, Iterator b, Iterator e , const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) : Base(unique, b, e, cmp, v_traits) {} rbtree(::boost::rv< rbtree > & x) : Base(::boost::move(static_cast(x))) {} rbtree& operator=(::boost::rv< rbtree > & x) { this->Base::operator=(::boost::move(static_cast(x))); return *this; } static rbtree &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } static const rbtree &container_from_end_iterator(const_iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } static rbtree &container_from_it(iterator it) { return static_cast(Base::container_from_iterator(it)); } static const rbtree &container_from_it(const_iterator it) { return static_cast(Base::container_from_iterator(it)); } }; } //namespace intrusive } //namespace boost ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2006-2009 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct is_fundamental_impl : public ::boost::type_traits::ice_or< ::boost::is_arithmetic::value , ::boost::is_void::value > { }; } // namespace detail //* is a type T a fundamental type described in the standard (3.9.1) template< typename T > struct is_fundamental : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { template struct integral_constant { static const T value = val; typedef integral_constant type; }; template< bool C_ > struct bool_ : integral_constant { static const bool value = C_; operator bool() const { return bool_::value; } }; typedef bool_ true_; typedef bool_ false_; typedef true_ true_type; typedef false_ false_type; typedef char yes_type; struct no_type { char padding[8]; }; template struct enable_if_c { typedef T type; }; template struct enable_if_c {}; template struct enable_if : public enable_if_c {}; template struct disable_if : public enable_if_c {}; template struct disable_if_c : public enable_if_c {}; template class is_convertible { typedef char true_t; class false_t { char dummy[2]; }; static true_t dispatch(U); static false_t dispatch(...); static T trigger(); public: enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; }; template< bool C , typename T1 , typename T2 > struct if_c { typedef T1 type; }; template< typename T1 , typename T2 > struct if_c { typedef T2 type; }; template< typename T1 , typename T2 , typename T3 > struct if_ { typedef typename if_c<0 != T1::value, T2, T3>::type type; }; template struct select1st // : public std::unary_function { template const typename Pair::first_type& operator()(const OtherPair& x) const { return x.first; } const typename Pair::first_type& operator()(const typename Pair::first_type& x) const { return x; } }; // identity is an extension: it is not part of the standard. template struct identity // : public std::unary_function { typedef T type; const T& operator()(const T& x) const { return x; } }; template struct ls_zeros { static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value); }; template<> struct ls_zeros<0> { static const std::size_t value = 0; }; template<> struct ls_zeros<1> { static const std::size_t value = 0; }; template struct unvoid { typedef T type; }; template <> struct unvoid { struct type { }; }; template <> struct unvoid { struct type { }; }; } //namespace container_detail { } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // (C) Copyright John Maddock 2000. // (C) Copyright Ion Gaztanaga 2005-2012. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // // The alignment_of implementation comes from John Maddock's boost::alignment_of code // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { struct nat{}; template struct LowPriorityConversion { // Convertible from T with user-defined-conversion rank. LowPriorityConversion(const U&) { } }; //boost::alignment_of yields to 10K lines of preprocessed code, so we //need an alternative template struct alignment_of; template struct alignment_of_hack { char c; T t; alignment_of_hack(); }; template struct alignment_logic { enum{ value = A < S ? A : S }; }; template< typename T > struct alignment_of { enum{ value = alignment_logic < sizeof(alignment_of_hack) - sizeof(T) , sizeof(T)>::value }; }; //This is not standard, but should work with all compilers union max_align { char char_; short short_; int int_; long long_; long long long_long_; float float_; double double_; long double long_double_; void * void_ptr_; }; template struct remove_reference { typedef T type; }; template struct remove_reference { typedef T type; }; template struct remove_reference< ::boost::rv > { typedef T type; }; template struct is_reference { enum { value = false }; }; template struct is_reference { enum { value = true }; }; template struct is_pointer { enum { value = false }; }; template struct is_pointer { enum { value = true }; }; template struct add_reference { typedef T& type; }; template struct add_reference { typedef T& type; }; template<> struct add_reference { typedef nat &type; }; template<> struct add_reference { typedef const nat &type; }; template struct add_const_reference { typedef const T &type; }; template struct add_const_reference { typedef T& type; }; template struct is_same { typedef char yes_type; struct no_type { char padding[8]; }; template static yes_type is_same_tester(V*, V*); static no_type is_same_tester(...); static T *t; static U *u; static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u)); }; template struct remove_const { typedef T type; }; template struct remove_const< const T> { typedef T type; }; template struct remove_ref_const { typedef typename remove_const< typename remove_reference::type >::type type; }; } // namespace container_detail } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Pablo Halpern 2009. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// //Note: //We define template parameters as const references to //be able to bind temporaries. After that we will un-const them. //This cast is ugly but it is necessary until "perfect forwarding" //is achieved in C++0x. Meanwhile, if we want to be able to //bind rvalues with non-const references, we have to be ugly ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// //#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING //#error "This file is not needed when perfect forwarding is available" //#endif //BOOST_CONTAINER_PERFECT_FORWARDING ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template class has_member_function_named_allocate { struct BaseMixin { void allocate(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_allocate_impl; //! template struct has_member_function_callable_with_allocate_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). allocate (), 0))> struct zeroarg_checker_allocate { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_allocate(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_allocate { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_allocate(int); }; template struct has_member_function_callable_with_allocate_impl { template static zeroarg_checker_allocate Test(zeroarg_checker_allocate*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap1_allocate : Fun { funwrap1_allocate(); using Fun::allocate; boost_intrusive_has_member_function_callable_with::private_type allocate ( boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_allocate_impl { typedef funwrap1_allocate FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). allocate ( boost::move_detail::declval< P0 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap2_allocate : Fun { funwrap2_allocate(); using Fun::allocate; boost_intrusive_has_member_function_callable_with::private_type allocate ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_allocate_impl { typedef funwrap2_allocate FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). allocate ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() ), 0 ) ) ) ); }; }}} namespace boost { namespace container { namespace container_detail { template struct has_member_function_callable_with_allocate : public has_member_function_callable_with_allocate_impl ::value , P0 , P1 > {}; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template class has_member_function_named_destroy { struct BaseMixin { void destroy(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_destroy_impl; //! template struct has_member_function_callable_with_destroy_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). destroy (), 0))> struct zeroarg_checker_destroy { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_destroy(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_destroy { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_destroy(int); }; template struct has_member_function_callable_with_destroy_impl { template static zeroarg_checker_destroy Test(zeroarg_checker_destroy*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap1_destroy : Fun { funwrap1_destroy(); using Fun::destroy; boost_intrusive_has_member_function_callable_with::private_type destroy ( boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_destroy_impl { typedef funwrap1_destroy FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). destroy ( boost::move_detail::declval< P0 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap2_destroy : Fun { funwrap2_destroy(); using Fun::destroy; boost_intrusive_has_member_function_callable_with::private_type destroy ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_destroy_impl { typedef funwrap2_destroy FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). destroy ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap3_destroy : Fun { funwrap3_destroy(); using Fun::destroy; boost_intrusive_has_member_function_callable_with::private_type destroy ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_destroy_impl { typedef funwrap3_destroy FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). destroy ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() ), 0 ) ) ) ); }; }}} namespace boost { namespace container { namespace container_detail { template struct has_member_function_callable_with_destroy : public has_member_function_callable_with_destroy_impl ::value , P0 , P1 , P2 > {}; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template class has_member_function_named_max_size { struct BaseMixin { void max_size(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_max_size_impl; //! template struct has_member_function_callable_with_max_size_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). max_size (), 0))> struct zeroarg_checker_max_size { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_max_size(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_max_size { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_max_size(int); }; template struct has_member_function_callable_with_max_size_impl { template static zeroarg_checker_max_size Test(zeroarg_checker_max_size*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} namespace boost { namespace container { namespace container_detail { template struct has_member_function_callable_with_max_size : public has_member_function_callable_with_max_size_impl ::value > {}; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template class has_member_function_named_select_on_container_copy_construction { struct BaseMixin { void select_on_container_copy_construction(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_select_on_container_copy_construction_impl; //! template struct has_member_function_callable_with_select_on_container_copy_construction_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). select_on_container_copy_construction (), 0))> struct zeroarg_checker_select_on_container_copy_construction { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_select_on_container_copy_construction(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_select_on_container_copy_construction { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_select_on_container_copy_construction(int); }; template struct has_member_function_callable_with_select_on_container_copy_construction_impl { template static zeroarg_checker_select_on_container_copy_construction Test(zeroarg_checker_select_on_container_copy_construction*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} namespace boost { namespace container { namespace container_detail { template struct has_member_function_callable_with_select_on_container_copy_construction : public has_member_function_callable_with_select_on_container_copy_construction_impl ::value > {}; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template class has_member_function_named_construct { struct BaseMixin { void construct(); }; struct Base : public ::boost::remove_cv::type, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; template struct has_member_function_callable_with_construct_impl; //! template struct has_member_function_callable_with_construct_impl { static const bool value = false; }; //! //Special case for 0 args template< class F , std::size_t N = sizeof((boost::move_detail::declval(). construct (), 0))> struct zeroarg_checker_construct { boost_intrusive_has_member_function_callable_with::yes_type dummy; zeroarg_checker_construct(int); }; //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. template struct zeroarg_checker_construct { boost_intrusive_has_member_function_callable_with::no_type dummy; zeroarg_checker_construct(int); }; template struct has_member_function_callable_with_construct_impl { template static zeroarg_checker_construct Test(zeroarg_checker_construct*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap1_construct : Fun { funwrap1_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap1_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap2_construct : Fun { funwrap2_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap2_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap3_construct : Fun { funwrap3_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap3_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap4_construct : Fun { funwrap4_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap4_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap5_construct : Fun { funwrap5_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap5_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() , boost::move_detail::declval< P4 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap6_construct : Fun { funwrap6_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap6_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() , boost::move_detail::declval< P4 >() , boost::move_detail::declval< P5 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap7_construct : Fun { funwrap7_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap7_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() , boost::move_detail::declval< P4 >() , boost::move_detail::declval< P5 >() , boost::move_detail::declval< P6 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap8_construct : Fun { funwrap8_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap8_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() , boost::move_detail::declval< P4 >() , boost::move_detail::declval< P5 >() , boost::move_detail::declval< P6 >() , boost::move_detail::declval< P7 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap9_construct : Fun { funwrap9_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap9_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() , boost::move_detail::declval< P4 >() , boost::move_detail::declval< P5 >() , boost::move_detail::declval< P6 >() , boost::move_detail::declval< P7 >() , boost::move_detail::declval< P8 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap10_construct : Fun { funwrap10_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap10_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() , boost::move_detail::declval< P4 >() , boost::move_detail::declval< P5 >() , boost::move_detail::declval< P6 >() , boost::move_detail::declval< P7 >() , boost::move_detail::declval< P8 >() , boost::move_detail::declval< P9 >() ), 0 ) ) ) ); }; }}} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// // sample.h namespace boost { namespace container { namespace container_detail { template struct funwrap11_construct : Fun { funwrap11_construct(); using Fun::construct; boost_intrusive_has_member_function_callable_with::private_type construct ( boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care , boost_intrusive_has_member_function_callable_with::dont_care) const; }; template struct has_member_function_callable_with_construct_impl { typedef funwrap11_construct FunWrap; static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == sizeof(boost_intrusive_has_member_function_callable_with::is_private_type ( (boost::move_detail::declval(). construct ( boost::move_detail::declval< P0 >() , boost::move_detail::declval< P1 >() , boost::move_detail::declval< P2 >() , boost::move_detail::declval< P3 >() , boost::move_detail::declval< P4 >() , boost::move_detail::declval< P5 >() , boost::move_detail::declval< P6 >() , boost::move_detail::declval< P7 >() , boost::move_detail::declval< P8 >() , boost::move_detail::declval< P9 >() , boost::move_detail::declval< P10 >() ), 0 ) ) ) ); }; }}} namespace boost { namespace container { namespace container_detail { template struct has_member_function_callable_with_construct : public has_member_function_callable_with_construct_impl ::value , P0 , P1 , P2 , P3 , P4 , P5 , P6 , P7 , P8 , P9 , P10 > {}; }}} namespace boost { namespace container { namespace container_detail { template struct boost_intrusive_default_type_pointer { template static char test(int, typename X::pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::pointer type; }; template struct boost_intrusive_eval_default_type_pointer { template static char test(int, typename X::pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::pointer type; }; template struct boost_intrusive_default_type_const_pointer { template static char test(int, typename X::const_pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType const_pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::const_pointer type; }; template struct boost_intrusive_eval_default_type_const_pointer { template static char test(int, typename X::const_pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type const_pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::const_pointer type; }; template struct boost_intrusive_default_type_reference { template static char test(int, typename X::reference*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType reference; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::reference type; }; template struct boost_intrusive_eval_default_type_reference { template static char test(int, typename X::reference*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type reference; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::reference type; }; template struct boost_intrusive_default_type_const_reference { template static char test(int, typename X::const_reference*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType const_reference; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::const_reference type; }; template struct boost_intrusive_eval_default_type_const_reference { template static char test(int, typename X::const_reference*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type const_reference; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::const_reference type; }; template struct boost_intrusive_default_type_void_pointer { template static char test(int, typename X::void_pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType void_pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::void_pointer type; }; template struct boost_intrusive_eval_default_type_void_pointer { template static char test(int, typename X::void_pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type void_pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::void_pointer type; }; template struct boost_intrusive_default_type_const_void_pointer { template static char test(int, typename X::const_void_pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType const_void_pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::const_void_pointer type; }; template struct boost_intrusive_eval_default_type_const_void_pointer { template static char test(int, typename X::const_void_pointer*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type const_void_pointer; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::const_void_pointer type; }; template struct boost_intrusive_default_type_size_type { template static char test(int, typename X::size_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType size_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::size_type type; }; template struct boost_intrusive_eval_default_type_size_type { template static char test(int, typename X::size_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type size_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::size_type type; }; template struct boost_intrusive_default_type_propagate_on_container_copy_assignment { template static char test(int, typename X::propagate_on_container_copy_assignment*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType propagate_on_container_copy_assignment; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::propagate_on_container_copy_assignment type; }; template struct boost_intrusive_eval_default_type_propagate_on_container_copy_assignment { template static char test(int, typename X::propagate_on_container_copy_assignment*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type propagate_on_container_copy_assignment; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::propagate_on_container_copy_assignment type; }; template struct boost_intrusive_default_type_propagate_on_container_move_assignment { template static char test(int, typename X::propagate_on_container_move_assignment*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType propagate_on_container_move_assignment; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::propagate_on_container_move_assignment type; }; template struct boost_intrusive_eval_default_type_propagate_on_container_move_assignment { template static char test(int, typename X::propagate_on_container_move_assignment*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type propagate_on_container_move_assignment; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::propagate_on_container_move_assignment type; }; template struct boost_intrusive_default_type_propagate_on_container_swap { template static char test(int, typename X::propagate_on_container_swap*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType propagate_on_container_swap; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::propagate_on_container_swap type; }; template struct boost_intrusive_eval_default_type_propagate_on_container_swap { template static char test(int, typename X::propagate_on_container_swap*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type propagate_on_container_swap; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::propagate_on_container_swap type; }; template struct boost_intrusive_default_type_difference_type { template static char test(int, typename X::difference_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef DefaultType difference_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::if_c ::type::difference_type type; }; template struct boost_intrusive_eval_default_type_difference_type { template static char test(int, typename X::difference_type*); template static int test(boost::intrusive::detail:: LowPriorityConversion, void*); struct DefaultWrap { typedef typename DefaultType::type difference_type; }; static const bool value = (1 == sizeof(test(0, 0))); typedef typename ::boost::intrusive::detail::eval_if_c < value , ::boost::intrusive::detail::identity , ::boost::intrusive::detail::identity > ::type::difference_type type; }; } //namespace container_detail { } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// // limits standard header /* ymath.h internal header */ namespace std { extern "C" { /* MACROS FOR _FPP_TYPE */ /* MACROS FOR _Dtest RETURN (0 => ZERO) */ /* MACROS FOR _Feraise ARGUMENT */ /* TYPE DEFINITIONS */ typedef union { /* pun float types as integer array */ unsigned short _Word[8]; float _Float; double _Double; long double _Long_double; } _Dconst; /* ERROR REPORTING */ void _Feraise(int); /* double DECLARATIONS */ double _Cosh(double, double); short _Dtest(double *); short _Exp(double *, double, short); double _Log(double, int); double _Sin(double, unsigned int); double _Sinh(double, double); extern /* const */ far _Dconst _Denorm, _Hugeval, _Inf, _Nan, _Snan; /* float DECLARATIONS */ float _FCosh(float, float); short _FDtest(float *); short _FExp(float *, float, short); float _FLog(float, int); float _FSin(float, unsigned int); float _FSinh(float, float); extern /* const */ far _Dconst _FDenorm, _FInf, _FNan, _FSnan; /* long double DECLARATIONS */ long double _LCosh(long double, long double); short _LDtest(long double *); short _LExp(long double *, long double, short); long double _LLog(long double, int); long double _LSin(long double, unsigned int); long double _LSinh(long double, long double); extern /* const */ far _Dconst _LDenorm, _LInf, _LNan, _LSnan; } } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // cfloat standard header /*****************************************************************************/ /* float.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /********************************************************************/ /* KEY: FLT_ - APPLIES TO TYPE FLOAT */ /* DBL_ - APPLIES TO TYPE DOUBLE */ /* LDBL_ - APPLIES TO TYPE LONG DOUBLE */ /********************************************************************/ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ // cmath standard header /****************************************************************************/ /* math.h v7.3.6 */ /* */ /* Copyright (c) 1997-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ /****************************************************************************/ /* access.h v7.3.6 */ /* */ /* Copyright (c) 1997-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ /****************************************************************************/ /* elfnames.h v7.3.6 */ /* */ /* Copyright (c) 1997-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ //---------------------------------------------------------------------------- // IS RECOMMENDED OVER . IS PROVIDED FOR // COMPATIBILITY WITH C AND THIS USAGE IS DEPRECATED IN C++ //---------------------------------------------------------------------------- extern "C" namespace std { extern "C" double sqrt (double x); extern "C" double exp (double x); extern "C" double log (double x); extern "C" double log10(double x); extern "C" double pow (double x, double y); extern "C" double sin (double x); extern "C" double cos (double x); extern "C" double tan (double x); extern "C" double asin (double x); extern "C" double acos (double x); extern "C" double atan (double x); extern "C" double atan2(double y, double x); extern "C" double sinh (double x); extern "C" double cosh (double x); extern "C" double tanh (double x); extern "C" double ceil (double x); extern "C" double floor(double x); extern "C" double fabs (double x); extern "C" double ldexp(double x, int n); extern "C" double frexp(double x, int *exp); extern "C" double modf (double x, double *ip); extern "C" double fmod (double x, double y); /* An inline version of fmod that works for limited domain only */ /* See comments in implementation below */ extern "C" double _FMOD(double x, double y); /* these present in many linked images, so we'll tell you about them. */ extern "C" double _nround(double x); /* round-to-nearest */ extern "C" double _trunc(double x); /* truncate towards 0 */ } /* extern "C" namespace std */ /* the ANSI-optional *f and *l routines */ /****************************************************************************/ /* mathf.h v7.3.6 */ /* */ /* Copyright (c) 1997-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ //---------------------------------------------------------------------------- // IS RECOMMENDED OVER . IS PROVIDED FOR // COMPATIBILITY WITH C AND THIS USAGE IS DEPRECATED IN C++ //---------------------------------------------------------------------------- extern "C" namespace std { extern "C" float sqrtf (float x); extern "C" float expf (float x); extern "C" float logf (float x); extern "C" float log10f(float x); extern "C" float powf (float x, float y); extern "C" float sinf (float x); extern "C" float cosf (float x); extern "C" float tanf (float x); extern "C" float asinf (float x); extern "C" float acosf (float x); extern "C" float atanf (float x); extern "C" float atan2f(float y, float x); extern "C" float sinhf (float x); extern "C" float coshf (float x); extern "C" float tanhf (float x); extern "C" float ceilf (float x); extern "C" float floorf(float x); extern "C" float fabsf (float x); extern "C" float ldexpf(float x, int n); extern "C" float frexpf(float x, int *exp); extern "C" float modff (float x, float *ip); extern "C" float fmodf (float x, float y); /* An inline version of fmodf that works for limited domain only */ /* See comments in implementation below */ extern "C" float _FMODF(float x, float y); /* these present in many linked images, so we'll tell you about them. */ extern "C" float _roundf(float x); /* round-to-nearest */ extern "C" float _truncf(float x); /* truncate towards 0 */ /* ------------------------------------------------- */ /* Routines below are an addition to ANSI math.h */ /* Some (noted with "9x" in comment) will become ANSI*/ /* once C9x is approved. */ /* ------------------------------------------------- */ extern "C" float rsqrtf(float x); /* == 1/sqrtf(x) but *MUCH* faster */ extern "C" float exp2f (float x); /*9x mathematically equiv to powf(2.0 ,x) */ extern "C" float exp10f(float x); /* mathematically equiv to powf(10.0,x) */ extern "C" float log2f (float x); /*9x mathematically equiv to logf(x)/logf(2.)*/ extern "C" float powif (float x, int i); /* equiv to powf(x,(float)i) */ extern "C" float cotf (float x); extern "C" float acotf (float x); extern "C" float acot2f(float x, float y); extern "C" float cothf (float x); extern "C" float asinhf(float x); /* 9x */ extern "C" float acoshf(float x); /* 9x */ extern "C" float atanhf(float x); /* 9x */ extern "C" float acothf(float x); extern "C" int __isinff(float x); extern "C" int __isnanf(float x); extern "C" int __isfinitef(float x); extern "C" int __isnormalf(float x); extern "C" int __fpclassifyf(float x); /****************************************************************************/ /* UNACCESS.H v7.3.6 */ /* */ /* Copyright (c) 2000-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ /* unaccess.h: Empty by default */ } /* extern "C" namespace std */ using std::__isnanf; using std::__isinff; using std::__isfinitef; using std::__isnormalf; using std::__fpclassifyf; using std::_roundf; /* round-to-nearest */ using std::_truncf; /* truncate towards 0 */ /****************************************************************************/ /* mathl.h v7.3.6 */ /* */ /* Copyright (c) 1997-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ namespace std { /* modfl() requires an actual function because the pointer arg cannot be implicitly converted. */ extern "C" long double modfl (long double x, long double *ip); } /* namespace std */ extern "C" namespace std { /* ------------------------------------------------- */ /* Routines below are an addition to ANSI math.h */ /* Some (noted with "9x" in comment) will become ANSI*/ /* once C9x is approved. */ /* ------------------------------------------------- */ extern "C" double rsqrt(double x); /* == 1/sqrt(x) but *MUCH* faster */ extern "C" double exp2 (double x); /*9x mathematically equiv to pow(2.0 ,x) */ extern "C" double exp10(double x); /* mathematically equiv to pow(10.0,x) */ extern "C" double log2 (double x); /*9x mathematically equiv to log(x)/log(2.0)*/ extern "C" double powi(double x, int i); /* equiv to pow(x,(double)i) */ extern "C" double cot (double x); extern "C" double acot (double x); extern "C" double acot2(double x, double y); extern "C" double coth (double x); extern "C" double asinh(double x); /* 9x */ extern "C" double acosh(double x); /* 9x */ extern "C" double atanh(double x); /* 9x */ extern "C" double acoth(double x); extern "C" int __isinf(double x); extern "C" int __isnan(volatile double x); extern "C" int __isfinite(double x); extern "C" int __isnormal(double x); extern "C" int __fpclassify(double x); /*Definitions of classification macros used in fp_classify We do not support subnormal numbers yet, but the classification exists for when they are supported */ } /* extern "C" namespace std */ /*******************************************************************************/ /* CQ35082 : Overloaded version of math functions for float and long double */ /* removed from here, and include in cmath instead (see Section 26.5 */ /* of C++ standard for details). Thus cpp_inline_math.h is now */ /* included in cmath . */ /*******************************************************************************/ /****************************************************************************/ /* UNACCESS.H v7.3.6 */ /* */ /* Copyright (c) 2000-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /****************************************************************************/ /* unaccess.h: Empty by default */ using std::__isnan; using std::__isinf; using std::__isfinite; using std::__isnormal; using std::__fpclassify; using std::_nround; /* round-to-nearest */ using std::_trunc; /*****************************************************************************/ /* CPP_INLINE_MATH.H v7.3.6 */ /* */ /* Copyright (c) 1995-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ namespace std { /*****************************************************************************/ /* These two inline functions for double, the other 23 should be default math*/ /* function defined in ANSI */ /*****************************************************************************/ inline double abs(double x) // OVERLOADS { // return absolute value return (fabs(x)); } inline double pow(double x, int y) { // raise to integer power return (pow(x, (double)y)); } /*****************************************************************************/ /* 24 float math functions defined by C++ ISO/IEC 14882 26.5 */ /*****************************************************************************/ inline float abs(float x) // OVERLOADS { // return absolute value return (float)(fabsf((double)x)); } inline float acos(float x) { // return arccosine return (float)(acosf((double)x)); } inline float asin(float x) { // return arcsine return (float)(asinf((double)x)); } inline float atan(float x) { // return arctangent return (float)(atanf((double)x)); } inline float atan2(float x, float y) { // return arctangent return (float)(atan2f((double)x, (double)y)); } inline float ceil(float x) { // return ceiling return (float)(ceilf((double)x)); } inline float cos(float x) { // return cosine return (float)(cosf((double)x)); } inline float cosh(float x) { // return hyperbolic cosine return (float)(coshf((double)x)); } inline float exp(float x) { // return exponential return (float)(expf((double)x)); } inline float fabs(float x) { // return absolute value return (float)(fabsf((double)x)); } inline float floor(float x) { // return floor return (float)(floorf((double)x)); } inline float fmod(float x, float y) { // return modulus return (float)(fmodf((double)x, (double)y)); } inline float frexp(float x, int *y) { // unpack exponent return (float)(frexpf((double)x, y)); } inline float ldexp(float x, int y) { // pack exponent return (float)(ldexpf((double)x, y)); } inline float log(float x) { // return natural logarithm return (float)(logf((double)x)); } inline float log10(float x) { // return base-10 logarithm return (float)(log10f((double)x)); } inline float modf(float x, float *y) { // unpack fraction return (float)(modff((float)x, (float *)y)); } inline float pow(float x, float y) { // raise to power return (float)(powf((double)x, (double)y)); } inline float pow(float x, int y) { // raise to integer power return (float)(powif((double)x, y)); } inline float sin(float x) { // return sine return (float)(sinf((double)x)); } inline float sinh(float x) { // return hyperbolic sine return (float)(sinhf((double)x)); } inline float sqrt(float x) { // return square root return (float)(sqrtf((double)x)); } inline float tan(float x) { // return tangent return (float)(tanf((double)x)); } inline float tanh(float x) { // return hyperbolic tangent return (float)(tanhf((double)x)); } /*****************************************************************************/ /* 24 long double math functions defined by C++ ISO/IEC 14882 26.5 */ /*****************************************************************************/ inline long double abs(long double x) // OVERLOADS { // return absolute value return (long double)(fabs((double)x)); } inline long double acos(long double x) { // return arccosine return (long double)(acos((double)x)); } inline long double asin(long double x) { // return arcsine return (long double)(asin((double)x)); } inline long double atan(long double x) { // return arctangent return (long double)(atan((double)x)); } inline long double atan2(long double x, long double y) { // return arctangent return (long double)(atan2((double)x, (double)y)); } inline long double ceil(long double x) { // return ceiling return (long double)(ceil((double)x)); } inline long double cos(long double x) { // return cosine return (long double)(cos((double)x)); } inline long double cosh(long double x) { // return hyperbolic cosine return (long double)(cosh((double)x)); } inline long double exp(long double x) { // return exponential return (long double)(exp((double)x)); } inline long double fabs(long double x) { // return absolute value return (long double)(fabs((double)x)); } inline long double floor(long double x) { // return floor return (long double)(floor((double)x)); } inline long double fmod(long double x, long double y) { // return modulus return (long double)(fmod((double)x, (double)y)); } inline long double frexp(long double x, int *y) { // unpack exponent return (long double)(frexp((double)x, y)); } inline long double ldexp(long double x, int y) { // pack exponent return (long double)(ldexp((double)x, y)); } inline long double log(long double x) { // return natural logarithm return (long double)(log((double)x)); } inline long double log10(long double x) { // return base-10 logarithm return (long double)(log10((double)x)); } inline long double modf(long double x, long double *y) { // unpack fraction return (long double)(modfl((long double)x, (long double *)y)); } inline long double pow(long double x, long double y) { // raise to power return (long double)(pow((double)x, (double)y)); } inline long double pow(long double x, int y) { // raise to integer power return (long double)(powi((double)x, y)); } inline long double sin(long double x) { // return sine return (long double)(sin((double)x)); } inline long double sinh(long double x) { // return hyperbolic sine return (long double)(sinh((double)x)); } inline long double sqrt(long double x) { // return square root return (long double)(sqrt((double)x)); } inline long double tan(long double x) { // return tangent return (long double)(tan((double)x)); } inline long double tanh(long double x) { // return hyperbolic tangent return (long double)(tanh((double)x)); } } /* namespace std */ /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ namespace std { // TI FP properties // ASSUMES: // wraparound 2's complement integer arithmetic w/o traps // all CHAR_BITs of each byte used by integers // IEC559 (IEEE 754) floating-point arithmetic // floating-point errors can trap // tinyness detected before floating-point rounding // 64-bit long long (if _LONGLONG defined) // ENUM float_denorm_style typedef enum { // constants for different IEEE float denormalization styles denorm_indeterminate = -1, denorm_absent = 0, denorm_present = 1} float_denorm_style; // ENUM float_round_style typedef enum { // constants for different IEEE rounding styles round_indeterminate = -1, round_toward_zero = 0, round_to_nearest = 1, round_toward_infinity = 2, round_toward_neg_infinity = 3} float_round_style; // STRUCT _Num_base struct _Num_base { // base for all types, with common defaults static const far float_denorm_style has_denorm = (float_denorm_style)(denorm_absent); static const far bool has_denorm_loss = (bool)(false); static const far bool has_infinity = (bool)(false); static const far bool has_quiet_NaN = (bool)(false); static const far bool has_signaling_NaN = (bool)(false); static const far bool is_bounded = (bool)(false); static const far bool is_exact = (bool)(false); static const far bool is_iec559 = (bool)(false); static const far bool is_integer = (bool)(false); static const far bool is_modulo = (bool)(false); static const far bool is_signed = (bool)(false); static const far bool is_specialized = (bool)(false); static const far bool tinyness_before = (bool)(false); static const far bool traps = (bool)(false); static const far float_round_style round_style = (float_round_style)(round_toward_zero); static const far int digits = (int)(0); static const far int digits10 = (int)(0); static const far int max_exponent = (int)(0); static const far int max_exponent10 = (int)(0); static const far int min_exponent = (int)(0); static const far int min_exponent10 = (int)(0); static const far int radix = (int)(0); }; // TEMPLATE CLASS numeric_limits template class numeric_limits : public _Num_base { // numeric limits for arbitrary type _Ty (say little or nothing) public: static _Ty (min)() throw () { // return minimum value return (_Ty(0)); } static _Ty (max)() throw () { // return maximum value return (_Ty(0)); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (_Ty(0)); } static _Ty round_error() throw () { // return largest rounding error return (_Ty(0)); } static _Ty denorm_min() throw () { // return minimum denormalized value return (_Ty(0)); } static _Ty infinity() throw () { // return positive infinity return (_Ty(0)); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (_Ty(0)); } static _Ty signaling_NaN() throw () { // return signaling NaN return (_Ty(0)); } }; // STRUCT _Num_int_base struct _Num_int_base : public _Num_base { // base for integer types static const far bool is_bounded = (bool)(true); static const far bool is_exact = (bool)(true); static const far bool is_integer = (bool)(true); static const far bool is_modulo = (bool)(true); static const far bool is_specialized = (bool)(true); static const far int radix = (int)(2); }; // STRUCT _Num_float_base struct _Num_float_base : public _Num_base { // base for floating-point types static const far float_denorm_style has_denorm = (float_denorm_style)(denorm_absent); static const far bool has_denorm_loss = (bool)(false); static const far bool has_infinity = (bool)(false); static const far bool has_quiet_NaN = (bool)(false); static const far bool has_signaling_NaN = (bool)(false); static const far bool is_bounded = (bool)(true); static const far bool is_exact = (bool)(false); static const far bool is_iec559 = (bool)(false); static const far bool is_integer = (bool)(false); static const far bool is_modulo = (bool)(false); static const far bool is_signed = (bool)(true); static const far bool is_specialized = (bool)(true); static const far bool tinyness_before = (bool)(false); static const far bool traps = (bool)(false); static const far float_round_style round_style = (float_round_style)(round_to_nearest); static const far int radix = (int)(2); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type char public: typedef char _Ty; static _Ty (min)() throw () { // return minimum value return (-128); } static _Ty (max)() throw () { // return maximum value return (127); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(-128 != 0); static const far int digits = (int)(8 - (-128 != 0 ? 1 : 0)); static const far int digits10 = (int)((8 - (-128 != 0 ? 1 : 0)) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type wchar_t public: typedef wchar_t _Ty; static _Ty (min)() throw () { // return minimum value return ((_Ty)0); } static _Ty (max)() throw () { // return maximum value return ((_Ty)0xffffu); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(0 != 0); static const far int digits = (int)(8 * sizeof (wchar_t) - (0 != 0 ? 1 : 0)); static const far int digits10 = (int)((8 * sizeof (wchar_t) - (0 != 0 ? 1 : 0)) * 301L / 1000); }; // CLASS numeric_limits<_Bool> template<> class numeric_limits<_Bool> : public _Num_int_base { // limits for type bool public: typedef bool _Ty; static _Ty (min)() throw () { // return minimum value return (false); } static _Ty (max)() throw () { // return maximum value return (true); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_modulo = (bool)(false); static const far bool is_signed = (bool)(false); static const far int digits = (int)(1); static const far int digits10 = (int)(0); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type signed char public: typedef signed char _Ty; static _Ty (min)() throw () { // return minimum value return (-128); } static _Ty (max)() throw () { // return maximum value return (127); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(true); static const far int digits = (int)(8 - 1); static const far int digits10 = (int)((8 - 1) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type unsigned char public: typedef unsigned char _Ty; static _Ty (min)() throw () { // return minimum value return (0); } static _Ty (max)() throw () { // return maximum value return (255); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(false); static const far int digits = (int)(8); static const far int digits10 = (int)((8) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type short public: typedef short _Ty; static _Ty (min)() throw () { // return minimum value return (-32768); } static _Ty (max)() throw () { // return maximum value return (32767); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(true); static const far int digits = (int)(8 * sizeof (short) - 1); static const far int digits10 = (int)((8 * sizeof (short) - 1) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type unsigned short public: typedef unsigned short _Ty; static _Ty (min)() throw () { // return minimum value return (0); } static _Ty (max)() throw () { // return maximum value return (65535); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(false); static const far int digits = (int)(8 * sizeof (unsigned short)); static const far int digits10 = (int)((8 * sizeof (unsigned short)) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type int public: typedef int _Ty; static _Ty (min)() throw () { // return minimum value return ((-2147483647-1)); } static _Ty (max)() throw () { // return maximum value return (2147483647); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(true); static const far int digits = (int)(8 * sizeof (int) - 1); static const far int digits10 = (int)((8 * sizeof (int) - 1) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type unsigned int public: typedef unsigned int _Ty; static _Ty (min)() throw () { // return minimum value return (0); } static _Ty (max)() throw () { // return maximum value return (4294967295U); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(false); static const far int digits = (int)(8 * sizeof (unsigned int)); static const far int digits10 = (int)((8 * sizeof (unsigned int)) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type long public: typedef long _Ty; static _Ty (min)() throw () { // return minimum value return ((-549755813887-1)); } static _Ty (max)() throw () { // return maximum value return (549755813887); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(true); // replacing sizeof(long) with CONSTANT 5 for C6x's 40bit long static const far int digits = (int)(8 * 5 - 1); static const far int digits10 = (int)((8 * 5 - 1) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_int_base { // limits for type unsigned long public: typedef unsigned long _Ty; static _Ty (min)() throw () { // return minimum value return (0); } static _Ty (max)() throw () { // return maximum value return (1099511627775U); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(false); // replacing sizeof(unsigned long) with CONSTANT 5 for C6x's 40bit long static const far int digits = (int)(8 * 5); static const far int digits10 = (int)((8 * 5) * 301L / 1000); }; // CLASS numeric_limits<_LONGLONG> template<> class numeric_limits : public _Num_int_base { // limits for type long long public: typedef long long _Ty; static _Ty (min)() throw () { // return minimum value return (-0x7fffffffffffffffLL - 1); } static _Ty (max)() throw () { // return maximum value return (0x7fffffffffffffffLL); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(true); static const far int digits = (int)(8 * sizeof (long long) - 1); static const far int digits10 = (int)((8 * sizeof (long long) - 1) * 301L / 1000); }; // CLASS numeric_limits<_ULONGLONG> template<> class numeric_limits : public _Num_int_base { // limits for type unsigned long long public: typedef unsigned long long _Ty; static _Ty (min)() throw () { // return minimum value return (0); } static _Ty (max)() throw () { // return maximum value return (0xffffffffffffffffULL); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (0); } static _Ty round_error() throw () { // return largest rounding error return (0); } static _Ty denorm_min() throw () { // return minimum denormalized value return (0); } static _Ty infinity() throw () { // return positive infinity return (0); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far bool is_signed = (bool)(false); static const far int digits = (int)(8 * sizeof (unsigned long long)); static const far int digits10 = (int)((8 * sizeof (unsigned long long)) * 301L / 1000); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_float_base { // limits for type float public: typedef float _Ty; static _Ty (min)() throw () { // return minimum value return (1.175494351E-38F); } static _Ty (max)() throw () { // return maximum value return (3.402823466E+38F); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (1.192092896E-07F); } static _Ty round_error() throw () { // return largest rounding error return (0.5); } static _Ty denorm_min() throw () { // return minimum denormalized value return (1.175494351E-38F); } static _Ty infinity() throw () { // return positive infinity return (3.402823466E+38F); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far int digits = (int)(24); static const far int digits10 = (int)(6); static const far int max_exponent = (int)((int)128); static const far int max_exponent10 = (int)((int)38); static const far int min_exponent = (int)((int)-125); static const far int min_exponent10 = (int)((int)-37); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_float_base { // limits for type double public: typedef double _Ty; static _Ty (min)() throw () { // return minimum value return (2.2250738585072014E-308); } static _Ty (max)() throw () { // return maximum value return (1.7976931348623157E+308); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (2.2204460492503131E-16); } static _Ty round_error() throw () { // return largest rounding error return (0.5); } static _Ty denorm_min() throw () { // return minimum denormalized value return (2.2250738585072014E-308); } static _Ty infinity() throw () { // return positive infinity return (1.7976931348623157E+308); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far int digits = (int)(53); static const far int digits10 = (int)(15); static const far int max_exponent = (int)((int)1024); static const far int max_exponent10 = (int)((int)308); static const far int min_exponent = (int)((int)-1021); static const far int min_exponent10 = (int)((int)-307); }; // CLASS numeric_limits template<> class numeric_limits : public _Num_float_base { // limits for type long double public: typedef long double _Ty; static _Ty (min)() throw () { // return minimum value return (2.2250738585072014E-308); } static _Ty (max)() throw () { // return maximum value return (1.7976931348623157E+308); } static _Ty epsilon() throw () { // return smallest effective increment from 1.0 return (2.2204460492503131E-16); } static _Ty round_error() throw () { // return largest rounding error return (0.5); } static _Ty denorm_min() throw () { // return minimum denormalized value return (2.2250738585072014E-308); } static _Ty infinity() throw () { // return positive infinity return (1.7976931348623157E+308); } static _Ty quiet_NaN() throw () { // return non-signaling NaN return (0); } static _Ty signaling_NaN() throw () { // return signaling NaN return (0); } static const far int digits = (int)(53); static const far int digits10 = (int)(15); static const far int max_exponent = (int)((int)1024); static const far int max_exponent10 = (int)((int)308); static const far int min_exponent = (int)((int)-1021); static const far int min_exponent10 = (int)((int)-307); }; } /* * Copyright (c) 1992-2004 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V4.02:1476 */ ///@cond namespace boost { namespace container { namespace container_detail { //workaround needed for C++03 compilers with no construct() //supporting rvalue references template struct is_std_allocator { static const bool value = false; }; template struct is_std_allocator< std::allocator > { static const bool value = true; }; } //namespace container_detail { ///@endcond //! The class template allocator_traits supplies a uniform interface to all allocator types. //! This class is a C++03-compatible implementation of std::allocator_traits template struct allocator_traits { //allocator_type typedef Alloc allocator_type; //value_type typedef typename Alloc::value_type value_type; //pointer typedef typename boost::container::container_detail:: boost_intrusive_default_type_pointer< Alloc, value_type* > ::type pointer; //const_pointer typedef typename boost::container::container_detail:: boost_intrusive_eval_default_type_const_pointer< Alloc, typename boost::intrusive::pointer_traits ::template rebind_pointer > ::type const_pointer; //reference typedef typename boost::container::container_detail:: boost_intrusive_default_type_reference< Alloc, typename container_detail::unvoid ::type& > ::type reference; //const_reference typedef typename boost::container::container_detail:: boost_intrusive_default_type_const_reference< Alloc, const typename container_detail::unvoid ::type& > ::type const_reference; //void_pointer typedef typename boost::container::container_detail:: boost_intrusive_eval_default_type_void_pointer< Alloc, typename boost::intrusive::pointer_traits ::template rebind_pointer > ::type void_pointer; //const_void_pointer typedef typename boost::container::container_detail:: boost_intrusive_eval_default_type_const_void_pointer< Alloc, typename boost::intrusive::pointer_traits ::template rebind_pointer > ::type const_void_pointer; //difference_type typedef typename boost::container::container_detail:: boost_intrusive_default_type_difference_type< Alloc, std::ptrdiff_t > ::type difference_type; //size_type typedef typename boost::container::container_detail:: boost_intrusive_default_type_size_type< Alloc, std::size_t > ::type size_type; //propagate_on_container_copy_assignment typedef typename boost::container::container_detail:: boost_intrusive_default_type_propagate_on_container_copy_assignment< Alloc, boost::false_type > ::type propagate_on_container_copy_assignment; //propagate_on_container_move_assignment typedef typename boost::container::container_detail:: boost_intrusive_default_type_propagate_on_container_move_assignment< Alloc, boost::false_type > ::type propagate_on_container_move_assignment; //propagate_on_container_swap typedef typename boost::container::container_detail:: boost_intrusive_default_type_propagate_on_container_swap< Alloc, boost::false_type > ::type propagate_on_container_swap; //Some workaround for C++03 or C++11 compilers with no template aliases template struct rebind_alloc : boost::intrusive::detail::type_rebinder::type { typedef typename boost::intrusive::detail::type_rebinder::type Base; rebind_alloc() : Base() {} template< class P0 > rebind_alloc( const P0 & p0) : Base( ::boost::forward< P0 >( p0 )) {} template< class P0 , class P1 > rebind_alloc( const P0 & p0 , const P1 & p1) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )) {} template< class P0 , class P1 , class P2 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )) {} template< class P0 , class P1 , class P2 , class P3 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )) {} template< class P0 , class P1 , class P2 , class P3 , class P4 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )) {} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )) {} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )) {} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )) {} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )) {} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > rebind_alloc( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) : Base( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )) {} }; template struct rebind_traits : allocator_traits::type> {}; template struct portable_rebind_alloc { typedef typename boost::intrusive::detail::type_rebinder::type type; }; //! Returns: `a.allocate(n)` //! static pointer allocate(Alloc &a, size_type n) { return a.allocate(n); } //! Returns: `a.deallocate(p, n)` //! //! Throws: Nothing static void deallocate(Alloc &a, pointer p, size_type n) { return a.deallocate(p, n); } //! Effects: calls `a.construct(p, std::forward(args)...)` if that call is well-formed; //! otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)` static pointer allocate(Alloc &a, size_type n, const_void_pointer p) { const bool value = boost::container::container_detail:: has_member_function_callable_with_allocate ::value; ::boost::integral_constant flag; return allocator_traits::priv_allocate(flag, a, n, p); } //! Effects: calls `a.destroy(p)` if that call is well-formed; //! otherwise, invokes `p->~T()`. template static void destroy(Alloc &a, T*p) { typedef T* destroy_pointer; const bool value = boost::container::container_detail:: has_member_function_callable_with_destroy ::value; ::boost::integral_constant flag; allocator_traits::priv_destroy(flag, a, p); } //! Returns: `a.max_size()` if that expression is well-formed; otherwise, //! `numeric_limits::max()`. static size_type max_size(const Alloc &a) { const bool value = boost::container::container_detail:: has_member_function_callable_with_max_size ::value; ::boost::integral_constant flag; return allocator_traits::priv_max_size(flag, a); } //! Returns: `a.select_on_container_copy_construction()` if that expression is well-formed; //! otherwise, a. static Alloc select_on_container_copy_construction(const Alloc &a) { const bool value = boost::container::container_detail:: has_member_function_callable_with_select_on_container_copy_construction ::value; ::boost::integral_constant flag; return allocator_traits::priv_select_on_container_copy_construction(flag, a); } ///@cond private: static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p) { return a.allocate(n, p); } static pointer priv_allocate(boost::false_type, Alloc &a, size_type n, const_void_pointer) { return allocator_traits::allocate(a, n); } template static void priv_destroy(boost::true_type, Alloc &a, T* p) { a.destroy(p); } template static void priv_destroy(boost::false_type, Alloc &, T* p) { p->~T(); (void)p; } static size_type priv_max_size(boost::true_type, const Alloc &a) { return a.max_size(); } static size_type priv_max_size(boost::false_type, const Alloc &) { return (std::numeric_limits::max)(); } static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a) { return a.select_on_container_copy_construction(); } static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a) { return a; } public: template static void construct(Alloc &a, T *p ) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p ); } template static void construct(Alloc &a, T *p , const P0 & p0) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )); } template static void construct(Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { ::boost::integral_constant ::value> flag; allocator_traits::priv_construct(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )); } private: template static void priv_construct(boost::false_type, Alloc &a, T *p ) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p ); } template static void priv_construct(boost::true_type, Alloc &a, T *p ) { priv_construct_dispatch2(boost::false_type(), a, p ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p ) { a . construct( p ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p ) { ::new((void*)p) T(); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0) { a . construct( p , ::boost::forward< P0 >( p0 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type , typename ::boost::move_detail::forward_type< P3 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type , typename ::boost::move_detail::forward_type< P3 > ::type , typename ::boost::move_detail::forward_type< P4 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type , typename ::boost::move_detail::forward_type< P3 > ::type , typename ::boost::move_detail::forward_type< P4 > ::type , typename ::boost::move_detail::forward_type< P5 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type , typename ::boost::move_detail::forward_type< P3 > ::type , typename ::boost::move_detail::forward_type< P4 > ::type , typename ::boost::move_detail::forward_type< P5 > ::type , typename ::boost::move_detail::forward_type< P6 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type , typename ::boost::move_detail::forward_type< P3 > ::type , typename ::boost::move_detail::forward_type< P4 > ::type , typename ::boost::move_detail::forward_type< P5 > ::type , typename ::boost::move_detail::forward_type< P6 > ::type , typename ::boost::move_detail::forward_type< P7 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type , typename ::boost::move_detail::forward_type< P3 > ::type , typename ::boost::move_detail::forward_type< P4 > ::type , typename ::boost::move_detail::forward_type< P5 > ::type , typename ::boost::move_detail::forward_type< P6 > ::type , typename ::boost::move_detail::forward_type< P7 > ::type , typename ::boost::move_detail::forward_type< P8 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )); } template static void priv_construct(boost::false_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { const bool value = boost::container::container_detail::has_member_function_callable_with_construct < Alloc, T* , typename ::boost::move_detail::forward_type< P0 > ::type , typename ::boost::move_detail::forward_type< P1 > ::type , typename ::boost::move_detail::forward_type< P2 > ::type , typename ::boost::move_detail::forward_type< P3 > ::type , typename ::boost::move_detail::forward_type< P4 > ::type , typename ::boost::move_detail::forward_type< P5 > ::type , typename ::boost::move_detail::forward_type< P6 > ::type , typename ::boost::move_detail::forward_type< P7 > ::type , typename ::boost::move_detail::forward_type< P8 > ::type , typename ::boost::move_detail::forward_type< P9 > ::type > ::value; ::boost::integral_constant flag; priv_construct_dispatch2(flag, a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ) ); } template static void priv_construct(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { priv_construct_dispatch2(boost::false_type(), a, p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ) ); } template static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { a . construct( p , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ) ); } template static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9 ) { ::new((void*)p) T( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )); } ///@endcond }; } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { template inline T* addressof(T& obj) { return static_cast( static_cast( const_cast( &reinterpret_cast(obj) ))); } template const T &max_value(const T &a, const T &b) { return a > b ? a : b; } template const T &min_value(const T &a, const T &b) { return a < b ? a : b; } template SizeType get_next_capacity(const SizeType max_size ,const SizeType capacity ,const SizeType n) { // if (n > max_size - capacity) // throw std::length_error("get_next_capacity"); const SizeType m3 = max_size/3; if (capacity < m3) return capacity + max_value(3*(capacity+1)/5, n); if (capacity < m3*2) return capacity + max_value((capacity+1)/2, n); return max_size; } template inline T* to_raw_pointer(T* p) { return p; } template inline typename Pointer::element_type* to_raw_pointer(const Pointer &p) { return boost::container::container_detail::to_raw_pointer(p.operator->()); } //!To avoid ADL problems with swap template inline void do_swap(T& x, T& y) { using std::swap; swap(x, y); } template inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type) {} template inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type) { container_detail::do_swap(l, r); } template inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type) {} template inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type) { l = r; } template inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type) {} template inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type) { l = ::boost::move(r); } //Rounds "orig_size" by excess to round_to bytes template inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to) { return ((orig_size-1)/round_to+1)*round_to; } template struct ct_rounded_size { enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo }; }; /* template struct __rw_is_enum { struct _C_no { }; struct _C_yes { int _C_dummy [2]; }; struct _C_indirect { // prevent classes with user-defined conversions from matching // use double to prevent float->int gcc conversion warnings _C_indirect (double); }; // nested struct gets rid of bogus gcc errors struct _C_nest { // supply first argument to prevent HP aCC warnings static _C_no _C_is (int, ...); static _C_yes _C_is (int, _C_indirect); static _TypeT _C_make_T (); }; enum { _C_val = sizeof (_C_yes) == sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ())) && !::boost::is_fundamental<_TypeT>::value }; }; */ template struct move_const_ref_type : if_c // < ::boost::is_fundamental::value || ::boost::is_pointer::value || ::boost::is_member_pointer::value || ::boost::is_enum::value < !::boost::is_class::value ,const T & ,const ::boost::rv< T > & > {}; } //namespace container_detail { ////////////////////////////////////////////////////////////////////////////// // // uninitialized_move_alloc // ////////////////////////////////////////////////////////////////////////////// //! Effects: //! \code //! for (; first != last; ++result, ++first) //! allocator_traits::construct(a, &*result, boost::move(*first)); //! \endcode //! //! Returns: result template // F models ForwardIterator F uninitialized_move_alloc(A &a, I f, I l, F r) { while (f != l) { allocator_traits::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f)); ++f; ++r; } return r; } ////////////////////////////////////////////////////////////////////////////// // // uninitialized_copy_alloc // ////////////////////////////////////////////////////////////////////////////// //! Effects: //! \code //! for (; first != last; ++result, ++first) //! allocator_traits::construct(a, &*result, *first); //! \endcode //! //! Returns: result template // F models ForwardIterator F uninitialized_copy_alloc(A &a, I f, I l, F r) { while (f != l) { allocator_traits::construct(a, container_detail::to_raw_pointer(&*r), *f); ++f; ++r; } return r; } ////////////////////////////////////////////////////////////////////////////// // // uninitialized_copy_alloc // ////////////////////////////////////////////////////////////////////////////// //! Effects: //! \code //! for (; first != last; ++result, ++first) //! allocator_traits::construct(a, &*result, *first); //! \endcode //! //! Returns: result template void uninitialized_fill_alloc(A &a, F f, F l, const T &t) { while (f != l) { allocator_traits::construct(a, container_detail::to_raw_pointer(&*f), t); ++f; } } ////////////////////////////////////////////////////////////////////////////// // // uninitialized_copy_or_move_alloc // ////////////////////////////////////////////////////////////////////////////// template // F models ForwardIterator F uninitialized_copy_or_move_alloc (A &a, I f, I l, F r ,typename boost::container::container_detail::enable_if < boost::move_detail::is_move_iterator >::type* = 0) { return ::boost::container::uninitialized_move_alloc(a, f, l, r); } template // F models ForwardIterator F uninitialized_copy_or_move_alloc (A &a, I f, I l, F r ,typename boost::container::container_detail::disable_if < boost::move_detail::is_move_iterator >::type* = 0) { return ::boost::container::uninitialized_copy_alloc(a, f, l, r); } } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail{ template struct is_volatile_rval_filter { static const bool value = ::boost::detail::cv_traits_imp ::is_volatile; }; } //* is a type T declared volatile - is_volatile template< typename T > struct is_volatile : public ::boost::integral_constant ::value> { public: }; template< typename T > struct is_volatile< T& > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct has_trivial_copy_impl { static const bool value = (::boost::type_traits::ice_and< ::boost::is_pod ::value, ::boost::type_traits::ice_not< ::boost::is_volatile ::value > ::value > ::value); }; } // namespace detail template< typename T > struct has_trivial_copy : public ::boost::integral_constant ::value> { public: }; template< typename T > struct has_trivial_copy_constructor : public ::boost::integral_constant ::value> { public: }; template< > struct has_trivial_copy< void > : public ::boost::integral_constant { public: }; template< > struct has_trivial_copy< void const > : public ::boost::integral_constant { public: }; template< > struct has_trivial_copy< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_trivial_copy< void volatile > : public ::boost::integral_constant { public: }; template< > struct has_trivial_copy_constructor< void > : public ::boost::integral_constant { public: }; template< > struct has_trivial_copy_constructor< void const > : public ::boost::integral_constant { public: }; template< > struct has_trivial_copy_constructor< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_trivial_copy_constructor< void volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail{ // // We can't filter out rvalue_references at the same level as // references or we get ambiguities from msvc: // template struct is_const_rvalue_filter { static const bool value = ::boost::detail::cv_traits_imp ::is_const; }; } //* is a type T declared const - is_const template< typename T > struct is_const : public ::boost::integral_constant ::value> { public: }; template< typename T > struct is_const< T& > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct has_trivial_assign_impl { static const bool value = (::boost::type_traits::ice_and< ::boost::is_pod ::value, ::boost::type_traits::ice_not< ::boost::is_const ::value > ::value, ::boost::type_traits::ice_not< ::boost::is_volatile ::value > ::value > ::value); }; } // namespace detail template< typename T > struct has_trivial_assign : public ::boost::integral_constant ::value> { public: }; template< > struct has_trivial_assign< void > : public ::boost::integral_constant { public: }; template< > struct has_trivial_assign< void const > : public ::boost::integral_constant { public: }; template< > struct has_trivial_assign< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_trivial_assign< void volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. // (C) Copyright Gennaro Prota 2003 - 2004. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { template class constant_iterator : public std::iterator { typedef constant_iterator this_type; public: explicit constant_iterator(const T &ref, Difference range_size) : m_ptr(&ref), m_num(range_size){} //Constructors constant_iterator() : m_ptr(0), m_num(0){} constant_iterator& operator++() { increment(); return *this; } constant_iterator operator++(int) { constant_iterator result (*this); increment(); return result; } constant_iterator& operator--() { decrement(); return *this; } constant_iterator operator--(int) { constant_iterator result (*this); decrement(); return result; } friend bool operator== (const constant_iterator& i, const constant_iterator& i2) { return i.equal(i2); } friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) { return !(i == i2); } friend bool operator< (const constant_iterator& i, const constant_iterator& i2) { return i.less(i2); } friend bool operator> (const constant_iterator& i, const constant_iterator& i2) { return i2 < i; } friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) { return !(i > i2); } friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) { return !(i < i2); } friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) { return i2.distance_to(i); } //Arithmetic constant_iterator& operator+=(Difference off) { this->advance(off); return *this; } constant_iterator operator+(Difference off) const { constant_iterator other(*this); other.advance(off); return other; } friend constant_iterator operator+(Difference off, const constant_iterator& right) { return right + off; } constant_iterator& operator-=(Difference off) { this->advance(-off); return *this; } constant_iterator operator-(Difference off) const { return *this + (-off); } const T& operator*() const { return dereference(); } const T& operator[] (Difference n) const { return dereference(); } const T* operator->() const { return &(dereference()); } private: const T * m_ptr; Difference m_num; void increment() { --m_num; } void decrement() { ++m_num; } bool equal(const this_type &other) const { return m_num == other.m_num; } bool less(const this_type &other) const { return other.m_num < m_num; } const T & dereference() const { return *m_ptr; } void advance(Difference n) { m_num -= n; } Difference distance_to(const this_type &other)const { return m_num - other.m_num; } }; template class default_construct_iterator : public std::iterator { typedef default_construct_iterator this_type; public: explicit default_construct_iterator(Difference range_size) : m_num(range_size){} //Constructors default_construct_iterator() : m_num(0){} default_construct_iterator& operator++() { increment(); return *this; } default_construct_iterator operator++(int) { default_construct_iterator result (*this); increment(); return result; } default_construct_iterator& operator--() { decrement(); return *this; } default_construct_iterator operator--(int) { default_construct_iterator result (*this); decrement(); return result; } friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2) { return i.equal(i2); } friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2) { return !(i == i2); } friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2) { return i.less(i2); } friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2) { return i2 < i; } friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2) { return !(i > i2); } friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2) { return !(i < i2); } friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2) { return i2.distance_to(i); } //Arithmetic default_construct_iterator& operator+=(Difference off) { this->advance(off); return *this; } default_construct_iterator operator+(Difference off) const { default_construct_iterator other(*this); other.advance(off); return other; } friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right) { return right + off; } default_construct_iterator& operator-=(Difference off) { this->advance(-off); return *this; } default_construct_iterator operator-(Difference off) const { return *this + (-off); } const T& operator*() const { return dereference(); } const T* operator->() const { return &(dereference()); } const T& operator[] (Difference n) const { return dereference(); } private: Difference m_num; void increment() { --m_num; } void decrement() { ++m_num; } bool equal(const this_type &other) const { return m_num == other.m_num; } bool less(const this_type &other) const { return other.m_num < m_num; } const T & dereference() const { static T dummy; return dummy; } void advance(Difference n) { m_num -= n; } Difference distance_to(const this_type &other)const { return m_num - other.m_num; } }; template class repeat_iterator : public std::iterator { typedef repeat_iterator this_type; public: explicit repeat_iterator(T &ref, Difference range_size) : m_ptr(&ref), m_num(range_size){} //Constructors repeat_iterator() : m_ptr(0), m_num(0){} this_type& operator++() { increment(); return *this; } this_type operator++(int) { this_type result (*this); increment(); return result; } this_type& operator--() { increment(); return *this; } this_type operator--(int) { this_type result (*this); increment(); return result; } friend bool operator== (const this_type& i, const this_type& i2) { return i.equal(i2); } friend bool operator!= (const this_type& i, const this_type& i2) { return !(i == i2); } friend bool operator< (const this_type& i, const this_type& i2) { return i.less(i2); } friend bool operator> (const this_type& i, const this_type& i2) { return i2 < i; } friend bool operator<= (const this_type& i, const this_type& i2) { return !(i > i2); } friend bool operator>= (const this_type& i, const this_type& i2) { return !(i < i2); } friend Difference operator- (const this_type& i, const this_type& i2) { return i2.distance_to(i); } //Arithmetic this_type& operator+=(Difference off) { this->advance(off); return *this; } this_type operator+(Difference off) const { this_type other(*this); other.advance(off); return other; } friend this_type operator+(Difference off, const this_type& right) { return right + off; } this_type& operator-=(Difference off) { this->advance(-off); return *this; } this_type operator-(Difference off) const { return *this + (-off); } T& operator*() const { return dereference(); } T& operator[] (Difference n) const { return dereference(); } T *operator->() const { return &(dereference()); } private: T * m_ptr; Difference m_num; void increment() { --m_num; } void decrement() { ++m_num; } bool equal(const this_type &other) const { return m_num == other.m_num; } bool less(const this_type &other) const { return other.m_num < m_num; } T & dereference() const { return *m_ptr; } void advance(Difference n) { m_num -= n; } Difference distance_to(const this_type &other)const { return m_num - other.m_num; } }; template class emplace_iterator : public std::iterator { typedef emplace_iterator this_type; public: typedef Difference difference_type; explicit emplace_iterator(EmplaceFunctor&e) : m_num(1), m_pe(&e){} emplace_iterator() : m_num(0), m_pe(0){} this_type& operator++() { increment(); return *this; } this_type operator++(int) { this_type result (*this); increment(); return result; } this_type& operator--() { decrement(); return *this; } this_type operator--(int) { this_type result (*this); decrement(); return result; } friend bool operator== (const this_type& i, const this_type& i2) { return i.equal(i2); } friend bool operator!= (const this_type& i, const this_type& i2) { return !(i == i2); } friend bool operator< (const this_type& i, const this_type& i2) { return i.less(i2); } friend bool operator> (const this_type& i, const this_type& i2) { return i2 < i; } friend bool operator<= (const this_type& i, const this_type& i2) { return !(i > i2); } friend bool operator>= (const this_type& i, const this_type& i2) { return !(i < i2); } friend difference_type operator- (const this_type& i, const this_type& i2) { return i2.distance_to(i); } //Arithmetic this_type& operator+=(difference_type off) { this->advance(off); return *this; } this_type operator+(difference_type off) const { this_type other(*this); other.advance(off); return other; } friend this_type operator+(difference_type off, const this_type& right) { return right + off; } this_type& operator-=(difference_type off) { this->advance(-off); return *this; } this_type operator-(difference_type off) const { return *this + (-off); } const T& operator*() const { return dereference(); } const T& operator[](difference_type) const { return dereference(); } const T* operator->() const { return &(dereference()); } template void construct_in_place(A &a, T* ptr) { (*m_pe)(a, ptr); } private: difference_type m_num; EmplaceFunctor * m_pe; void increment() { --m_num; } void decrement() { ++m_num; } bool equal(const this_type &other) const { return m_num == other.m_num; } bool less(const this_type &other) const { return other.m_num < m_num; } const T & dereference() const { static T dummy; return dummy; } void advance(difference_type n) { m_num -= n; } difference_type distance_to(const this_type &other)const { return difference_type(m_num - other.m_num); } }; struct emplace_functor0arg { emplace_functor0arg ( ) {} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr ); } }; template < class P0 > struct emplace_functor1arg { emplace_functor1arg ( const P0 & p0 ) : m_p0 (const_cast(p0)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) ); } P0 & m_p0; }; template < class P0 , class P1 > struct emplace_functor2arg { emplace_functor2arg ( const P0 & p0 , const P1 & p1 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) ); } P0 & m_p0; P1 & m_p1; }; template < class P0 , class P1 , class P2 > struct emplace_functor3arg { emplace_functor3arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; }; template < class P0 , class P1 , class P2 , class P3 > struct emplace_functor4arg { emplace_functor4arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; }; template < class P0 , class P1 , class P2 , class P3 , class P4 > struct emplace_functor5arg { emplace_functor5arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; }; template < class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > struct emplace_functor6arg { emplace_functor6arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; }; template < class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > struct emplace_functor7arg { emplace_functor7arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; }; template < class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > struct emplace_functor8arg { emplace_functor8arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)) , m_p7 (const_cast(p7)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; P7 & m_p7; }; template < class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > struct emplace_functor9arg { emplace_functor9arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)) , m_p7 (const_cast(p7)) , m_p8 (const_cast(p8)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; P7 & m_p7; P8 & m_p8; }; template < class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > struct emplace_functor10arg { emplace_functor10arg ( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9 ) : m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)) , m_p7 (const_cast(p7)) , m_p8 (const_cast(p8)) , m_p9 (const_cast(p9)){} template void operator()(A &a, T *ptr) { allocator_traits ::construct (a, ptr , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) , ::boost::forward< P9 >( this->m_p9 ) ); } P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; P7 & m_p7; P8 & m_p8; P9 & m_p9; }; } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { template inline void construct_in_place(A &a, T* dest, InpIt source) { boost::container::allocator_traits::construct(a, dest, *source); } //#endif template inline void construct_in_place(A &a, T *dest, default_construct_iterator) { boost::container::allocator_traits::construct(a, dest); } template inline void construct_in_place(A &a, T *dest, emplace_iterator ei) { ei.construct_in_place(a, dest); } } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// // // This code comes from N1953 document by Howard E. Hinnant // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost{ namespace container { namespace container_detail { //using namespace boost; template struct version_type : public container_detail::integral_constant { typedef T type; version_type(const version_type&); }; namespace impl{ template , typename T::version>::value> struct extract_version { static const unsigned value = 1; }; template struct extract_version { static const unsigned value = T::version::value; }; template struct has_version { private: struct two {char _[2];}; template static two test(...); template static char test(const typename U::version*); public: static const bool value = sizeof(test(0)) == 1; void dummy(){} }; template ::value> struct version { static const unsigned value = 1; }; template struct version { static const unsigned value = extract_version::value; }; } //namespace impl template struct version : public container_detail::integral_constant::value> { }; } //namespace container_detail { } //namespace container { } //namespace boost{ ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { //!A deleter for scoped_ptr that deallocates the memory //!allocated for an array of objects using a STL allocator. template struct scoped_array_deallocator { typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; scoped_array_deallocator(pointer p, Allocator& a, size_type length) : m_ptr(p), m_alloc(a), m_length(length) {} ~scoped_array_deallocator() { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); } void release() { m_ptr = 0; } private: pointer m_ptr; Allocator& m_alloc; size_type m_length; }; template struct null_scoped_array_deallocator { typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; null_scoped_array_deallocator(pointer, Allocator&, size_type) {} void release() {} }; //!A deleter for scoped_ptr that destroys //!an object using a STL allocator. template struct scoped_destructor_n { typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::value_type value_type; typedef typename AllocTraits::size_type size_type; scoped_destructor_n(pointer p, Allocator& a, size_type n) : m_p(p), m_a(a), m_n(n) {} void release() { m_p = 0; } void increment_size(size_type inc) { m_n += inc; } void increment_size_backwards(size_type inc) { m_n += inc; m_p -= inc; } ~scoped_destructor_n() { if(!m_p) return; value_type *raw_ptr = container_detail::to_raw_pointer(m_p); for(size_type i = 0; i < m_n; ++i, ++raw_ptr) AllocTraits::destroy(m_a, raw_ptr); } private: pointer m_p; Allocator & m_a; size_type m_n; }; //!A deleter for scoped_ptr that destroys //!an object using a STL allocator. template struct null_scoped_destructor_n { typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; null_scoped_destructor_n(pointer, Allocator&, size_type) {} void increment_size(size_type) {} void increment_size_backwards(size_type) {} void release() {} }; template class scoped_destructor { typedef boost::container::allocator_traits AllocTraits; public: typedef typename A::value_type value_type; scoped_destructor(A &a, value_type *pv) : pv_(pv), a_(a) {} ~scoped_destructor() { if(pv_){ AllocTraits::destroy(a_, pv_); } } void release() { pv_ = 0; } private: value_type *pv_; A &a_; }; template class allocator_destroyer { typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::value_type value_type; typedef typename AllocTraits::pointer pointer; typedef container_detail::integral_constant::value> alloc_version; typedef container_detail::integral_constant allocator_v1; typedef container_detail::integral_constant allocator_v2; private: Allocator & a_; private: void priv_deallocate(const pointer &p, allocator_v1) { AllocTraits::deallocate(a_,p, 1); } void priv_deallocate(const pointer &p, allocator_v2) { a_.deallocate_one(p); } public: allocator_destroyer(Allocator &a) : a_(a) {} void operator()(const pointer &p) { AllocTraits::destroy(a_, container_detail::to_raw_pointer(p)); priv_deallocate(p, alloc_version()); } }; } //namespace container_detail { } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { //!A deleter for scoped_ptr that deallocates the memory //!allocated for an object using a STL allocator. template struct scoped_deallocator { typedef allocator_traits allocator_traits_type; typedef typename allocator_traits_type::pointer pointer; typedef container_detail::integral_constant::value> alloc_version; typedef container_detail::integral_constant allocator_v1; typedef container_detail::integral_constant allocator_v2; private: void priv_deallocate(allocator_v1) { m_alloc.deallocate(m_ptr, 1); } void priv_deallocate(allocator_v2) { m_alloc.deallocate_one(m_ptr); } private: scoped_deallocator(scoped_deallocator &); scoped_deallocator& operator=(scoped_deallocator &); public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: public: pointer m_ptr; A& m_alloc; scoped_deallocator(pointer p, A& a) : m_ptr(p), m_alloc(a) {} ~scoped_deallocator() { if (m_ptr)priv_deallocate(alloc_version()); } scoped_deallocator(::boost::rv< scoped_deallocator > & o) : m_ptr(o.m_ptr), m_alloc(o.m_alloc) { o.release(); } pointer get() const { return m_ptr; } void release() { m_ptr = 0; } }; template class allocator_destroyer_and_chain_builder { typedef allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef typename A::multiallocation_chain multiallocation_chain; A & a_; multiallocation_chain &c_; public: allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c) : a_(a), c_(c) {} void operator()(const typename A::pointer &p) { allocator_traits::destroy(a_, container_detail::to_raw_pointer(p)); c_.push_front(p); } }; template class allocator_multialloc_chain_node_deallocator { typedef allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef typename A::multiallocation_chain multiallocation_chain; typedef allocator_destroyer_and_chain_builder chain_builder; A & a_; multiallocation_chain c_; public: allocator_multialloc_chain_node_deallocator(A &a) : a_(a), c_() {} chain_builder get_chain_builder() { return chain_builder(a_, c_); } ~allocator_multialloc_chain_node_deallocator() { if(!c_.empty()) a_.deallocate_individual(boost::move(c_)); } }; template struct node_compare : private ValueCompare { typedef typename ValueCompare::key_type key_type; typedef typename ValueCompare::value_type value_type; typedef typename ValueCompare::key_of_value key_of_value; node_compare(const ValueCompare &pred) : ValueCompare(pred) {} ValueCompare &value_comp() { return static_cast(*this); } ValueCompare &value_comp() const { return static_cast(*this); } bool operator()(const Node &a, const Node &b) const { return ValueCompare::operator()(a.get_data(), b.get_data()); } }; template struct node_alloc_holder { typedef allocator_traits allocator_traits_type; typedef node_alloc_holder self_t; typedef typename allocator_traits_type::value_type value_type; typedef typename ICont::value_type Node; typedef typename allocator_traits_type::template portable_rebind_alloc::type NodeAlloc; typedef allocator_traits node_allocator_traits_type; typedef A ValAlloc; typedef typename node_allocator_traits_type::pointer NodePtr; typedef container_detail::scoped_deallocator Deallocator; typedef typename node_allocator_traits_type::size_type size_type; typedef typename node_allocator_traits_type::difference_type difference_type; typedef container_detail::integral_constant allocator_v1; typedef container_detail::integral_constant allocator_v2; typedef container_detail::integral_constant::value> alloc_version; typedef typename ICont::iterator icont_iterator; typedef typename ICont::const_iterator icont_citerator; typedef allocator_destroyer Destroyer; typedef allocator_traits NodeAllocTraits; private: public: node_alloc_holder& operator=(node_alloc_holder &t) { this->operator=(static_cast & >(const_cast(t))); return *this;} public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: public: //Constructors for sequence containers node_alloc_holder() : members_() {} explicit node_alloc_holder(const ValAlloc &a) : members_(a) {} explicit node_alloc_holder(const node_alloc_holder &x) : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) {} explicit node_alloc_holder(::boost::rv< node_alloc_holder > & x) : members_(boost::move(x.node_alloc())) { this->icont().swap(x.icont()); } //Constructors for associative containers explicit node_alloc_holder(const ValAlloc &a, const Pred &c) : members_(a, c) {} explicit node_alloc_holder(const node_alloc_holder &x, const Pred &c) : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c) {} explicit node_alloc_holder(const Pred &c) : members_(c) {} //helpers for move assignments explicit node_alloc_holder(::boost::rv< node_alloc_holder > & x, const Pred &c) : members_(boost::move(x.node_alloc()), c) { this->icont().swap(x.icont()); } void copy_assign_alloc(const node_alloc_holder &x) { container_detail::bool_ flag; container_detail::assign_alloc( static_cast(this->members_) , static_cast(x.members_), flag); } void move_assign_alloc( node_alloc_holder &x) { container_detail::bool_ flag; container_detail::move_alloc( static_cast(this->members_) , static_cast(x.members_), flag); } ~node_alloc_holder() { this->clear(alloc_version()); } size_type max_size() const { return allocator_traits_type::max_size(this->node_alloc()); } NodePtr allocate_one() { return this->allocate_one(alloc_version()); } NodePtr allocate_one(allocator_v1) { return this->node_alloc().allocate(1); } NodePtr allocate_one(allocator_v2) { return this->node_alloc().allocate_one(); } void deallocate_one(const NodePtr &p) { return this->deallocate_one(p, alloc_version()); } void deallocate_one(const NodePtr &p, allocator_v1) { this->node_alloc().deallocate(p, 1); } void deallocate_one(const NodePtr &p, allocator_v2) { this->node_alloc().deallocate_one(p); } NodePtr create_node() { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) ); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 > NodePtr create_node( const P0 & p0) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 > NodePtr create_node( const P0 & p0 , const P1 & p1) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 , class P3 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 , class P3 , class P4 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > NodePtr create_node( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); allocator_traits ::construct (this->node_alloc(), container_detail::addressof(p->m_data) , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )); node_deallocator . release(); typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } template NodePtr create_node_from_it(const It &it) { NodePtr p = this->allocate_one(); Deallocator node_deallocator(p, this->node_alloc()); ::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it); node_deallocator.release(); //This does not throw typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; return (p); } void destroy_node(const NodePtr &nodep) { allocator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep)); this->deallocate_one(nodep); } void swap(node_alloc_holder &x) { this->icont().swap(x.icont()); container_detail::bool_ flag; container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag); } template FwdIterator allocate_many_and_construct (FwdIterator beg, difference_type n, Inserter inserter) { if(n){ typedef typename NodeAlloc::multiallocation_chain multiallocation_chain; //Try to allocate memory in a single block multiallocation_chain mem(this->node_alloc().allocate_individual(n)); int constructed = 0; Node *p = 0; { try{ for(difference_type i = 0; i < n; ++i, ++beg, --constructed){ p = container_detail::to_raw_pointer(mem.front()); mem.pop_front(); //This can throw constructed = 0; boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg); ++constructed; //This does not throw typedef typename Node::hook_type hook_type; ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; //This can throw in some containers (predicate might throw) inserter(*p); } } catch(...){ if(constructed){ allocator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(p)); } this->node_alloc().deallocate_individual(boost::move(mem)); throw; } } } return beg; } void clear(allocator_v1) { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } void clear(allocator_v2) { typename NodeAlloc::multiallocation_chain chain; allocator_destroyer_and_chain_builder builder(this->node_alloc(), chain); this->icont().clear_and_dispose(builder); //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled::value == true)); if(!chain.empty()) this->node_alloc().deallocate_individual(boost::move(chain)); } icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1) { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); } icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2) { allocator_multialloc_chain_node_deallocator chain_holder(this->node_alloc()); return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder()); } template size_type erase_key(const Key& k, const Comparator &comp, allocator_v1) { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); } template size_type erase_key(const Key& k, const Comparator &comp, allocator_v2) { allocator_multialloc_chain_node_deallocator chain_holder(this->node_alloc()); return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder()); } protected: struct cloner { cloner(node_alloc_holder &holder) : m_holder(holder) {} NodePtr operator()(const Node &other) const { return m_holder.create_node(other.get_data()); } node_alloc_holder &m_holder; }; struct members_holder : public NodeAlloc { private: members_holder(const members_holder&); members_holder & operator=(const members_holder&); public: members_holder() : NodeAlloc(), m_icont() {} template explicit members_holder(const ConvertibleToAlloc & c2alloc) : NodeAlloc(boost::forward(c2alloc)) , m_icont() {} template members_holder(const ConvertibleToAlloc & c2alloc, const Pred &c) : NodeAlloc(boost::forward(c2alloc)) , m_icont(typename ICont::value_compare(c)) {} explicit members_holder(const Pred &c) : NodeAlloc() , m_icont(typename ICont::value_compare(c)) {} //The intrusive container ICont m_icont; }; ICont &non_const_icont() const { return const_cast(this->members_.m_icont); } ICont &icont() { return this->members_.m_icont; } const ICont &icont() const { return this->members_.m_icont; } NodeAlloc &node_alloc() { return static_cast(this->members_); } const NodeAlloc &node_alloc() const { return static_cast(this->members_); } members_holder members_; }; } //namespace container_detail { } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { template struct pair; template struct is_pair { static const bool value = false; }; template struct is_pair< pair > { static const bool value = true; }; template struct is_pair< std::pair > { static const bool value = true; }; struct pair_nat; struct piecewise_construct_t { }; static const piecewise_construct_t piecewise_construct = piecewise_construct_t(); /* template struct pair { template pair(pair&& p); template pair(piecewise_construct_t, tuple first_args, tuple second_args); template pair& operator=(const pair& p); pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable::value && is_nothrow_move_assignable::value); template pair& operator=(pair&& p); void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && noexcept(swap(second, p.second))); }; template bool operator==(const pair&, const pair&); template bool operator!=(const pair&, const pair&); template bool operator< (const pair&, const pair&); template bool operator> (const pair&, const pair&); template bool operator>=(const pair&, const pair&); template bool operator<=(const pair&, const pair&); */ template struct pair { private: public: pair& operator=(pair &t) { this->operator=(static_cast & >(const_cast(t))); return *this;} public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: public: typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; //Default constructor pair() : first(), second() {} //pair copy assignment pair(const pair& x) : first(x.first), second(x.second) {} //pair move constructor pair(::boost::rv< pair > & p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} template pair(const pair &p) : first(p.first), second(p.second) {} template pair(::boost::rv< pair > & p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} //pair from two values pair(const T1 &t1, const T2 &t2) : first(t1) , second(t2) {} template pair(const U & u, const V & v) : first(::boost::forward(u)) , second(::boost::forward(v)) {} //And now compatibility with std::pair pair(const std::pair& x) : first(x.first), second(x.second) {} template pair(const std::pair& p) : first(p.first), second(p.second) {} pair(::boost::rv< std::pair > & p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} template pair(::boost::rv< std::pair > & p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} //piecewise_construct missing //template pair(pair&& p); //template // pair(piecewise_construct_t, tuple first_args, // tuple second_args); /* //Variadic versions template pair(BOOST_CONTAINER_PP_PARAM(U, u), typename container_detail::disable_if < container_detail::is_pair< typename container_detail::remove_ref_const::type >, pair_nat>::type* = 0) : first(::boost::forward(u)) , second() {} #ifdef BOOST_CONTAINER_PERFECT_FORWARDING template pair(U &&u, V &&v) : first(::boost::forward(u)) , second(::boost::forward(v), ::boost::forward(args)...) {} #else #define BOOST_PP_LOCAL_MACRO(n) template pair(BOOST_CONTAINER_PP_PARAM(U, u) ,BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) : first(::boost::forward(u)) , second(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) {} //! #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #include BOOST_PP_LOCAL_ITERATE() #endif */ //pair copy assignment pair& operator=(const ::boost::rv< pair > & p) { first = p.first; second = p.second; return *this; } //pair move assignment pair& operator=(::boost::rv< pair > & p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } template typename ::boost::container::container_detail::enable_if_c < !(::boost::container::container_detail::is_same::value && ::boost::container::container_detail::is_same::value) , pair &>::type operator=(const pair&p) { first = p.first; second = p.second; return *this; } template typename ::boost::container::container_detail::enable_if_c < !(::boost::container::container_detail::is_same::value && ::boost::container::container_detail::is_same::value) , pair &>::type operator=(::boost::rv< pair > & p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } //std::pair copy assignment pair& operator=(const std::pair &p) { first = p.first; second = p.second; return *this; } template pair& operator=(const std::pair &p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } //std::pair move assignment pair& operator=(::boost::rv< std::pair > & p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } template pair& operator=(::boost::rv< std::pair > & p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } //swap void swap(pair& p) { using std::swap; swap(this->first, p.first); swap(this->second, p.second); } }; template inline bool operator==(const pair& x, const pair& y) { return static_cast(x.first == y.first && x.second == y.second); } template inline bool operator< (const pair& x, const pair& y) { return static_cast(x.first < y.first || (!(y.first < x.first) && x.second < y.second)); } template inline bool operator!=(const pair& x, const pair& y) { return static_cast(!(x == y)); } template inline bool operator> (const pair& x, const pair& y) { return y < x; } template inline bool operator>=(const pair& x, const pair& y) { return static_cast(!(x < y)); } template inline bool operator<=(const pair& x, const pair& y) { return static_cast(!(y < x)); } template inline pair make_pair(T1 x, T2 y) { return pair(x, y); } template inline void swap(pair& x, pair& y) { swap(x.first, y.first); swap(x.second, y.second); } } //namespace container_detail { } //namespace container { //Without this specialization recursive flat_(multi)map instantiation fails //because is_enum needs to instantiate the recursive pair, leading to a compilation error). //This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation. template struct is_enum; template struct is_enum< ::boost::container::container_detail::pair > { static const bool value = false; }; //This specialization is needed to avoid instantiation of pair in //is_class, and allow recursive maps. template struct is_class< ::boost::container::container_detail::pair > : public ::boost::true_type {}; template struct has_move_emulation_enabled< ::boost::container::container_detail::pair > : ::boost::true_type {}; } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { template struct value_compare_impl : public KeyCompare { typedef Value value_type; typedef KeyCompare key_compare; typedef KeyOfValue key_of_value; typedef Key key_type; value_compare_impl(const key_compare &kcomp) : key_compare(kcomp) {} const key_compare &key_comp() const { return static_cast(*this); } key_compare &key_comp() { return static_cast(*this); } template struct is_key { static const bool value = is_same::value; }; template typename enable_if_c::value, const key_type &>::type key_forward(const T &key) const { return key; } template typename enable_if_c::value, const key_type &>::type key_forward(const T &key) const { return KeyOfValue()(key); } template bool operator()(const KeyType &key1, const KeyType2 &key2) const { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); } }; template struct rbtree_hook { typedef typename container_detail::bi::make_set_base_hook < container_detail::bi::void_pointer , container_detail::bi::link_mode , container_detail::bi::optimize_size >::type type; }; //This trait is used to type-pun std::pair because in C++03 //compilers std::pair is useless for C++11 features template struct rbtree_internal_data_type { typedef T type; }; template struct rbtree_internal_data_type< std::pair > { typedef pair type; }; //The node to be store in the tree template struct rbtree_node : public rbtree_hook::type { private: //BOOST_COPYABLE_AND_MOVABLE(rbtree_node) rbtree_node(); public: typedef typename rbtree_hook::type hook_type; typedef T value_type; typedef typename rbtree_internal_data_type::type internal_type; typedef rbtree_node node_type; T &get_data() { T* ptr = reinterpret_cast(&this->m_data); return *ptr; } const T &get_data() const { const T* ptr = reinterpret_cast(&this->m_data); return *ptr; } internal_type m_data; template void do_assign(const std::pair &p) { const_cast(m_data.first) = p.first; m_data.second = p.second; } template void do_assign(const pair &p) { const_cast(m_data.first) = p.first; m_data.second = p.second; } template void do_assign(const V &v) { m_data = v; } template void do_move_assign(std::pair &p) { const_cast(m_data.first) = ::boost::move(p.first); m_data.second = ::boost::move(p.second); } template void do_move_assign(pair &p) { const_cast(m_data.first) = ::boost::move(p.first); m_data.second = ::boost::move(p.second); } template void do_move_assign(V &v) { m_data = ::boost::move(v); } }; }//namespace container_detail { namespace container_detail { template struct intrusive_rbtree_type { typedef typename boost::container:: allocator_traits::value_type value_type; typedef typename boost::container:: allocator_traits::void_pointer void_pointer; typedef typename boost::container:: allocator_traits::size_type size_type; typedef typename container_detail::rbtree_node node_type; typedef node_compare node_compare_type; typedef typename container_detail::bi::make_rbtree ,container_detail::bi::base_hook::type> ,container_detail::bi::constant_time_size ,container_detail::bi::size_type >::type container_type; typedef container_type type ; }; } //namespace container_detail { namespace container_detail { template class rbtree : protected container_detail::node_alloc_holder < A , typename container_detail::intrusive_rbtree_type >::type , KeyCompare > { typedef typename container_detail::intrusive_rbtree_type < A, value_compare_impl >::type Icont; typedef container_detail::node_alloc_holder AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; typedef rbtree < Key, Value, KeyOfValue , KeyCompare, A> ThisType; typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef typename AllocHolder::ValAlloc ValAlloc; typedef typename AllocHolder::Node Node; typedef typename Icont::iterator iiterator; typedef typename Icont::const_iterator iconst_iterator; typedef container_detail::allocator_destroyer Destroyer; typedef typename AllocHolder::allocator_v1 allocator_v1; typedef typename AllocHolder::allocator_v2 allocator_v2; typedef typename AllocHolder::alloc_version alloc_version; class RecyclingCloner; friend class RecyclingCloner; class RecyclingCloner { public: RecyclingCloner(AllocHolder &holder, Icont &irbtree) : m_holder(holder), m_icont(irbtree) {} NodePtr operator()(const Node &other) const { if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){ //First recycle a node (this can't throw) try{ //This can throw p->do_assign(other.m_data); return p; } catch(...){ //If there is an exception destroy the whole source m_holder.destroy_node(p); while((p = m_icont.unlink_leftmost_without_rebalance())){ m_holder.destroy_node(p); } throw; } } else{ return m_holder.create_node(other.m_data); } } AllocHolder &m_holder; Icont &m_icont; }; class RecyclingMoveCloner; friend class RecyclingMoveCloner; class RecyclingMoveCloner { public: RecyclingMoveCloner(AllocHolder &holder, Icont &irbtree) : m_holder(holder), m_icont(irbtree) {} NodePtr operator()(const Node &other) const { if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){ //First recycle a node (this can't throw) try{ //This can throw p->do_move_assign(const_cast(other).m_data); return p; } catch(...){ //If there is an exception destroy the whole source m_holder.destroy_node(p); while((p = m_icont.unlink_leftmost_without_rebalance())){ m_holder.destroy_node(p); } throw; } } else{ return m_holder.create_node(other.m_data); } } AllocHolder &m_holder; Icont &m_icont; }; public: rbtree& operator=(rbtree &t) { this->operator=(static_cast & >(const_cast(t))); return *this;} public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: public: typedef Key key_type; typedef Value value_type; typedef A allocator_type; typedef KeyCompare key_compare; typedef value_compare_impl< Key, Value , KeyCompare, KeyOfValue> value_compare; typedef typename boost::container:: allocator_traits::pointer pointer; typedef typename boost::container:: allocator_traits::const_pointer const_pointer; typedef typename boost::container:: allocator_traits::reference reference; typedef typename boost::container:: allocator_traits::const_reference const_reference; typedef typename boost::container:: allocator_traits::size_type size_type; typedef typename boost::container:: allocator_traits::difference_type difference_type; typedef difference_type rbtree_difference_type; typedef pointer rbtree_pointer; typedef const_pointer rbtree_const_pointer; typedef reference rbtree_reference; typedef const_reference rbtree_const_reference; typedef NodeAlloc stored_allocator_type; private: template struct key_node_compare : private KeyValueCompare { key_node_compare(const KeyValueCompare &comp) : KeyValueCompare(comp) {} template struct is_node { static const bool value = is_same::value; }; template typename enable_if_c::value, const value_type &>::type key_forward(const T &node) const { return node.get_data(); } template typename enable_if_c::value, const T &>::type key_forward(const T &key) const { return key; } template bool operator()(const KeyType &key1, const KeyType2 &key2) const { return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); } }; typedef key_node_compare KeyNodeCompare; public: //rbtree const_iterator class const_iterator : public std::iterator < std::bidirectional_iterator_tag , value_type , rbtree_difference_type , rbtree_const_pointer , rbtree_const_reference> { protected: typedef typename Icont::iterator iiterator; iiterator m_it; explicit const_iterator(iiterator it) : m_it(it){} void prot_incr() { ++m_it; } void prot_decr() { --m_it; } private: iiterator get() { return this->m_it; } public: friend class rbtree ; typedef rbtree_difference_type difference_type; //Constructors const_iterator() : m_it() {} //Pointer like operators const_reference operator*() const { return m_it->get_data(); } const_pointer operator->() const { return const_pointer(&m_it->get_data()); } //Increment / Decrement const_iterator& operator++() { prot_incr(); return *this; } const_iterator operator++(int) { iiterator tmp = m_it; ++*this; return const_iterator(tmp); } const_iterator& operator--() { prot_decr(); return *this; } const_iterator operator--(int) { iiterator tmp = m_it; --*this; return const_iterator(tmp); } //Comparison operators bool operator== (const const_iterator& r) const { return m_it == r.m_it; } bool operator!= (const const_iterator& r) const { return m_it != r.m_it; } }; //rbtree iterator class iterator : public const_iterator { private: explicit iterator(iiterator it) : const_iterator(it) {} iiterator get() { return this->m_it; } public: friend class rbtree ; typedef rbtree_pointer pointer; typedef rbtree_reference reference; //Constructors iterator(){} //Pointer like operators reference operator*() const { return this->m_it->get_data(); } pointer operator->() const { return boost::intrusive::pointer_traits::pointer_to(this->m_it->get_data()); } //Increment / Decrement iterator& operator++() { this->prot_incr(); return *this; } iterator operator++(int) { iiterator tmp = this->m_it; ++*this; return iterator(tmp); } iterator& operator--() { this->prot_decr(); return *this; } iterator operator--(int) { iterator tmp = *this; --*this; return tmp; } }; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; rbtree() : AllocHolder(key_compare()) {} rbtree(const key_compare& comp, const allocator_type& a = allocator_type()) : AllocHolder(a, comp) {} template rbtree(InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& a, bool unique_insertion) : AllocHolder(a, comp) { typedef typename std::iterator_traits::iterator_category ItCat; priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat()); } template rbtree( ordered_range_t, InputIterator first, InputIterator last , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()) : AllocHolder(a, comp) { typedef typename std::iterator_traits::iterator_category ItCat; priv_create_and_insert_ordered_nodes(first, last, alloc_version(), ItCat()); } rbtree(const rbtree& x) : AllocHolder(x, x.key_comp()) { this->icont().clone_from (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); } rbtree(::boost::rv< rbtree > & x) : AllocHolder(::boost::move(static_cast(x)), x.key_comp()) {} rbtree(const rbtree& x, const allocator_type &a) : AllocHolder(a, x.key_comp()) { this->icont().clone_from (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); } rbtree(::boost::rv< rbtree > & x, const allocator_type &a) : AllocHolder(a, x.key_comp()) { if(this->node_alloc() == x.node_alloc()){ this->icont().swap(x.icont()); } else{ this->icont().clone_from (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); } } ~rbtree() {} //AllocHolder clears the tree rbtree& operator=(const ::boost::rv< rbtree > & x) { if (&x != this){ NodeAlloc &this_alloc = this->get_stored_allocator(); const NodeAlloc &x_alloc = x.get_stored_allocator(); container_detail::bool_:: propagate_on_container_copy_assignment::value> flag; if(flag && this_alloc != x_alloc){ this->clear(); } this->AllocHolder::copy_assign_alloc(x); //Transfer all the nodes to a temporary tree //If anything goes wrong, all the nodes will be destroyed //automatically Icont other_tree(::boost::move(this->icont())); //Now recreate the source tree reusing nodes stored by other_tree this->icont().clone_from (x.icont() , RecyclingCloner(*this, other_tree) , Destroyer(this->node_alloc())); //If there are remaining nodes, destroy them NodePtr p; while((p = other_tree.unlink_leftmost_without_rebalance())){ AllocHolder::destroy_node(p); } } return *this; } rbtree& operator=(::boost::rv< rbtree > & x) { if (&x != this){ NodeAlloc &this_alloc = this->node_alloc(); NodeAlloc &x_alloc = x.node_alloc(); //If allocators are equal we can just swap pointers if(this_alloc == x_alloc){ //Destroy and swap pointers this->clear(); this->icont() = ::boost::move(x.icont()); //Move allocator if needed this->AllocHolder::move_assign_alloc(x); } //If unequal allocators, then do a one by one move else{ //Transfer all the nodes to a temporary tree //If anything goes wrong, all the nodes will be destroyed //automatically Icont other_tree(::boost::move(this->icont())); //Now recreate the source tree reusing nodes stored by other_tree this->icont().clone_from (x.icont() , RecyclingMoveCloner(*this, other_tree) , Destroyer(this->node_alloc())); //If there are remaining nodes, destroy them NodePtr p; while((p = other_tree.unlink_leftmost_without_rebalance())){ AllocHolder::destroy_node(p); } } } return *this; } public: // accessors: value_compare value_comp() const { return this->icont().value_comp().value_comp(); } key_compare key_comp() const { return this->icont().value_comp().value_comp().key_comp(); } allocator_type get_allocator() const { return allocator_type(this->node_alloc()); } const stored_allocator_type &get_stored_allocator() const { return this->node_alloc(); } stored_allocator_type &get_stored_allocator() { return this->node_alloc(); } iterator begin() { return iterator(this->icont().begin()); } const_iterator begin() const { return this->cbegin(); } iterator end() { return iterator(this->icont().end()); } const_iterator end() const { return this->cend(); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return this->crbegin(); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return this->crend(); } //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cbegin() const { return const_iterator(this->non_const_icont().begin()); } //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cend() const { return const_iterator(this->non_const_icont().end()); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } bool empty() const { return !this->size(); } size_type size() const { return this->icont().size(); } size_type max_size() const { return AllocHolder::max_size(); } void swap(ThisType& x) { AllocHolder::swap(x); } public: typedef typename Icont::insert_commit_data insert_commit_data; // insert/erase std::pair insert_unique_check (const key_type& key, insert_commit_data &data) { std::pair ret = this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data); return std::pair(iterator(ret.first), ret.second); } std::pair insert_unique_check (const_iterator hint, const key_type& key, insert_commit_data &data) { std::pair ret = this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data); return std::pair(iterator(ret.first), ret.second); } iterator insert_unique_commit(const value_type& v, insert_commit_data &data) { NodePtr tmp = AllocHolder::create_node(v); iiterator it(this->icont().insert_unique_commit(*tmp, data)); return iterator(it); } template iterator insert_unique_commit (const MovableConvertible & mv, insert_commit_data &data) { NodePtr tmp = AllocHolder::create_node(boost::forward(mv)); iiterator it(this->icont().insert_unique_commit(*tmp, data)); return iterator(it); } std::pair insert_unique(const value_type& v) { insert_commit_data data; std::pair ret = this->insert_unique_check(KeyOfValue()(v), data); if(!ret.second) return ret; return std::pair (this->insert_unique_commit(v, data), true); } template std::pair insert_unique(const MovableConvertible & mv) { insert_commit_data data; std::pair ret = this->insert_unique_check(KeyOfValue()(mv), data); if(!ret.second) return ret; return std::pair (this->insert_unique_commit(boost::forward(mv), data), true); } private: std::pair emplace_unique_impl(NodePtr p) { value_type &v = p->get_data(); insert_commit_data data; std::pair ret = this->insert_unique_check(KeyOfValue()(v), data); if(!ret.second){ Destroyer(this->node_alloc())(p); return ret; } return std::pair ( iterator(iiterator(this->icont().insert_unique_commit(*p, data))) , true ); } iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p) { value_type &v = p->get_data(); insert_commit_data data; std::pair ret = this->insert_unique_check(hint, KeyOfValue()(v), data); if(!ret.second){ Destroyer(this->node_alloc())(p); return ret.first; } return iterator(iiterator(this->icont().insert_unique_commit(*p, data))); } public: std::pair emplace_unique() { return this->emplace_unique_impl (AllocHolder::create_node()); } iterator emplace_hint_unique(const_iterator hint ) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node()); } iterator emplace_equal() { NodePtr p(AllocHolder::create_node()); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } iterator emplace_hint_equal(const_iterator hint ) { NodePtr p(AllocHolder::create_node()); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 > std::pair emplace_unique( const P0 & p0) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ))); } template< class P0 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ))); } template< class P0 > iterator emplace_equal( const P0 & p0) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 > std::pair emplace_unique( const P0 & p0 , const P1 & p1) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ))); } template< class P0 , class P1 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ))); } template< class P0 , class P1 > iterator emplace_equal( const P0 & p0 , const P1 & p1) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ))); } template< class P0 , class P1 , class P2 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ))); } template< class P0 , class P1 , class P2 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 , class P3 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ))); } template< class P0 , class P1 , class P2 , class P3 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ))); } template< class P0 , class P1 , class P2 , class P3 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 , class P3 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > std::pair emplace_unique( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { return this->emplace_unique_impl (AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > iterator emplace_hint_unique(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { return this->emplace_unique_hint_impl (hint, AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ))); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > iterator emplace_equal( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ))); return iterator(this->icont(). insert_equal(this->icont(). end(), *p)); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > iterator emplace_hint_equal(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { NodePtr p(AllocHolder::create_node( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ))); return iterator(this->icont(). insert_equal(hint . get(), *p)); } iterator insert_unique(const_iterator hint, const value_type& v) { insert_commit_data data; std::pair ret = this->insert_unique_check(hint, KeyOfValue()(v), data); if(!ret.second) return ret.first; return this->insert_unique_commit(v, data); } template iterator insert_unique(const_iterator hint, const MovableConvertible & mv) { insert_commit_data data; std::pair ret = this->insert_unique_check(hint, KeyOfValue()(mv), data); if(!ret.second) return ret.first; return this->insert_unique_commit(boost::forward(mv), data); } template void insert_unique(InputIterator first, InputIterator last) { if(this->empty()){ //Insert with end hint, to achieve linear //complexity if [first, last) is ordered const_iterator hint(this->cend()); for( ; first != last; ++first) hint = this->insert_unique(hint, *first); } else{ for( ; first != last; ++first) this->insert_unique(*first); } } iterator insert_equal(const value_type& v) { NodePtr p(AllocHolder::create_node(v)); return iterator(this->icont().insert_equal(this->icont().end(), *p)); } template iterator insert_equal(const MovableConvertible & mv) { NodePtr p(AllocHolder::create_node(boost::forward(mv))); return iterator(this->icont().insert_equal(this->icont().end(), *p)); } iterator insert_equal(const_iterator hint, const value_type& v) { NodePtr p(AllocHolder::create_node(v)); return iterator(this->icont().insert_equal(hint.get(), *p)); } template iterator insert_equal(const_iterator hint, const MovableConvertible & mv) { NodePtr p(AllocHolder::create_node(boost::forward(mv))); return iterator(this->icont().insert_equal(hint.get(), *p)); } template void insert_equal(InputIterator first, InputIterator last) { //Insert with end hint, to achieve linear //complexity if [first, last) is ordered const_iterator hint(this->cend()); for( ; first != last; ++first) hint = this->insert_equal(hint, *first); } iterator erase(const_iterator position) { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); } size_type erase(const key_type& k) { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); } iterator erase(const_iterator first, const_iterator last) { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); } void clear() { AllocHolder::clear(alloc_version()); } // set operations: iterator find(const key_type& k) { return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); } const_iterator find(const key_type& k) const { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); } size_type count(const key_type& k) const { return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); } iterator lower_bound(const key_type& k) { return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); } const_iterator lower_bound(const key_type& k) const { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); } iterator upper_bound(const key_type& k) { return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); } const_iterator upper_bound(const key_type& k) const { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); } std::pair equal_range(const key_type& k) { std::pair ret = this->icont().equal_range(k, KeyNodeCompare(value_comp())); return std::pair(iterator(ret.first), iterator(ret.second)); } std::pair equal_range(const key_type& k) const { std::pair ret = this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp())); return std::pair (const_iterator(ret.first), const_iterator(ret.second)); } private: //Iterator range version template void priv_create_and_insert_nodes (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag) { if(unique){ for (; beg != end; ++beg){ this->insert_unique(*beg); } } else{ for (; beg != end; ++beg){ this->insert_equal(*beg); } } } template void priv_create_and_insert_nodes (InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag) { //Just forward to the default one priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag()); } class insertion_functor; friend class insertion_functor; class insertion_functor { Icont &icont_; public: insertion_functor(Icont &icont) : icont_(icont) {} void operator()(Node &n) { this->icont_.insert_equal(this->icont_.cend(), n); } }; template void priv_create_and_insert_nodes (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag) { if(beg != end){ if(unique){ priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag()); } else{ //Optimized allocation and construction this->allocate_many_and_construct (beg, std::distance(beg, end), insertion_functor(this->icont())); } } } //Iterator range version template void priv_create_and_insert_ordered_nodes (InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag) { const_iterator cend_n(this->cend()); for (; beg != end; ++beg){ this->insert_before(cend_n, *beg); } } template void priv_create_and_insert_ordered_nodes (InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag) { //Just forward to the default one priv_create_and_insert_ordered_nodes(beg, end, allocator_v1(), std::input_iterator_tag()); } class back_insertion_functor; friend class back_insertion_functor; class back_insertion_functor { Icont &icont_; public: back_insertion_functor(Icont &icont) : icont_(icont) {} void operator()(Node &n) { this->icont_.push_back(n); } }; template void priv_create_and_insert_ordered_nodes (FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag) { if(beg != end){ //Optimized allocation and construction this->allocate_many_and_construct (beg, std::distance(beg, end), back_insertion_functor(this->icont())); } } }; template inline bool operator==(const rbtree& x, const rbtree& y) { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } template inline bool operator<(const rbtree& x, const rbtree& y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } template inline bool operator!=(const rbtree& x, const rbtree& y) { return !(x == y); } template inline bool operator>(const rbtree& x, const rbtree& y) { return y < x; } template inline bool operator<=(const rbtree& x, const rbtree& y) { return !(y < x); } template inline bool operator>=(const rbtree& x, const rbtree& y) { return !(x < y); } template inline void swap(rbtree& x, rbtree& y) { x.swap(y); } } //namespace container_detail { } //namespace container { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations template struct has_trivial_destructor_after_move > { static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { namespace container_detail { template struct value_init { value_init() : m_t() {} operator T &() { return m_t; } T m_t; }; } //namespace container_detail { } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2010-2011. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { template< typename T, typename U > struct is_same : public ::boost::integral_constant { public: }; template< typename T > struct is_same< T,T > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // Boost enable_if library // Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) // Even the definition of enable_if causes problems on some compilers, // so it's macroed out for all compilers that do not support SFINAE namespace boost { template struct enable_if_c { typedef T type; }; template struct enable_if_c {}; template struct enable_if : public enable_if_c {}; template struct lazy_enable_if_c { typedef typename T::type type; }; template struct lazy_enable_if_c {}; template struct lazy_enable_if : public lazy_enable_if_c {}; template struct disable_if_c { typedef T type; }; template struct disable_if_c {}; template struct disable_if : public disable_if_c {}; template struct lazy_disable_if_c { typedef typename T::type type; }; template struct lazy_disable_if_c {}; template struct lazy_disable_if : public lazy_disable_if_c {}; } // namespace boost // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: if.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: value_wknd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: integral.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: eti.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // flags for MSVC 6.5's so-called "early template instantiation bug" namespace boost { namespace mpl { namespace aux { template< typename T > struct value_type_wknd { typedef typename T::value_type type; }; }}} // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: na_spec.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: lambda_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: void_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace mpl_ { struct void_; } namespace boost { namespace mpl { using ::mpl_::void_; } } // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: na.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: na_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace mpl_ { // n.a. == not available struct na { typedef na type; enum { value = 0 }; }; } namespace boost { namespace mpl { using ::mpl_::na; } } namespace boost { namespace mpl { template< typename T > struct is_na : false_ { }; template<> struct is_na : true_ { }; template< typename T > struct is_not_na : true_ { }; template<> struct is_not_na : false_ { }; template< typename T, typename U > struct if_na { typedef T type; }; template< typename U > struct if_na { typedef U type; }; }} // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: lambda_arity_param.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace boost { namespace mpl { template< typename T = na , typename Tag = void_ , typename Arity = int_< aux::template_arity ::value > > struct lambda; }} // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: arity.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: dtp.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // MWCW 7.x-8.0 "losts" default template parameters of nested class // templates when their owner classes are passed as arguments to other // templates; Borland 5.5.1 "forgets" them from the very beginning (if // the owner class is a class template), and Borland 5.6 isn't even // able to compile a definition of nested class template with DTP // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: enum.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // BOOST_MPL_PP_ENUM(0,int): // BOOST_MPL_PP_ENUM(1,int): int // BOOST_MPL_PP_ENUM(2,int): int, int // BOOST_MPL_PP_ENUM(n,int): int, int, .., int // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: def_params_tail.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: arity.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // BOOST_MPL_PP_DEF_PARAMS_TAIL(1,T,value): , T1 = value, .., Tn = value // BOOST_MPL_PP_DEF_PARAMS_TAIL(2,T,value): , T2 = value, .., Tn = value // BOOST_MPL_PP_DEF_PARAMS_TAIL(n,T,value): namespace boost { namespace mpl { template< bool C , typename T1 , typename T2 > struct if_c { typedef T1 type; }; template< typename T1 , typename T2 > struct if_c { typedef T2 type; }; // agurt, 05/sep/04: nondescriptive parameter names for the sake of DigitalMars // (and possibly MWCW < 8.0); see http://article.gmane.org/gmane.comp.lib.boost.devel/108959 template< typename T1 = na , typename T2 = na , typename T3 = na > struct if_ { private: // agurt, 02/jan/03: two-step 'type' definition for the sake of aCC typedef if_c< static_cast(T1::value) , T2 , T3 > almost_type_; public: typedef typename almost_type_::type type; }; template< > struct if_< na , na , na > { template< typename T1 , typename T2 , typename T3 , typename T4 =na , typename T5 =na > struct apply : if_< T1 , T2 , T3 > { }; }; template< typename Tag > struct lambda< if_< na , na , na > , Tag , int_< -1> > { typedef false_ is_le; typedef if_< na , na , na > result_; typedef if_< na , na , na > type; }; namespace aux { template< typename T1 , typename T2 , typename T3 > struct template_arity< if_< T1 , T2 , T3 > > : int_<3> { }; template< > struct template_arity< if_< na , na , na > > : int_< -1> { }; } }} struct not_a_type; namespace boost { namespace container { /// @cond // Forward declarations of operators == and <, needed for friend declarations. template inline bool operator==(const map& x, const map& y); template inline bool operator<(const map& x, const map& y); /// @endcond //! A map is a kind of associative container that supports unique keys (contains at //! most one of each key value) and provides for fast retrieval of values of another //! type T based on the keys. The map class supports bidirectional iterators. //! //! A map satisfies all of the requirements of a container and of a reversible //! container and of an associative container. For a //! map the key_type is Key and the value_type is std::pair. //! //! Pred is the ordering function for Keys (e.g. std::less). //! //! A is the allocator to allocate the value_types //! (e.g. allocator< std::pair > ). template class map { /// @cond private: public: map& operator=(map &t) { this->operator=(static_cast & >(const_cast(t))); return *this;} public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: typedef container_detail::rbtree, container_detail::select1st< std::pair >, Pred, A> tree_t; tree_t m_tree; // red-black tree representing map /// @endcond public: // typedefs: typedef typename tree_t::key_type key_type; typedef typename tree_t::value_type value_type; typedef typename tree_t::pointer pointer; typedef typename tree_t::const_pointer const_pointer; typedef typename tree_t::reference reference; typedef typename tree_t::const_reference const_reference; typedef T mapped_type; typedef Pred key_compare; typedef typename tree_t::iterator iterator; typedef typename tree_t::const_iterator const_iterator; typedef typename tree_t::reverse_iterator reverse_iterator; typedef typename tree_t::const_reverse_iterator const_reverse_iterator; typedef typename tree_t::size_type size_type; typedef typename tree_t::difference_type difference_type; typedef typename tree_t::allocator_type allocator_type; typedef typename tree_t::stored_allocator_type stored_allocator_type; typedef std::pair nonconst_value_type; typedef container_detail::pair nonconst_impl_value_type; /// @cond class value_compare_impl : public Pred, public std::binary_function { friend class map; protected : value_compare_impl(const Pred &c) : Pred(c) {} public: bool operator()(const value_type& x, const value_type& y) const { return Pred::operator()(x.first, y.first); } }; /// @endcond typedef value_compare_impl value_compare; //! Effects: Default constructs an empty map. //! //! Complexity: Constant. map() : m_tree() { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_135; } //! Effects: Constructs an empty map using the specified comparison object //! and allocator. //! //! Complexity: Constant. explicit map(const Pred& comp, const allocator_type& a = allocator_type()) : m_tree(comp, a) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_147; } //! Effects: Constructs an empty map using the specified comparison object and //! allocator, and inserts elements from the range [first ,last ). //! //! Complexity: Linear in N if the range [first ,last ) is already sorted using //! comp and otherwise N logN, where N is last - first. template map(InputIterator first, InputIterator last, const Pred& comp = Pred(), const allocator_type& a = allocator_type()) : m_tree(first, last, comp, a, true) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_161; } //! Effects: Constructs an empty map using the specified comparison object and //! allocator, and inserts elements from the ordered unique range [first ,last). This function //! is more efficient than the normal range creation for ordered ranges. //! //! Requires: [first ,last) must be ordered according to the predicate and must be //! unique values. //! //! Complexity: Linear in N. template map( ordered_unique_range_t, InputIterator first, InputIterator last , const Pred& comp = Pred(), const allocator_type& a = allocator_type()) : m_tree(ordered_range, first, last, comp, a) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_178; } //! Effects: Copy constructs a map. //! //! Complexity: Linear in x.size(). map(const map& x) : m_tree(x.m_tree) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_188; } //! Effects: Move constructs a map. Constructs *this using x's resources. //! //! Complexity: Constant. //! //! Postcondition: x is emptied. map(::boost::rv< map > & x) : m_tree(boost::move(x.m_tree)) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_200; } //! Effects: Copy constructs a map using the specified allocator. //! //! Complexity: Linear in x.size(). map(const map& x, const allocator_type &a) : m_tree(x.m_tree, a) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_210; } //! Effects: Move constructs a map using the specified allocator. //! Constructs *this using x's resources. //! //! Complexity: Constant if x == x.get_allocator(), linear otherwise. //! //! Postcondition: x is emptied. map(::boost::rv< map > & x, const allocator_type &a) : m_tree(boost::move(x.m_tree), a) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_223; } //! Effects: Makes *this a copy of x. //! //! Complexity: Linear in x.size(). map& operator=(const ::boost::rv< map > & x) { m_tree = x.m_tree; return *this; } //! Effects: this->swap(x.get()). //! //! Complexity: Constant. map& operator=(::boost::rv< map > & x) { m_tree = boost::move(x.m_tree); return *this; } //! Effects: Returns the comparison object out //! of which a was constructed. //! //! Complexity: Constant. key_compare key_comp() const { return m_tree.key_comp(); } //! Effects: Returns an object of value_compare constructed out //! of the comparison object. //! //! Complexity: Constant. value_compare value_comp() const { return value_compare(m_tree.key_comp()); } //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! //! Complexity: Constant. allocator_type get_allocator() const { return m_tree.get_allocator(); } const stored_allocator_type &get_stored_allocator() const { return m_tree.get_stored_allocator(); } stored_allocator_type &get_stored_allocator() { return m_tree.get_stored_allocator(); } //! Effects: Returns an iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. iterator begin() { return m_tree.begin(); } //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator begin() const { return this->cbegin(); } //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cbegin() const { return m_tree.begin(); } //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. iterator end() { return m_tree.end(); } //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator end() const { return this->cend(); } //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cend() const { return m_tree.end(); } //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. reverse_iterator rbegin() { return m_tree.rbegin(); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator rbegin() const { return this->crbegin(); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crbegin() const { return m_tree.rbegin(); } //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. reverse_iterator rend() { return m_tree.rend(); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator rend() const { return this->crend(); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crend() const { return m_tree.rend(); } //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. //! //! Complexity: Constant. bool empty() const { return m_tree.empty(); } //! Effects: Returns the number of the elements contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. size_type size() const { return m_tree.size(); } //! Effects: Returns the largest possible size of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. size_type max_size() const { return m_tree.max_size(); } mapped_type& operator[](typename ::boost::mpl::if_< ::boost::is_class, const ::boost::rv< key_type > &, const key_type & > ::type x) { return priv_subscript(static_cast(x)); } mapped_type& operator[](typename ::boost::mpl::if_< ::boost::is_class, ::boost::rv< key_type > &, not_a_type> ::type x) { return priv_subscript(::boost::move(x)); } mapped_type& operator[](key_type &x) { return priv_subscript(const_cast(x)); } template typename ::boost::enable_if_c < ::boost::is_class ::value && ::boost::is_same ::value && ! ::boost::has_move_emulation_enabled ::value , mapped_type& > ::type operator[](const BOOST_MOVE_TEMPL_PARAM &u) { return priv_subscript(u); } template typename ::boost::enable_if_c < (! ::boost::is_class ::value || ! ::boost::move_detail::is_rv ::value) && ! ::boost::is_same ::value , mapped_type& > ::type operator[](const BOOST_MOVE_TEMPL_PARAM &u) { key_type t(u); return priv_subscript(::boost::move(t)); } //! Returns: A reference to the element whose key is equivalent to x. //! Throws: An exception object of type out_of_range if no such element is present. //! Complexity: logarithmic. T& at(const key_type& k) { iterator i = this->find(k); if(i == this->end()){ throw std::out_of_range("key not found"); } return i->second; } //! Returns: A reference to the element whose key is equivalent to x. //! Throws: An exception object of type out_of_range if no such element is present. //! Complexity: logarithmic. const T& at(const key_type& k) const { const_iterator i = this->find(k); if(i == this->end()){ throw std::out_of_range("key not found"); } return i->second; } //! Effects: Swaps the contents of *this and x. //! //! Throws: Nothing. //! //! Complexity: Constant. void swap(map& x) { m_tree.swap(x.m_tree); } //! Effects: Inserts x if and only if there is no element in the container //! with key equivalent to the key of x. //! //! Returns: The bool component of the returned pair is true if and only //! if the insertion takes place, and the iterator component of the pair //! points to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. std::pair insert(const value_type& x) { return m_tree.insert_unique(x); } //! Effects: Inserts a new value_type created from the pair if and only if //! there is no element in the container with key equivalent to the key of x. //! //! Returns: The bool component of the returned pair is true if and only //! if the insertion takes place, and the iterator component of the pair //! points to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. std::pair insert(const nonconst_value_type& x) { return m_tree.insert_unique(x); } //! Effects: Inserts a new value_type move constructed from the pair if and //! only if there is no element in the container with key equivalent to the key of x. //! //! Returns: The bool component of the returned pair is true if and only //! if the insertion takes place, and the iterator component of the pair //! points to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. std::pair insert(::boost::rv< nonconst_value_type > & x) { return m_tree.insert_unique(boost::move(x)); } //! Effects: Inserts a new value_type move constructed from the pair if and //! only if there is no element in the container with key equivalent to the key of x. //! //! Returns: The bool component of the returned pair is true if and only //! if the insertion takes place, and the iterator component of the pair //! points to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. std::pair insert(::boost::rv< nonconst_impl_value_type > & x) { return m_tree.insert_unique(boost::move(x)); } //! Effects: Move constructs a new value from x if and only if there is //! no element in the container with key equivalent to the key of x. //! //! Returns: The bool component of the returned pair is true if and only //! if the insertion takes place, and the iterator component of the pair //! points to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. std::pair insert(::boost::rv< value_type > & x) { return m_tree.insert_unique(boost::move(x)); } //! Effects: Inserts a copy of x in the container if and only if there is //! no element in the container with key equivalent to the key of x. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent //! to the key of x. //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(iterator position, const value_type& x) { return m_tree.insert_unique(position, x); } //! Effects: Move constructs a new value from x if and only if there is //! no element in the container with key equivalent to the key of x. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent //! to the key of x. //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(iterator position, ::boost::rv< nonconst_value_type > & x) { return m_tree.insert_unique(position, boost::move(x)); } //! Effects: Move constructs a new value from x if and only if there is //! no element in the container with key equivalent to the key of x. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent //! to the key of x. //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(iterator position, ::boost::rv< nonconst_impl_value_type > & x) { return m_tree.insert_unique(position, boost::move(x)); } //! Effects: Inserts a copy of x in the container. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. iterator insert(iterator position, const nonconst_value_type& x) { return m_tree.insert_unique(position, x); } //! Effects: Inserts an element move constructed from x in the container. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. iterator insert(iterator position, ::boost::rv< value_type > & x) { return m_tree.insert_unique(position, boost::move(x)); } //! Requires: first, last are not iterators into *this. //! //! Effects: inserts each element from the range [first,last) if and only //! if there is no element with key equivalent to the key of that element. //! //! Complexity: At most N log(size()+N) (N is the distance from first to last) template void insert(InputIterator first, InputIterator last) { m_tree.insert_unique(first, last); } std::pair emplace() { return m_tree . emplace_unique(); } iterator emplace_hint(const_iterator hint ) { return m_tree . emplace_hint_unique(hint );} template< class P0 > std::pair emplace( const P0 & p0) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 )); } template< class P0 > iterator emplace_hint(const_iterator hint , const P0 & p0) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ));} template< class P0 , class P1 > std::pair emplace( const P0 & p0 , const P1 & p1) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )); } template< class P0 , class P1 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ));} template< class P0 , class P1 , class P2 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )); } template< class P0 , class P1 , class P2 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ));} template< class P0 , class P1 , class P2 , class P3 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )); } template< class P0 , class P1 , class P2 , class P3 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > std::pair emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { return m_tree . emplace_unique( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { return m_tree . emplace_hint_unique(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ));} //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately //! following q prior to the element being erased. If no such element exists, //! returns end(). //! //! Complexity: Amortized constant time iterator erase(const_iterator position) { return m_tree.erase(position); } //! Effects: Erases all elements in the container with key equivalent to x. //! //! Returns: Returns the number of erased elements. //! //! Complexity: log(size()) + count(k) size_type erase(const key_type& x) { return m_tree.erase(x); } //! Effects: Erases all the elements in the range [first, last). //! //! Returns: Returns last. //! //! Complexity: log(size())+N where N is the distance from first to last. iterator erase(const_iterator first, const_iterator last) { return m_tree.erase(first, last); } //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. //! //! Complexity: linear in size(). void clear() { m_tree.clear(); } //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. iterator find(const key_type& x) { return m_tree.find(x); } //! Returns: A const_iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. const_iterator find(const key_type& x) const { return m_tree.find(x); } //! Returns: The number of elements with key equivalent to x. //! //! Complexity: log(size())+count(k) size_type count(const key_type& x) const { return m_tree.find(x) == m_tree.end() ? 0 : 1; } //! Returns: An iterator pointing to the first element with key not less //! than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic iterator lower_bound(const key_type& x) { return m_tree.lower_bound(x); } //! Returns: A const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic const_iterator lower_bound(const key_type& x) const { return m_tree.lower_bound(x); } //! Returns: An iterator pointing to the first element with key not less //! than x, or end() if such an element is not found. //! //! Complexity: Logarithmic iterator upper_bound(const key_type& x) { return m_tree.upper_bound(x); } //! Returns: A const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic const_iterator upper_bound(const key_type& x) const { return m_tree.upper_bound(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic std::pair equal_range(const key_type& x) { return m_tree.equal_range(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } /// @cond template friend bool operator== (const map&, const map&); template friend bool operator< (const map&, const map&); private: mapped_type& priv_subscript(const key_type &k) { //we can optimize this iterator i = lower_bound(k); // i->first is greater than or equivalent to k. if (i == end() || key_comp()(k, (*i).first)){ container_detail::value_init m; nonconst_impl_value_type val(k, boost::move(m.m_t)); i = insert(i, boost::move(val)); } return (*i).second; } mapped_type& priv_subscript(::boost::rv< key_type > & mk) { key_type &k = mk; //we can optimize this iterator i = lower_bound(k); // i->first is greater than or equivalent to k. if (i == end() || key_comp()(k, (*i).first)){ container_detail::value_init m; nonconst_impl_value_type val(boost::move(k), boost::move(m.m_t)); i = insert(i, boost::move(val)); } return (*i).second; } /// @endcond }; template inline bool operator==(const map& x, const map& y) { return x.m_tree == y.m_tree; } template inline bool operator<(const map& x, const map& y) { return x.m_tree < y.m_tree; } template inline bool operator!=(const map& x, const map& y) { return !(x == y); } template inline bool operator>(const map& x, const map& y) { return y < x; } template inline bool operator<=(const map& x, const map& y) { return !(y < x); } template inline bool operator>=(const map& x, const map& y) { return !(x < y); } template inline void swap(map& x, map& y) { x.swap(y); } /// @cond // Forward declaration of operators < and ==, needed for friend declaration. template inline bool operator==(const multimap& x, const multimap& y); template inline bool operator<(const multimap& x, const multimap& y); } //namespace container { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations template struct has_trivial_destructor_after_move > { static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { /// @endcond //! A multimap is a kind of associative container that supports equivalent keys //! (possibly containing multiple copies of the same key value) and provides for //! fast retrieval of values of another type T based on the keys. The multimap class //! supports bidirectional iterators. //! //! A multimap satisfies all of the requirements of a container and of a reversible //! container and of an associative container. For a //! map the key_type is Key and the value_type is std::pair. //! //! Pred is the ordering function for Keys (e.g. std::less). //! //! A is the allocator to allocate the value_types //!(e.g. allocator< std::pair<const Key, T> >). template class multimap { /// @cond private: public: multimap& operator=(multimap &t) { this->operator=(static_cast & >(const_cast(t))); return *this;} public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: typedef container_detail::rbtree, container_detail::select1st< std::pair >, Pred, A> tree_t; tree_t m_tree; // red-black tree representing map typedef typename container_detail:: move_const_ref_type::type insert_key_const_ref_type; /// @endcond public: // typedefs: typedef typename tree_t::key_type key_type; typedef typename tree_t::value_type value_type; typedef typename tree_t::pointer pointer; typedef typename tree_t::const_pointer const_pointer; typedef typename tree_t::reference reference; typedef typename tree_t::const_reference const_reference; typedef T mapped_type; typedef Pred key_compare; typedef typename tree_t::iterator iterator; typedef typename tree_t::const_iterator const_iterator; typedef typename tree_t::reverse_iterator reverse_iterator; typedef typename tree_t::const_reverse_iterator const_reverse_iterator; typedef typename tree_t::size_type size_type; typedef typename tree_t::difference_type difference_type; typedef typename tree_t::allocator_type allocator_type; typedef typename tree_t::stored_allocator_type stored_allocator_type; typedef std::pair nonconst_value_type; typedef container_detail::pair nonconst_impl_value_type; /// @cond class value_compare_impl : public Pred, public std::binary_function { friend class multimap; protected : value_compare_impl(const Pred &c) : Pred(c) {} public: bool operator()(const value_type& x, const value_type& y) const { return Pred::operator()(x.first, y.first); } }; /// @endcond typedef value_compare_impl value_compare; //! Effects: Default constructs an empty multimap. //! //! Complexity: Constant. multimap() : m_tree() { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_882; } //! Effects: Constructs an empty multimap using the specified comparison //! object and allocator. //! //! Complexity: Constant. explicit multimap(const Pred& comp, const allocator_type& a = allocator_type()) : m_tree(comp, a) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_893; } //! Effects: Constructs an empty multimap using the specified comparison object //! and allocator, and inserts elements from the range [first ,last ). //! //! Complexity: Linear in N if the range [first ,last ) is already sorted using //! comp and otherwise N logN, where N is last - first. template multimap(InputIterator first, InputIterator last, const Pred& comp = Pred(), const allocator_type& a = allocator_type()) : m_tree(first, last, comp, a, false) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_908; } //! Effects: Constructs an empty multimap using the specified comparison object and //! allocator, and inserts elements from the ordered range [first ,last). This function //! is more efficient than the normal range creation for ordered ranges. //! //! Requires: [first ,last) must be ordered according to the predicate. //! //! Complexity: Linear in N. template multimap(ordered_range_t ordered_range, InputIterator first, InputIterator last, const Pred& comp = Pred(), const allocator_type& a = allocator_type()) : m_tree(ordered_range, first, last, comp, a) {} //! Effects: Copy constructs a multimap. //! //! Complexity: Linear in x.size(). multimap(const multimap& x) : m_tree(x.m_tree) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_931; } //! Effects: Move constructs a multimap. Constructs *this using x's resources. //! //! Complexity: Constant. //! //! Postcondition: x is emptied. multimap(::boost::rv< multimap > & x) : m_tree(boost::move(x.m_tree)) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_943; } //! Effects: Copy constructs a multimap. //! //! Complexity: Linear in x.size(). multimap(const multimap& x, const allocator_type &a) : m_tree(x.m_tree, a) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_953; } //! Effects: Move constructs a multimap using the specified allocator. //! Constructs *this using x's resources. //! Complexity: Constant if a == x.get_allocator(), linear otherwise. //! //! Postcondition: x is emptied. multimap(::boost::rv< multimap > & x, const allocator_type &a) : m_tree(boost::move(x.m_tree), a) { //Allocator type must be std::pair typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)((container_detail::is_same, typename A::value_type> ::value)) >)> boost_static_assert_typedef_965; } //! Effects: Makes *this a copy of x. //! //! Complexity: Linear in x.size(). multimap& operator=(const ::boost::rv< multimap > & x) { m_tree = x.m_tree; return *this; } //! Effects: this->swap(x.get()). //! //! Complexity: Constant. multimap& operator=(::boost::rv< multimap > & x) { m_tree = boost::move(x.m_tree); return *this; } //! Effects: Returns the comparison object out //! of which a was constructed. //! //! Complexity: Constant. key_compare key_comp() const { return m_tree.key_comp(); } //! Effects: Returns an object of value_compare constructed out //! of the comparison object. //! //! Complexity: Constant. value_compare value_comp() const { return value_compare(m_tree.key_comp()); } //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! //! Complexity: Constant. allocator_type get_allocator() const { return m_tree.get_allocator(); } const stored_allocator_type &get_stored_allocator() const { return m_tree.get_stored_allocator(); } stored_allocator_type &get_stored_allocator() { return m_tree.get_stored_allocator(); } //! Effects: Returns an iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. iterator begin() { return m_tree.begin(); } //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator begin() const { return this->cbegin(); } //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cbegin() const { return m_tree.begin(); } //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. iterator end() { return m_tree.end(); } //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator end() const { return this->cend(); } //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cend() const { return m_tree.end(); } //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. reverse_iterator rbegin() { return m_tree.rbegin(); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator rbegin() const { return this->crbegin(); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crbegin() const { return m_tree.rbegin(); } //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. reverse_iterator rend() { return m_tree.rend(); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator rend() const { return this->crend(); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crend() const { return m_tree.rend(); } //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. //! //! Complexity: Constant. bool empty() const { return m_tree.empty(); } //! Effects: Returns the number of the elements contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. size_type size() const { return m_tree.size(); } //! Effects: Returns the largest possible size of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. size_type max_size() const { return m_tree.max_size(); } //! Effects: Swaps the contents of *this and x. //! //! Throws: Nothing. //! //! Complexity: Constant. void swap(multimap& x) { m_tree.swap(x.m_tree); } //! Effects: Inserts x and returns the iterator pointing to the //! newly inserted element. //! //! Complexity: Logarithmic. iterator insert(const value_type& x) { return m_tree.insert_equal(x); } //! Effects: Inserts a new value constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! Complexity: Logarithmic. iterator insert(const nonconst_value_type& x) { return m_tree.insert_equal(x); } //! Effects: Inserts a new value move-constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! Complexity: Logarithmic. iterator insert(::boost::rv< nonconst_value_type > & x) { return m_tree.insert_equal(boost::move(x)); } //! Effects: Inserts a new value move-constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! Complexity: Logarithmic. iterator insert(::boost::rv< nonconst_impl_value_type > & x) { return m_tree.insert_equal(boost::move(x)); } //! Effects: Inserts a copy of x in the container. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent //! to the key of x. //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(iterator position, const value_type& x) { return m_tree.insert_equal(position, x); } //! Effects: Inserts a new value constructed from x in the container. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent //! to the key of x. //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(iterator position, const nonconst_value_type& x) { return m_tree.insert_equal(position, x); } //! Effects: Inserts a new value move constructed from x in the container. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent //! to the key of x. //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(iterator position, ::boost::rv< nonconst_value_type > & x) { return m_tree.insert_equal(position, boost::move(x)); } //! Effects: Inserts a new value move constructed from x in the container. //! p is a hint pointing to where the insert should start to search. //! //! Returns: An iterator pointing to the element with key equivalent //! to the key of x. //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(iterator position, ::boost::rv< nonconst_impl_value_type > & x) { return m_tree.insert_equal(position, boost::move(x)); } //! Requires: first, last are not iterators into *this. //! //! Effects: inserts each element from the range [first,last) . //! //! Complexity: At most N log(size()+N) (N is the distance from first to last) template void insert(InputIterator first, InputIterator last) { m_tree.insert_equal(first, last); } iterator emplace() { return m_tree . emplace_equal(); } iterator emplace_hint(const_iterator hint ) { return m_tree . emplace_hint_equal(hint );} template< class P0 > iterator emplace( const P0 & p0) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 )); } template< class P0 > iterator emplace_hint(const_iterator hint , const P0 & p0) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ));} template< class P0 , class P1 > iterator emplace( const P0 & p0 , const P1 & p1) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )); } template< class P0 , class P1 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ));} template< class P0 , class P1 , class P2 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )); } template< class P0 , class P1 , class P2 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ));} template< class P0 , class P1 , class P2 , class P3 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )); } template< class P0 , class P1 , class P2 , class P3 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ));} template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > iterator emplace( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { return m_tree . emplace_equal( ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > iterator emplace_hint(const_iterator hint , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { return m_tree . emplace_hint_equal(hint , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ));} //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately //! following q prior to the element being erased. If no such element exists, //! returns end(). //! //! Complexity: Amortized constant time iterator erase(const_iterator position) { return m_tree.erase(position); } //! Effects: Erases all elements in the container with key equivalent to x. //! //! Returns: Returns the number of erased elements. //! //! Complexity: log(size()) + count(k) size_type erase(const key_type& x) { return m_tree.erase(x); } //! Effects: Erases all the elements in the range [first, last). //! //! Returns: Returns last. //! //! Complexity: log(size())+N where N is the distance from first to last. iterator erase(const_iterator first, const_iterator last) { return m_tree.erase(first, last); } //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. //! //! Complexity: linear in size(). void clear() { m_tree.clear(); } //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. iterator find(const key_type& x) { return m_tree.find(x); } //! Returns: A const iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. const_iterator find(const key_type& x) const { return m_tree.find(x); } //! Returns: The number of elements with key equivalent to x. //! //! Complexity: log(size())+count(k) size_type count(const key_type& x) const { return m_tree.count(x); } //! Returns: An iterator pointing to the first element with key not less //! than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic iterator lower_bound(const key_type& x) {return m_tree.lower_bound(x); } //! Returns: A const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic const_iterator lower_bound(const key_type& x) const { return m_tree.lower_bound(x); } //! Returns: An iterator pointing to the first element with key not less //! than x, or end() if such an element is not found. //! //! Complexity: Logarithmic iterator upper_bound(const key_type& x) { return m_tree.upper_bound(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic std::pair equal_range(const key_type& x) { return m_tree.equal_range(x); } //! Returns: A const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic const_iterator upper_bound(const key_type& x) const { return m_tree.upper_bound(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } /// @cond template friend bool operator== (const multimap& x, const multimap& y); template friend bool operator< (const multimap& x, const multimap& y); /// @endcond }; template inline bool operator==(const multimap& x, const multimap& y) { return x.m_tree == y.m_tree; } template inline bool operator<(const multimap& x, const multimap& y) { return x.m_tree < y.m_tree; } template inline bool operator!=(const multimap& x, const multimap& y) { return !(x == y); } template inline bool operator>(const multimap& x, const multimap& y) { return y < x; } template inline bool operator<=(const multimap& x, const multimap& y) { return !(y < x); } template inline bool operator>=(const multimap& x, const multimap& y) { return !(x < y); } template inline void swap(multimap& x, multimap& y) { x.swap(y); } /// @cond } //namespace container { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations template struct has_trivial_destructor_after_move > { static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { /// @endcond }} ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail{ template struct has_nothrow_copy_imp{ static const bool value = ::boost::has_trivial_copy ::value; }; } template< typename T > struct has_nothrow_copy : public ::boost::integral_constant ::value> { public: }; template< typename T > struct has_nothrow_copy_constructor : public ::boost::integral_constant ::value> { public: }; template< > struct has_nothrow_copy< void > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_copy< void const > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_copy< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_copy< void volatile > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_copy_constructor< void > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_copy_constructor< void const > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_copy_constructor< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_copy_constructor< void volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail{ template struct has_nothrow_assign_imp{ static const bool value = ::boost::has_trivial_assign ::value; }; } template< typename T > struct has_nothrow_assign : public ::boost::integral_constant ::value> { public: }; template< > struct has_nothrow_assign< void > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_assign< void const > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_assign< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_assign< void volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { template struct has_trivial_ctor_impl { static const bool value = (::boost::type_traits::ice_or< ::boost::is_pod ::value, false > ::value); }; } // namespace detail template< typename T > struct has_trivial_constructor : public ::boost::integral_constant ::value> { public: }; template< typename T > struct has_trivial_default_constructor : public ::boost::integral_constant ::value> { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail{ template struct has_nothrow_constructor_imp{ static const bool value = ::boost::has_trivial_constructor ::value; }; } template< typename T > struct has_nothrow_constructor : public ::boost::integral_constant ::value> { public: }; template< typename T > struct has_nothrow_default_constructor : public ::boost::integral_constant ::value> { public: }; template< > struct has_nothrow_constructor< void > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_constructor< void const > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_constructor< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_constructor< void volatile > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_default_constructor< void > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_default_constructor< void const > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_default_constructor< void const volatile > : public ::boost::integral_constant { public: }; template< > struct has_nothrow_default_constructor< void volatile > : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ /////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // /////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace boost { namespace container { /// @cond enum allocation_type_v { // constants for allocation commands allocate_new_v = 0x01, expand_fwd_v = 0x02, expand_bwd_v = 0x04, // expand_both = expand_fwd | expand_bwd, // expand_or_new = allocate_new | expand_both, shrink_in_place_v = 0x08, nothrow_allocation_v = 0x10, zero_memory_v = 0x20, try_shrink_in_place_v = 0x40 }; typedef int allocation_type; /// @endcond static const allocation_type allocate_new = (allocation_type)allocate_new_v; static const allocation_type expand_fwd = (allocation_type)expand_fwd_v; static const allocation_type expand_bwd = (allocation_type)expand_bwd_v; static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v; static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v; static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v; static const allocation_type zero_memory = (allocation_type)zero_memory_v; } //namespace container { } //namespace boost { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- // boost aligned_storage.hpp header file // See http://www.boost.org for updates, documentation, and revision history. //----------------------------------------------------------------------------- // // Copyright (c) 2002-2003 // Eric Friedman, Itay Maman // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-04-25 08:26:48 -0400 (Mon, 25 Apr 2011) $ // $Revision: 71481 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: size_t.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: size_t_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace mpl_ { template< std::size_t N > struct size_t; } namespace boost { namespace mpl { using ::mpl_::size_t; } } // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: integral_wrapper.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! namespace mpl_ { template< std::size_t N > struct size_t { static const std::size_t value = N; // agurt, 08/mar/03: SGI MIPSpro C++ workaround, have to #ifdef because some // other compilers (e.g. MSVC) are not particulary happy about it typedef size_t type; typedef std::size_t value_type; typedef integral_c_tag tag; // have to #ifdef here: some compilers don't like the 'N + 1' form (MSVC), // while some other don't like 'value + 1' (Borland), and some don't like // either typedef mpl_::size_t< static_cast((value + 1)) > next; typedef mpl_::size_t< static_cast((value - 1)) > prior; // enables uniform function call syntax for families of overloaded // functions that return objects of both arithmetic ('int', 'long', // 'double', etc.) and wrapped integral types (for an example, see // "mpl/example/power.cpp") operator std::size_t() const { return static_cast(this->value); } }; template< std::size_t N > std::size_t const mpl_::size_t< N > ::value; } namespace boost { template struct alignment_of; // get the alignment of some arbitrary type: namespace detail { template struct alignment_of_hack { char c; T t; alignment_of_hack(); }; template struct alignment_logic { static const std::size_t value = A < S ? A : S; }; template< typename T > struct alignment_of_impl { static const std::size_t value = (::boost::detail::alignment_logic< sizeof(::boost::detail::alignment_of_hack) - sizeof(T), sizeof(T) > ::value); }; } // namespace detail template< typename T > struct alignment_of : public ::boost::integral_constant ::value> { public: }; // references have to be treated specially, assume // that a reference is just a special pointer: template struct alignment_of : public alignment_of { }; // void has to be treated specially: template< > struct alignment_of : public ::boost::integral_constant { public: }; template< > struct alignment_of : public ::boost::integral_constant { public: }; template< > struct alignment_of : public ::boost::integral_constant { public: }; template< > struct alignment_of : public ::boost::integral_constant { public: }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $ // $Revision: 24874 $ // (C) Copyright John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // should be the last #include // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { class alignment_dummy; typedef void (*function_ptr)(); typedef int (alignment_dummy::*member_ptr); typedef int (alignment_dummy::*member_function_ptr)(); // // lower_alignment_helper -- // // This template gets instantiated a lot, so use partial // specialization when available to reduce the compiler burden. // template struct lower_alignment_helper { typedef char type; enum { value = true }; }; template struct lower_alignment_helper { enum { value = (alignment_of::value == target) }; typedef typename mpl::if_c::type type; }; template struct has_one_T { T data; }; template union lower_alignment { enum { found0 = false }; typename lower_alignment_helper< found0,target,char > ::type t0; enum { found1 = lower_alignment_helper ::value }; typename lower_alignment_helper< found1,target,short > ::type t1; enum { found2 = lower_alignment_helper ::value }; typename lower_alignment_helper< found2,target,int > ::type t2; enum { found3 = lower_alignment_helper ::value }; typename lower_alignment_helper< found3,target,long > ::type t3; enum { found4 = lower_alignment_helper ::value }; typename lower_alignment_helper< found4,target,::boost::long_long_type > ::type t4; enum { found5 = lower_alignment_helper ::value }; typename lower_alignment_helper< found5,target,float > ::type t5; enum { found6 = lower_alignment_helper ::value }; typename lower_alignment_helper< found6,target,double > ::type t6; enum { found7 = lower_alignment_helper ::value }; typename lower_alignment_helper< found7,target,long double > ::type t7; enum { found8 = lower_alignment_helper ::value }; typename lower_alignment_helper< found8,target,void* > ::type t8; enum { found9 = lower_alignment_helper ::value }; typename lower_alignment_helper< found9,target,function_ptr > ::type t9; enum { found10 = lower_alignment_helper ::value }; typename lower_alignment_helper< found10,target,member_ptr > ::type t10; enum { found11 = lower_alignment_helper ::value }; typename lower_alignment_helper< found11,target,member_function_ptr > ::type t11; enum { found12 = lower_alignment_helper ::value }; typename lower_alignment_helper< found12,target,boost::detail::has_one_T< char > > ::type t12; enum { found13 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found13,target,boost::detail::has_one_T< short > > ::type t13; enum { found14 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found14,target,boost::detail::has_one_T< int > > ::type t14; enum { found15 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found15,target,boost::detail::has_one_T< long > > ::type t15; enum { found16 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found16,target,boost::detail::has_one_T< ::boost::long_long_type > > ::type t16; enum { found17 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found17,target,boost::detail::has_one_T< float > > ::type t17; enum { found18 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found18,target,boost::detail::has_one_T< double > > ::type t18; enum { found19 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found19,target,boost::detail::has_one_T< long double > > ::type t19; enum { found20 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found20,target,boost::detail::has_one_T< void* > > ::type t20; enum { found21 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found21,target,boost::detail::has_one_T< function_ptr > > ::type t21; enum { found22 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found22,target,boost::detail::has_one_T< member_ptr > > ::type t22; enum { found23 = lower_alignment_helper > ::value }; typename lower_alignment_helper< found23,target,boost::detail::has_one_T< member_function_ptr > > ::type t23; enum { found24 = lower_alignment_helper > ::value }; }; union max_align { char t0; short t1; int t2; long t3; ::boost::long_long_type t4; float t5; double t6; long double t7; void* t8; function_ptr t9; member_ptr t10; member_function_ptr t11; boost::detail::has_one_T< char > t12; boost::detail::has_one_T< short > t13; boost::detail::has_one_T< int > t14; boost::detail::has_one_T< long > t15; boost::detail::has_one_T< ::boost::long_long_type > t16; boost::detail::has_one_T< float > t17; boost::detail::has_one_T< double > t18; boost::detail::has_one_T< long double > t19; boost::detail::has_one_T< void* > t20; boost::detail::has_one_T< function_ptr > t21; boost::detail::has_one_T< member_ptr > t22; boost::detail::has_one_T< member_function_ptr > t23; }; template struct is_aligned { static const bool value = (TAlign >= Align) & (TAlign % Align == 0); }; } // namespace detail template struct is_pod< ::boost::detail::lower_alignment > { static const std::size_t value = true; }; // This alignment method originally due to Brian Parker, implemented by David // Abrahams, and then ported here by Doug Gregor. namespace detail{ template class type_with_alignment_imp { typedef ::boost::detail::lower_alignment t1; typedef typename mpl::if_c< ::boost::detail::is_aligned< ::boost::alignment_of::value,Align >::value , t1 , ::boost::detail::max_align >::type align_t; static const std::size_t found = alignment_of ::value; typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)(found >= Align) >)> boost_static_assert_typedef_206; typedef ::boost::static_assert_test< sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)(found % Align == 0) >)> boost_static_assert_typedef_207; public: typedef align_t type; }; } template class type_with_alignment : public ::boost::detail::type_with_alignment_imp { }; namespace align { struct __attribute__((__aligned__(2))) a2 {}; struct __attribute__((__aligned__(4))) a4 {}; struct __attribute__((__aligned__(8))) a8 {}; struct __attribute__((__aligned__(16))) a16 {}; struct __attribute__((__aligned__(32))) a32 {}; struct __attribute__((__aligned__(64))) a64 {}; struct __attribute__((__aligned__(128))) a128 {}; } template<> class type_with_alignment<1> { public: typedef char type; }; template<> class type_with_alignment<2> { public: typedef align::a2 type; }; template<> class type_with_alignment<4> { public: typedef align::a4 type; }; template<> class type_with_alignment<8> { public: typedef align::a8 type; }; template<> class type_with_alignment<16> { public: typedef align::a16 type; }; template<> class type_with_alignment<32> { public: typedef align::a32 type; }; template<> class type_with_alignment<64> { public: typedef align::a64 type; }; template<> class type_with_alignment<128> { public: typedef align::a128 type; }; namespace detail { template< > struct is_pod_impl< ::boost::align::a2 > { public: static const bool value = (true); }; template< > struct is_pod_impl< ::boost::align::a4 > { public: static const bool value = (true); }; template< > struct is_pod_impl< ::boost::align::a8 > { public: static const bool value = (true); }; template< > struct is_pod_impl< ::boost::align::a16 > { public: static const bool value = (true); }; template< > struct is_pod_impl< ::boost::align::a32 > { public: static const bool value = (true); }; template< > struct is_pod_impl< ::boost::align::a64 > { public: static const bool value = (true); }; template< > struct is_pod_impl< ::boost::align::a128 > { public: static const bool value = (true); }; } } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: eval_if.hpp 61921 2010-05-11 21:33:24Z neilgroves $ // $Date: 2010-05-11 17:33:24 -0400 (Tue, 11 May 2010) $ // $Revision: 61921 $ namespace boost { namespace mpl { template< typename C = na , typename F1 = na , typename F2 = na > struct eval_if { typedef typename if_::type f_; typedef typename f_::type type; }; // (almost) copy & paste in order to save one more // recursively nested template instantiation to user template< bool C , typename F1 , typename F2 > struct eval_if_c { typedef typename if_c::type f_; typedef typename f_::type type; }; template< > struct eval_if< na , na , na > { template< typename T1 , typename T2 , typename T3 , typename T4 =na , typename T5 =na > struct apply : eval_if< T1 , T2 , T3 > { }; }; template< typename Tag > struct lambda< eval_if< na , na , na > , Tag , int_< -1> > { typedef false_ is_le; typedef eval_if< na , na , na > result_; typedef eval_if< na , na , na > type; }; namespace aux { template< typename T1 , typename T2 , typename T3 > struct template_arity< eval_if< T1 , T2 , T3 > > : int_<3> { }; template< > struct template_arity< eval_if< na , na , na > > : int_< -1> { }; } }} // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id: identity.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ // $Revision: 49267 $ namespace boost { namespace mpl { template< typename T = na > struct identity { typedef T type; }; template< typename T = na > struct make_identity { typedef identity type; }; template< > struct identity< na > { template< typename T1 , typename T2 =na , typename T3 =na , typename T4 =na , typename T5 =na > struct apply : identity< T1 > { }; }; template< typename Tag > struct lambda< identity< na > , Tag , int_< -1> > { typedef false_ is_le; typedef identity< na > result_; typedef identity< na > type; }; namespace aux { template< typename T1 > struct template_arity< identity< T1 > > : int_<1> { }; template< > struct template_arity< identity< na > > : int_< -1> { }; } template< > struct make_identity< na > { template< typename T1 , typename T2 =na , typename T3 =na , typename T4 =na , typename T5 =na > struct apply : make_identity< T1 > { }; }; template< typename Tag > struct lambda< make_identity< na > , Tag , int_< -1> > { typedef false_ is_le; typedef make_identity< na > result_; typedef make_identity< na > type; }; namespace aux { template< typename T1 > struct template_arity< make_identity< T1 > > : int_<1> { }; template< > struct template_arity< make_identity< na > > : int_< -1> { }; } }} // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Unfortunately some libraries have started using this header without // cleaning up afterwards: so we'd better undef the macros just in case // they've been defined already.... // namespace boost { namespace detail { namespace aligned_storage { static const std::size_t alignment_of_max_align = ::boost::alignment_of ::value; // // To be TR1 conforming this must be a POD type: // template < std::size_t size_ , std::size_t alignment_ > struct aligned_storage_imp { union data_t { char buf[size_]; typename mpl::eval_if_c< alignment_ == std::size_t(-1) , mpl::identity , type_with_alignment >::type align_; } data_; void* address() const { return const_cast(this); } }; template< std::size_t alignment_ > struct aligned_storage_imp<0u,alignment_> { /* intentionally empty */ void* address() const { return 0; } }; }} // namespace detail::aligned_storage template < std::size_t size_ , std::size_t alignment_ = std::size_t(-1) > class aligned_storage : private detail::aligned_storage::aligned_storage_imp { public: // constants typedef detail::aligned_storage::aligned_storage_imp type; static const std::size_t size = size_; static const std::size_t alignment = ( alignment_ == std::size_t(-1) ? ::boost::detail::aligned_storage::alignment_of_max_align : alignment_ ); public: // _should_ be noncopyable, but GCC compiler emits error aligned_storage(const aligned_storage&); aligned_storage& operator=(const aligned_storage&); public: // structors aligned_storage() { } ~aligned_storage() { } public: // accessors void* address() { return static_cast(this)->address(); } const void* address() const { return static_cast(this)->address(); } }; // // Make sure that is_pod recognises aligned_storage<>::type // as a POD (Note that aligned_storage<> itself is not a POD): // template struct is_pod > : public ::boost::integral_constant { }; } // namespace boost // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Source$ // $Date: 2011-10-09 18:28:33 -0400 (Sun, 09 Oct 2011) $ // $Revision: 74865 $ // // boost/assert.hpp - BOOST_ASSERT(expr) // BOOST_ASSERT_MSG(expr, msg) // BOOST_VERIFY(expr) // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2007 Peter Dimov // Copyright (c) Beman Dawes 2011 // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Note: There are no include guards. This is intentional. // // See http://www.boost.org/libs/utility/assert.html for documentation. // // // Stop inspect complaining about use of 'assert': // // boostinspect:naassert_macro // //--------------------------------------------------------------------------------------// // BOOST_ASSERT // //--------------------------------------------------------------------------------------// /*****************************************************************************/ /* assert.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ using std::_nassert; //--------------------------------------------------------------------------------------// // BOOST_ASSERT_MSG // //--------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------// // BOOST_VERIFY // //--------------------------------------------------------------------------------------// namespace boost { namespace container { namespace container_detail { //This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl template struct advanced_insert_aux_int { typedef typename std::iterator_traits::difference_type difference_type; virtual void copy_remaining_to(Iterator p) = 0; virtual void uninitialized_copy_remaining_to(Iterator p) = 0; virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0; virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0; virtual ~advanced_insert_aux_int() {} }; //This class template will adapt each FwIt types to advanced_insert_aux_int template struct advanced_insert_aux_proxy : public advanced_insert_aux_int { typedef typename allocator_traits::size_type size_type; typedef typename allocator_traits::value_type value_type; typedef typename advanced_insert_aux_int::difference_type difference_type; advanced_insert_aux_proxy(A& a, FwdIt first, FwdIt last) : a_(a), first_(first), last_(last) {} virtual ~advanced_insert_aux_proxy() {} virtual void copy_remaining_to(Iterator p) { ::boost::copy_or_move(this->first_, this->last_, p); } virtual void uninitialized_copy_remaining_to(Iterator p) { ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); } virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n) { FwdIt mid = this->first_; std::advance(mid, division_count); if(first_n){ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos); this->first_ = mid; } else{ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos); this->last_ = mid; } } virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n) { FwdIt mid = this->first_; std::advance(mid, division_count); if(first_n){ ::boost::copy_or_move(this->first_, mid, pos); this->first_ = mid; } else{ ::boost::copy_or_move(mid, this->last_, pos); this->last_ = mid; } } A &a_; FwdIt first_, last_; }; //This class template will adapt default construction insertions to advanced_insert_aux_int template struct default_construct_aux_proxy : public advanced_insert_aux_int { typedef ::boost::container::allocator_traits alloc_traits; typedef typename allocator_traits::size_type size_type; typedef typename allocator_traits::value_type value_type; typedef typename advanced_insert_aux_int::difference_type difference_type; default_construct_aux_proxy(A &a, size_type count) : a_(a), count_(count) {} virtual ~default_construct_aux_proxy() {} virtual void copy_remaining_to(Iterator) { //This should never be called with any count std:: _assert((this->count_ == 0) != 0, "Assertion failed, (" "this->count_ == 0" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/detail/advanced_insert_int.hpp" ", line " "113" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { this->priv_uninitialized_copy(p, this->count_); } virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n) { size_type new_count; if(first_n){ new_count = division_count; } else{ std:: _assert((difference_type(this->count_)>= division_count) != 0, "Assertion failed, (" "difference_type(this->count_)>= division_count" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/detail/advanced_insert_int.hpp" ", line " "126" "\n"); new_count = this->count_ - division_count; } this->priv_uninitialized_copy(pos, new_count); } virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n) { std:: _assert((this->count_ == 0) != 0, "Assertion failed, (" "this->count_ == 0" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/detail/advanced_insert_int.hpp" ", line " "134" "\n"); size_type new_count; if(first_n){ new_count = division_count; } else{ std:: _assert((difference_type(this->count_)>= division_count) != 0, "Assertion failed, (" "difference_type(this->count_)>= division_count" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/detail/advanced_insert_int.hpp" ", line " "140" "\n"); new_count = this->count_ - division_count; } //This function should never called with a count different to zero std:: _assert((new_count == 0) != 0, "Assertion failed, (" "new_count == 0" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/detail/advanced_insert_int.hpp" ", line " "144" "\n"); (void)new_count; } private: void priv_uninitialized_copy(Iterator p, const size_type n) { std:: _assert((n <= this->count_) != 0, "Assertion failed, (" "n <= this->count_" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/detail/advanced_insert_int.hpp" ", line " "151" "\n"); Iterator orig_p = p; size_type i = 0; try{ for(; i < n; ++i, ++p){ alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p)); } } catch(...){ while(i--){ alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++)); } throw; } this->count_ -= n; } A &a_; size_type count_; }; }}} //namespace boost { namespace container { namespace container_detail { namespace boost { namespace container { namespace container_detail { template struct advanced_insert_aux_non_movable_emplace0arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace0arg ( A &a ) : a_(a) , used_(false) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "34" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "34" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "34" "\n"); } A &a_; bool used_; }; template struct advanced_insert_aux_emplace0arg : advanced_insert_aux_non_movable_emplace0arg < A, Iterator > { typedef advanced_insert_aux_non_movable_emplace0arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace0arg ( A &a ) : base_t(a ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp ); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "34" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp ); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace1arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace1arg ( A &a , const P0 & p0 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "37" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "37" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "37" "\n"); } A &a_; bool used_; P0 & m_p0; }; template struct advanced_insert_aux_emplace1arg : advanced_insert_aux_non_movable_emplace1arg < A, Iterator , P0 > { typedef advanced_insert_aux_non_movable_emplace1arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace1arg ( A &a , const P0 & p0 ) : base_t(a , ::boost::forward< P0 >( p0 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "37" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace2arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace2arg ( A &a , const P0 & p0 , const P1 & p1 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "40" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "40" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "40" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; }; template struct advanced_insert_aux_emplace2arg : advanced_insert_aux_non_movable_emplace2arg < A, Iterator , P0 , P1 > { typedef advanced_insert_aux_non_movable_emplace2arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace2arg ( A &a , const P0 & p0 , const P1 & p1 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "40" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace3arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace3arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "43" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "43" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "43" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; }; template struct advanced_insert_aux_emplace3arg : advanced_insert_aux_non_movable_emplace3arg < A, Iterator , P0 , P1 , P2 > { typedef advanced_insert_aux_non_movable_emplace3arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace3arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "43" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace4arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace4arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "46" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "46" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "46" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; }; template struct advanced_insert_aux_emplace4arg : advanced_insert_aux_non_movable_emplace4arg < A, Iterator , P0 , P1 , P2 , P3 > { typedef advanced_insert_aux_non_movable_emplace4arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace4arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "46" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace5arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace5arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "49" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "49" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "49" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; }; template struct advanced_insert_aux_emplace5arg : advanced_insert_aux_non_movable_emplace5arg < A, Iterator , P0 , P1 , P2 , P3 , P4 > { typedef advanced_insert_aux_non_movable_emplace5arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace5arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "49" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace6arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace6arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "52" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "52" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "52" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; }; template struct advanced_insert_aux_emplace6arg : advanced_insert_aux_non_movable_emplace6arg < A, Iterator , P0 , P1 , P2 , P3 , P4 , P5 > { typedef advanced_insert_aux_non_movable_emplace6arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace6arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "52" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace7arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace7arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "55" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "55" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "55" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; }; template struct advanced_insert_aux_emplace7arg : advanced_insert_aux_non_movable_emplace7arg < A, Iterator , P0 , P1 , P2 , P3 , P4 , P5 , P6 > { typedef advanced_insert_aux_non_movable_emplace7arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace7arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "55" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace8arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace8arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)) , m_p7 (const_cast(p7)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "58" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "58" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "58" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; P7 & m_p7; }; template struct advanced_insert_aux_emplace8arg : advanced_insert_aux_non_movable_emplace8arg < A, Iterator , P0 , P1 , P2 , P3 , P4 , P5 , P6 , P7 > { typedef advanced_insert_aux_non_movable_emplace8arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace8arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "58" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace9arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace9arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)) , m_p7 (const_cast(p7)) , m_p8 (const_cast(p8)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "61" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "61" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "61" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; P7 & m_p7; P8 & m_p8; }; template struct advanced_insert_aux_emplace9arg : advanced_insert_aux_non_movable_emplace9arg < A, Iterator , P0 , P1 , P2 , P3 , P4 , P5 , P6 , P7 , P8 > { typedef advanced_insert_aux_non_movable_emplace9arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace9arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "61" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; template struct advanced_insert_aux_non_movable_emplace10arg : public advanced_insert_aux_int { typedef boost::container::allocator_traits alloc_traits; typedef typename allocator_traits ::size_type size_type; typedef typename allocator_traits ::value_type value_type; typedef typename advanced_insert_aux_int ::difference_type difference_type; advanced_insert_aux_non_movable_emplace10arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9 ) : a_(a) , used_(false) , m_p0 (const_cast(p0)) , m_p1 (const_cast(p1)) , m_p2 (const_cast(p2)) , m_p3 (const_cast(p3)) , m_p4 (const_cast(p4)) , m_p5 (const_cast(p5)) , m_p6 (const_cast(p6)) , m_p7 (const_cast(p7)) , m_p8 (const_cast(p8)) , m_p9 (const_cast(p9)) {} virtual void copy_remaining_to(Iterator) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "64" "\n"); } virtual void uninitialized_copy_remaining_to(Iterator p) { if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) , ::boost::forward< P9 >( this->m_p9 ) ); this->used_ = true; } } virtual void uninitialized_copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "64" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ alloc_traits::construct ( this->a_ , container_detail::to_raw_pointer(& *p) , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) , ::boost::forward< P9 >( this->m_p9 ) ); this->used_ = true; } } } virtual void copy_some_and_update(Iterator, difference_type, bool) { std:: _assert((false) != 0, "Assertion failed, (" "false" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "64" "\n"); } A &a_; bool used_; P0 & m_p0; P1 & m_p1; P2 & m_p2; P3 & m_p3; P4 & m_p4; P5 & m_p5; P6 & m_p6; P7 & m_p7; P8 & m_p8; P9 & m_p9; }; template struct advanced_insert_aux_emplace10arg : advanced_insert_aux_non_movable_emplace10arg < A, Iterator , P0 , P1 , P2 , P3 , P4 , P5 , P6 , P7 , P8 , P9 > { typedef advanced_insert_aux_non_movable_emplace10arg base_t; typedef typename base_t::value_type value_type; typedef typename base_t::difference_type difference_type; typedef boost::container::allocator_traits alloc_traits; advanced_insert_aux_emplace10arg ( A &a , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9 ) : base_t(a , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ) ) {} virtual void copy_remaining_to(Iterator p) { if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) , ::boost::forward< P9 >( this->m_p9 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } virtual void copy_some_and_update (Iterator p, difference_type division_count, bool first_n) { std:: _assert((division_count <=1) != 0, "Assertion failed, (" "division_count <=1" "), file " "E:/boost/include/boost-1_50_0_ti/boost/preprocessor/iteration/detail/local.hpp" ", line " "64" "\n"); if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if(!this->used_){ aligned_storage ::value> v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(this->a_, vp , ::boost::forward< P0 >( this->m_p0 ) , ::boost::forward< P1 >( this->m_p1 ) , ::boost::forward< P2 >( this->m_p2 ) , ::boost::forward< P3 >( this->m_p3 ) , ::boost::forward< P4 >( this->m_p4 ) , ::boost::forward< P5 >( this->m_p5 ) , ::boost::forward< P6 >( this->m_p6 ) , ::boost::forward< P7 >( this->m_p7 ) , ::boost::forward< P8 >( this->m_p8 ) , ::boost::forward< P9 >( this->m_p9 )); scoped_destructor d(this->a_, vp); *p = ::boost::move(*vp); d . release(); this->used_ = true; } } } }; }}} //namespace boost { namespace container { namespace container_detail { ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// // // boost/assert.hpp - BOOST_ASSERT(expr) // BOOST_ASSERT_MSG(expr, msg) // BOOST_VERIFY(expr) // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2007 Peter Dimov // Copyright (c) Beman Dawes 2011 // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Note: There are no include guards. This is intentional. // // See http://www.boost.org/libs/utility/assert.html for documentation. // // // Stop inspect complaining about use of 'assert': // // boostinspect:naassert_macro // //--------------------------------------------------------------------------------------// // BOOST_ASSERT // //--------------------------------------------------------------------------------------// /*****************************************************************************/ /* assert.h v7.3.6 */ /* */ /* Copyright (c) 1993-2012 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ using std::_nassert; //--------------------------------------------------------------------------------------// // BOOST_ASSERT_MSG // //--------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------// // BOOST_VERIFY // //--------------------------------------------------------------------------------------// namespace boost { namespace container { /// @cond namespace container_detail { //! Const vector_iterator used to iterate through a vector. template class vector_const_iterator { public: typedef std::random_access_iterator_tag iterator_category; typedef typename boost::intrusive::pointer_traits::element_type value_type; typedef typename boost::intrusive::pointer_traits::difference_type difference_type; typedef typename boost::intrusive::pointer_traits::template rebind_pointer::type pointer; typedef const value_type& reference; /// @cond protected: Pointer m_ptr; public: Pointer get_ptr() const { return m_ptr; } explicit vector_const_iterator(Pointer ptr) : m_ptr(ptr){} /// @endcond public: //Constructors vector_const_iterator() : m_ptr(0){} //Pointer like operators reference operator*() const { return *m_ptr; } const value_type * operator->() const { return container_detail::to_raw_pointer(m_ptr); } reference operator[](difference_type off) const { return m_ptr[off]; } //Increment / Decrement vector_const_iterator& operator++() { ++m_ptr; return *this; } vector_const_iterator operator++(int) { Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); } vector_const_iterator& operator--() { --m_ptr; return *this; } vector_const_iterator operator--(int) { Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); } //Arithmetic vector_const_iterator& operator+=(difference_type off) { m_ptr += off; return *this; } vector_const_iterator operator+(difference_type off) const { return vector_const_iterator(m_ptr+off); } friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right) { return vector_const_iterator(off + right.m_ptr); } vector_const_iterator& operator-=(difference_type off) { m_ptr -= off; return *this; } vector_const_iterator operator-(difference_type off) const { return vector_const_iterator(m_ptr-off); } difference_type operator-(const vector_const_iterator& right) const { return m_ptr - right.m_ptr; } //Comparison operators bool operator== (const vector_const_iterator& r) const { return m_ptr == r.m_ptr; } bool operator!= (const vector_const_iterator& r) const { return m_ptr != r.m_ptr; } bool operator< (const vector_const_iterator& r) const { return m_ptr < r.m_ptr; } bool operator<= (const vector_const_iterator& r) const { return m_ptr <= r.m_ptr; } bool operator> (const vector_const_iterator& r) const { return m_ptr > r.m_ptr; } bool operator>= (const vector_const_iterator& r) const { return m_ptr >= r.m_ptr; } }; //! Iterator used to iterate through a vector template class vector_iterator : public vector_const_iterator { public: explicit vector_iterator(Pointer ptr) : vector_const_iterator(ptr) {} public: typedef std::random_access_iterator_tag iterator_category; typedef typename boost::intrusive::pointer_traits::element_type value_type; typedef typename boost::intrusive::pointer_traits::difference_type difference_type; typedef Pointer pointer; typedef value_type& reference; //Constructors vector_iterator() {} //Pointer like operators reference operator*() const { return *this->m_ptr; } value_type* operator->() const { return container_detail::to_raw_pointer(this->m_ptr); } reference operator[](difference_type off) const { return this->m_ptr[off]; } //Increment / Decrement vector_iterator& operator++() { ++this->m_ptr; return *this; } vector_iterator operator++(int) { pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); } vector_iterator& operator--() { --this->m_ptr; return *this; } vector_iterator operator--(int) { vector_iterator tmp = *this; --*this; return vector_iterator(tmp); } // Arithmetic vector_iterator& operator+=(difference_type off) { this->m_ptr += off; return *this; } vector_iterator operator+(difference_type off) const { return vector_iterator(this->m_ptr+off); } friend vector_iterator operator+(difference_type off, const vector_iterator& right) { return vector_iterator(off + right.m_ptr); } vector_iterator& operator-=(difference_type off) { this->m_ptr -= off; return *this; } vector_iterator operator-(difference_type off) const { return vector_iterator(this->m_ptr-off); } difference_type operator-(const vector_const_iterator& right) const { return static_cast&>(*this) - right; } }; template struct vector_value_traits { typedef T value_type; typedef A allocator_type; static const bool trivial_dctr = boost::has_trivial_destructor::value; static const bool trivial_dctr_after_move = trivial_dctr; //::boost::has_trivial_destructor_after_move::value || trivial_dctr; //static const bool trivial_copy = has_trivial_copy::value; //static const bool nothrow_copy = has_nothrow_copy::value; //static const bool trivial_assign = has_trivial_assign::value; //static const bool nothrow_assign = has_nothrow_assign::value; static const bool trivial_copy = has_trivial_copy::value; static const bool nothrow_copy = has_nothrow_copy::value; static const bool trivial_assign = has_trivial_assign::value; static const bool nothrow_assign = false; //This is the anti-exception array destructor //to deallocate values already constructed typedef typename container_detail::if_c ,container_detail::scoped_destructor_n >::type OldArrayDestructor; //This is the anti-exception array destructor //to destroy objects created with copy construction typedef typename container_detail::if_c ,container_detail::scoped_destructor_n >::type ArrayDestructor; //This is the anti-exception array deallocator typedef typename container_detail::if_c ,container_detail::scoped_array_deallocator >::type ArrayDeallocator; }; //!This struct deallocates and allocated memory template struct vector_alloc_holder { typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::value_type value_type; typedef vector_value_traits value_traits; //Constructor, does not throw vector_alloc_holder() : members_() {} //Constructor, does not throw template explicit vector_alloc_holder(const AllocConvertible & a) : members_(boost::forward(a)) {} //Destructor ~vector_alloc_holder() { this->prot_destroy_all(); this->prot_deallocate(); } typedef container_detail::integral_constant allocator_v1; typedef container_detail::integral_constant allocator_v2; typedef container_detail::integral_constant::value> alloc_version; std::pair allocation_command(allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse = 0) { return allocation_command(command, limit_size, preferred_size, received_size, reuse, alloc_version()); } std::pair allocation_command(allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse, allocator_v1) { (void)limit_size; (void)reuse; if(!(command & allocate_new)) return std::pair(pointer(0), false); received_size = preferred_size; return std::make_pair(this->alloc().allocate(received_size), false); } std::pair allocation_command(allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse, allocator_v2) { return this->alloc().allocation_command (command, limit_size, preferred_size, received_size, reuse); } size_type next_capacity(size_type additional_objects) const { return get_next_capacity( allocator_traits_type::max_size(this->alloc()) , this->members_.m_capacity, additional_objects); } struct members_holder : public A { private: members_holder(const members_holder&); public: template explicit members_holder(const Alloc & alloc) : A(boost::forward(alloc)), m_start(0), m_size(0), m_capacity(0) {} members_holder() : A(), m_start(0), m_size(0), m_capacity(0) {} pointer m_start; size_type m_size; size_type m_capacity; } members_; void swap_members(vector_alloc_holder &x) { container_detail::do_swap(this->members_.m_start, x.members_.m_start); container_detail::do_swap(this->members_.m_size, x.members_.m_size); container_detail::do_swap(this->members_.m_capacity, x.members_.m_capacity); } A &alloc() { return members_; } const A &alloc() const { return members_; } protected: void prot_deallocate() { if(!this->members_.m_capacity) return; this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); this->members_.m_start = 0; this->members_.m_size = 0; this->members_.m_capacity = 0; } void destroy(value_type* p) { if(!value_traits::trivial_dctr) allocator_traits_type::destroy(this->alloc(), p); } void destroy_n(value_type* p, size_type n) { if(!value_traits::trivial_dctr){ for(; n--; ++p){ allocator_traits_type::destroy(this->alloc(), p); } } } void prot_destroy_all() { this->destroy_n(container_detail::to_raw_pointer(this->members_.m_start), this->members_.m_size); this->members_.m_size = 0; } }; } //namespace container_detail { /// @endcond //! \class vector //! A vector is a sequence that supports random access to elements, constant //! time insertion and removal of elements at the end, and linear time insertion //! and removal of elements at the beginning or in the middle. The number of //! elements in a vector may vary dynamically; memory management is automatic. //! boost::container::vector is similar to std::vector but it's compatible //! with shared memory and memory mapped files. template class vector : private container_detail::vector_alloc_holder { /// @cond typedef vector self_t; typedef container_detail::vector_alloc_holder base_t; typedef allocator_traits allocator_traits_type; /// @endcond public: //! The type of object, T, stored in the vector typedef T value_type; //! Pointer to T typedef typename allocator_traits_type::pointer pointer; //! Const pointer to T typedef typename allocator_traits_type::const_pointer const_pointer; //! Reference to T typedef typename allocator_traits_type::reference reference; //! Const reference to T typedef typename allocator_traits_type::const_reference const_reference; //! An unsigned integral type typedef typename allocator_traits_type::size_type size_type; //! A signed integral type typedef typename allocator_traits_type::difference_type difference_type; //! The allocator type typedef A allocator_type; //! The random access iterator typedef container_detail::vector_iterator iterator; //! The random access const_iterator typedef container_detail::vector_const_iterator const_iterator; //! Iterator used to iterate backwards through a vector. typedef std::reverse_iterator reverse_iterator; //! Const iterator used to iterate backwards through a vector. typedef std::reverse_iterator const_reverse_iterator; //! The stored allocator type typedef allocator_type stored_allocator_type; /// @cond private: public: vector& operator=(vector &t) { this->operator=(static_cast & >(const_cast(t))); return *this;} public: operator ::boost::rv &() { return *static_cast< ::boost::rv * >(this); } operator const ::boost::rv &() const { return *static_cast * >(this); } private: typedef container_detail::advanced_insert_aux_int advanced_insert_aux_int_t; typedef container_detail::vector_value_traits value_traits; typedef typename base_t::allocator_v1 allocator_v1; typedef typename base_t::allocator_v2 allocator_v2; typedef typename base_t::alloc_version alloc_version; typedef constant_iterator cvalue_iterator; typedef repeat_iterator repeat_it; typedef boost::move_iterator repeat_move_it; /// @endcond public: //! Effects: Constructs a vector taking the allocator as parameter. //! //! Throws: If allocator_type's default constructor throws. //! //! Complexity: Constant. vector() : base_t() {} //! Effects: Constructs a vector taking the allocator as parameter. //! //! Throws: Nothing //! //! Complexity: Constant. explicit vector(const A& a) : base_t(a) {} //! Effects: Constructs a vector that will use a copy of allocator a //! and inserts n default contructed values. //! //! Throws: If allocator_type's default constructor or allocation //! throws or T's default constructor throws. //! //! Complexity: Linear to n. explicit vector(size_type n) : base_t() { //Allocate size_type real_cap; std::pair ret = this->allocation_command(allocate_new, n, n, real_cap, this->members_.m_start); T *new_mem = container_detail::to_raw_pointer(ret.first); //Anti-exception rollback typename value_traits::ArrayDeallocator scoped_alloc(new_mem, this->alloc(), real_cap); //Default constructor container_detail::default_construct_aux_proxy proxy(this->alloc(), n); proxy.uninitialized_copy_remaining_to(new_mem); //All ok, commit this->members_.m_start = ret.first; this->members_.m_size = n; this->members_.m_capacity = real_cap; scoped_alloc.release(); } //! Effects: Constructs a vector that will use a copy of allocator a //! and inserts n copies of value. //! //! Throws: If allocator_type's default constructor or allocation //! throws or T's copy constructor throws. //! //! Complexity: Linear to n. vector(size_type n, const T& value, const allocator_type& a = allocator_type()) : base_t(a) { this->insert(this->cend(), n, value); } //! Effects: Copy constructs a vector. //! //! Postcondition: x == *this. //! //! Throws: If allocator_type's default constructor or allocation //! throws or T's copy constructor throws. //! //! Complexity: Linear to the elements x contains. vector(const vector &x) : base_t(allocator_traits_type::select_on_container_copy_construction(x.alloc())) { this->assign( container_detail::to_raw_pointer(x.members_.m_start) , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size)); } //! Effects: Move constructor. Moves mx's resources to *this. //! //! Throws: Nothing //! //! Complexity: Constant. vector(::boost::rv< vector > & mx) : base_t(boost::move(mx.alloc())) { this->swap_members(mx); } //! Effects: Copy constructs a vector using the specified allocator. //! //! Postcondition: x == *this. //! //! Throws: If allocation //! throws or T's copy constructor throws. //! //! Complexity: Linear to the elements x contains. vector(const vector &x, const allocator_type &a) : base_t(a) { this->assign( container_detail::to_raw_pointer(x.members_.m_start) , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size)); } //! Effects: Move constructor using the specified allocator. //! Moves mx's resources to *this if a == allocator_type(). //! Otherwise copies values from x to *this. //! //! Throws: If allocation or T's copy constructor throws. //! //! Complexity: Constant if a == mx.get_allocator(), linear otherwise. vector(::boost::rv< vector > & mx, const allocator_type &a) : base_t(a) { if(mx.alloc() == a){ this->swap_members(mx); } else{ this->assign( container_detail::to_raw_pointer(mx.members_.m_start) , container_detail::to_raw_pointer(mx.members_.m_start + mx.members_.m_size)); } } //! Effects: Constructs a vector that will use a copy of allocator a //! and inserts a copy of the range [first, last) in the vector. //! //! Throws: If allocator_type's default constructor or allocation //! throws or T's constructor taking an dereferenced InIt throws. //! //! Complexity: Linear to the range [first, last). template vector(InIt first, InIt last, const allocator_type& a = allocator_type()) : base_t(a) { this->assign(first, last); } //! Effects: Destroys the vector. All stored values are destroyed //! and used memory is deallocated. //! //! Throws: Nothing. //! //! Complexity: Linear to the number of elements. ~vector() {} //vector_alloc_holder clears the data //! Effects: Returns an iterator to the first element contained in the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. iterator begin() { return iterator(this->members_.m_start); } //! Effects: Returns a const_iterator to the first element contained in the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator begin() const { return const_iterator(this->members_.m_start); } //! Effects: Returns an iterator to the end of the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. iterator end() { return iterator(this->members_.m_start + this->members_.m_size); } //! Effects: Returns a const_iterator to the end of the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator end() const { return this->cend(); } //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed vector. //! //! Throws: Nothing. //! //! Complexity: Constant. reverse_iterator rbegin() { return reverse_iterator(this->end()); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator rbegin() const { return this->crbegin(); } //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed vector. //! //! Throws: Nothing. //! //! Complexity: Constant. reverse_iterator rend() { return reverse_iterator(this->begin()); } //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator rend() const { return this->crend(); } //! Effects: Returns a const_iterator to the first element contained in the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cbegin() const { return const_iterator(this->members_.m_start); } //! Effects: Returns a const_iterator to the end of the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_iterator cend() const { return const_iterator(this->members_.m_start + this->members_.m_size); } //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crbegin() const { return const_reverse_iterator(this->end());} //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed vector. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reverse_iterator crend() const { return const_reverse_iterator(this->begin()); } //! Requires: !empty() //! //! Effects: Returns a reference to the first //! element of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. reference front() { return *this->members_.m_start; } //! Requires: !empty() //! //! Effects: Returns a const reference to the first //! element of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reference front() const { return *this->members_.m_start; } //! Requires: !empty() //! //! Effects: Returns a reference to the last //! element of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. reference back() { return this->members_.m_start[this->members_.m_size - 1]; } //! Requires: !empty() //! //! Effects: Returns a const reference to the last //! element of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reference back() const { return this->members_.m_start[this->members_.m_size - 1]; } //! Returns: A pointer such that [data(),data() + size()) is a valid range. //! For a non-empty vector, data() == &front(). //! //! Throws: Nothing. //! //! Complexity: Constant. pointer data() { return this->members_.m_start; } //! Returns: A pointer such that [data(),data() + size()) is a valid range. //! For a non-empty vector, data() == &front(). //! //! Throws: Nothing. //! //! Complexity: Constant. const_pointer data() const { return this->members_.m_start; } //! Effects: Returns the number of the elements contained in the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. size_type size() const { return this->members_.m_size; } //! Effects: Returns the largest possible size of the vector. //! //! Throws: Nothing. //! //! Complexity: Constant. size_type max_size() const { return allocator_traits_type::max_size(this->alloc()); } //! Effects: Number of elements for which memory has been allocated. //! capacity() is always greater than or equal to size(). //! //! Throws: Nothing. //! //! Complexity: Constant. size_type capacity() const { return this->members_.m_capacity; } //! Effects: Returns true if the vector contains no elements. //! //! Throws: Nothing. //! //! Complexity: Constant. bool empty() const { return !this->members_.m_size; } //! Requires: size() > n. //! //! Effects: Returns a reference to the nth element //! from the beginning of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. reference operator[](size_type n) { return this->members_.m_start[n]; } //! Requires: size() > n. //! //! Effects: Returns a const reference to the nth element //! from the beginning of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. const_reference operator[](size_type n) const { return this->members_.m_start[n]; } //! Requires: size() > n. //! //! Effects: Returns a reference to the nth element //! from the beginning of the container. //! //! Throws: std::range_error if n >= size() //! //! Complexity: Constant. reference at(size_type n) { this->priv_check_range(n); return this->members_.m_start[n]; } //! Requires: size() > n. //! //! Effects: Returns a const reference to the nth element //! from the beginning of the container. //! //! Throws: std::range_error if n >= size() //! //! Complexity: Constant. const_reference at(size_type n) const { this->priv_check_range(n); return this->members_.m_start[n]; } //! Effects: Returns a copy of the internal allocator. //! //! Throws: If allocator's copy constructor throws. //! //! Complexity: Constant. allocator_type get_allocator() const { return this->alloc(); } //! Effects: Returns a reference to the internal allocator. //! //! Throws: Nothing //! //! Complexity: Constant. //! //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return this->alloc(); } //! Effects: Returns a reference to the internal allocator. //! //! Throws: Nothing //! //! Complexity: Constant. //! //! Note: Non-standard extension. stored_allocator_type &get_stored_allocator() { return this->alloc(); } //! Effects: If n is less than or equal to capacity(), this call has no //! effect. Otherwise, it is a request for allocation of additional memory. //! If the request is successful, then capacity() is greater than or equal to //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. //! //! Throws: If memory allocation allocation throws or T's copy/move constructor throws. void reserve(size_type new_cap) { if (this->capacity() < new_cap){ //There is not enough memory, allocate a new //buffer or expand the old one. bool same_buffer_start; size_type real_cap = 0; std::pair ret = this->allocation_command (allocate_new | expand_fwd | expand_bwd, new_cap, new_cap, real_cap, this->members_.m_start); //Check for forward expansion same_buffer_start = ret.second && this->members_.m_start == ret.first; if(same_buffer_start){ this->members_.m_capacity = real_cap; } //If there is no forward expansion, move objects else{ //We will reuse insert code, so create a dummy input iterator T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start)); container_detail::advanced_insert_aux_proxy, T*> proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it)); //Backwards (and possibly forward) expansion if(ret.second){ this->priv_range_insert_expand_backwards ( container_detail::to_raw_pointer(ret.first) , real_cap , container_detail::to_raw_pointer(this->members_.m_start) , 0 , proxy); } //New buffer else{ this->priv_range_insert_new_allocation ( container_detail::to_raw_pointer(ret.first) , real_cap , container_detail::to_raw_pointer(this->members_.m_start) , 0 , proxy); } } } } //! Effects: Makes *this contain the same elements as x. //! //! Postcondition: this->size() == x.size(). *this contains a copy //! of each of x's elements. //! //! Throws: If memory allocation throws or T's copy/move constructor/assignment throws. //! //! Complexity: Linear to the number of elements in x. vector& operator=(const ::boost::rv< vector > & x) { if (&x != this){ allocator_type &this_alloc = this->alloc(); const allocator_type &x_alloc = x.alloc(); container_detail::bool_ flag; if(flag && this_alloc != x_alloc){ this->clear(); this->shrink_to_fit(); } container_detail::assign_alloc(this_alloc, x_alloc, flag); this->assign( container_detail::to_raw_pointer(x.members_.m_start) , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size)); } return *this; } //! Effects: Move assignment. All mx's values are transferred to *this. //! //! Postcondition: x.empty(). *this contains a the elements x had //! before the function. //! //! Throws: Nothing //! //! Complexity: Linear. vector& operator=(::boost::rv< vector > & x) //iG BOOST_CONTAINER_NOEXCEPT_IF(!allocator_type::propagate_on_container_move_assignment::value || is_nothrow_move_assignable::value);) { if (&x != this){ allocator_type &this_alloc = this->alloc(); allocator_type &x_alloc = x.alloc(); //If allocators are equal we can just swap pointers if(this_alloc == x_alloc){ //Destroy objects but retain memory in case x reuses it in the future this->clear(); this->swap_members(x); //Move allocator if needed container_detail::bool_ flag; container_detail::move_alloc(this_alloc, x_alloc, flag); } //If unequal allocators, then do a one by one move else{ this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start)) , boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size))); } } return *this; } //! Effects: Assigns the n copies of val to *this. //! //! Throws: If memory allocation throws or //! T's copy/move constructor/assignment throws. //! //! Complexity: Linear to n. void assign(size_type n, const value_type& val) { this->assign(cvalue_iterator(val, n), cvalue_iterator()); } //! Effects: Assigns the the range [first, last) to *this. //! //! Throws: If memory allocation throws or T's copy/move constructor/assignment or //! T's constructor/assignment from dereferencing InpIt throws. //! //! Complexity: Linear to n. template void assign(InIt first, InIt last) { //Dispatch depending on integer/iterator const bool aux_boolean = container_detail::is_convertible::value; typedef container_detail::bool_ Result; this->priv_assign_dispatch(first, last, Result()); } void push_back(typename ::boost::mpl::if_< ::boost::is_class, const ::boost::rv< T > &, const T & > ::type x) { return priv_push_back(static_cast(x)); } void push_back(typename ::boost::mpl::if_< ::boost::is_class, ::boost::rv< T > &, not_a_type> ::type x) { return priv_push_back(::boost::move(x)); } void push_back(T &x) { return priv_push_back(const_cast(x)); } template typename ::boost::enable_if_c < ::boost::is_class ::value && ::boost::is_same ::value && ! ::boost::has_move_emulation_enabled ::value , void > ::type push_back(const BOOST_MOVE_TEMPL_PARAM &u) { return priv_push_back(u); } template typename ::boost::enable_if_c < (! ::boost::is_class ::value || ! ::boost::move_detail::is_rv ::value) && ! ::boost::is_same ::value , void > ::type push_back(const BOOST_MOVE_TEMPL_PARAM &u) { T t(u); return priv_push_back(::boost::move(t)); } void emplace_back() { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace0arg proxy (this->alloc() ); priv_range_insert(back_pos, 1, proxy); } } iterator emplace(const_iterator pos ) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace0arg proxy (this->alloc() ); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 > void emplace_back( const P0 & p0) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace1arg proxy (this->alloc() , ::boost::forward< P0 >( p0 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 > iterator emplace(const_iterator pos , const P0 & p0) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace1arg proxy (this->alloc() , ::boost::forward< P0 >( p0 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 > void emplace_back( const P0 & p0 , const P1 & p1) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace2arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace2arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace3arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace3arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 , class P3 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace4arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 , class P3 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace4arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 , class P3 , class P4 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace5arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 , class P3 , class P4 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace5arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace6arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace6arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace7arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace7arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace8arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace8arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace9arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace9arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > void emplace_back( const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { T* back_pos = container_detail::to_raw_pointer (this->members_ . m_start) + this->members_ . m_size; if (this->members_ . m_size < this->members_ . m_capacity){ allocator_traits_type::construct (this->alloc() , back_pos , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 ) ); ++this->members_ . m_size; } else{ container_detail::advanced_insert_aux_emplace10arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )); priv_range_insert(back_pos, 1, proxy); } } template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 > iterator emplace(const_iterator pos , const P0 & p0 , const P1 & p1 , const P2 & p2 , const P3 & p3 , const P4 & p4 , const P5 & p5 , const P6 & p6 , const P7 & p7 , const P8 & p8 , const P9 & p9) { size_type pos_n = pos - cbegin(); container_detail::advanced_insert_aux_emplace10arg proxy (this->alloc() , ::boost::forward< P0 >( p0 ) , ::boost::forward< P1 >( p1 ) , ::boost::forward< P2 >( p2 ) , ::boost::forward< P3 >( p3 ) , ::boost::forward< P4 >( p4 ) , ::boost::forward< P5 >( p5 ) , ::boost::forward< P6 >( p6 ) , ::boost::forward< P7 >( p7 ) , ::boost::forward< P8 >( p8 ) , ::boost::forward< P9 >( p9 )); priv_range_insert(container_detail::to_raw_pointer(pos . get_ptr()), 1, proxy); return iterator(this->members_ . m_start + pos_n); } //! Effects: Swaps the contents of *this and x. //! //! Throws: Nothing. //! //! Complexity: Constant. void swap(vector& x) { //Just swap internals this->swap_members(x); //And now the allocator container_detail::bool_ flag; container_detail::swap_alloc(this->alloc(), x.alloc(), flag); } iterator insert(const_iterator arg1, typename ::boost::mpl::if_< ::boost::is_class, const ::boost::rv< T > &, const T & > ::type x) { return priv_insert(arg1, static_cast(x)); } iterator insert(const_iterator arg1, typename ::boost::mpl::if_< ::boost::is_class, ::boost::rv< T > &, not_a_type> ::type x) { return priv_insert(arg1, ::boost::move(x)); } iterator insert(const_iterator arg1, T &x) { return priv_insert(arg1, const_cast(x)); } template typename ::boost::enable_if_c < ::boost::is_class ::value && ::boost::is_same ::value && ! ::boost::has_move_emulation_enabled ::value , iterator > ::type insert(const_iterator arg1, const BOOST_MOVE_TEMPL_PARAM &u) { return priv_insert(arg1, u); } template typename ::boost::enable_if_c < (! ::boost::is_class ::value || ! ::boost::move_detail::is_rv ::value) && ! ::boost::is_same ::value , iterator > ::type insert(const_iterator arg1, const BOOST_MOVE_TEMPL_PARAM &u) { T t(u); return priv_insert(arg1, ::boost::move(t)); } //! Requires: pos must be a valid iterator of *this. //! //! Effects: Insert a copy of the [first, last) range before pos. //! //! Throws: If memory allocation throws, T's constructor from a //! dereferenced InpIt throws or T's copy/move constructor/assignment throws. //! //! Complexity: Linear to std::distance [first, last). template void insert(const_iterator pos, InIt first, InIt last) { //Dispatch depending on integer/iterator const bool aux_boolean = container_detail::is_convertible::value; typedef container_detail::bool_ Result; this->priv_insert_dispatch(pos, first, last, Result()); } //! Requires: pos must be a valid iterator of *this. //! //! Effects: Insert n copies of x before pos. //! //! Throws: If memory allocation throws or T's copy constructor throws. //! //! Complexity: Linear to n. void insert(const_iterator p, size_type n, const T& x) { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); } //! Effects: Removes the last element from the vector. //! //! Throws: Nothing. //! //! Complexity: Constant time. void pop_back() { //Destroy last element --this->members_.m_size; this->destroy(container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size); } //! Effects: Erases the element at position pos. //! //! Throws: Nothing. //! //! Complexity: Linear to the elements between pos and the //! last element. Constant if pos is the last element. iterator erase(const_iterator position) { T *pos = container_detail::to_raw_pointer(position.get_ptr()); T *beg = container_detail::to_raw_pointer(this->members_.m_start); ::boost::move(pos + 1, beg + this->members_.m_size, pos); --this->members_.m_size; //Destroy last element base_t::destroy(container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size); return iterator(position.get_ptr()); } //! Effects: Erases the elements pointed by [first, last). //! //! Throws: Nothing. //! //! Complexity: Linear to the distance between first and last //! plus linear to the elements between pos and the last element. iterator erase(const_iterator first, const_iterator last) { if (first != last){ // worth doing, copy down over hole T* end_pos = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size; T* ptr = container_detail::to_raw_pointer(boost::move (container_detail::to_raw_pointer(last.get_ptr()) ,end_pos ,container_detail::to_raw_pointer(first.get_ptr()) )); size_type destroyed = (end_pos - ptr); this->destroy_n(ptr, destroyed); this->members_.m_size -= destroyed; } return iterator(first.get_ptr()); } //! Effects: Inserts or erases elements at the end such that //! the size becomes n. New elements are copy constructed from x. //! //! Throws: If memory allocation throws, or T's copy constructor throws. //! //! Complexity: Linear to the difference between size() and new_size. void resize(size_type new_size, const T& x) { pointer finish = this->members_.m_start + this->members_.m_size; if (new_size < size()){ //Destroy last elements this->erase(const_iterator(this->members_.m_start + new_size), this->end()); } else{ //Insert new elements at the end this->insert(const_iterator(finish), new_size - this->size(), x); } } //! Effects: Inserts or erases elements at the end such that //! the size becomes n. New elements are default constructed. //! //! Throws: If memory allocation throws, or T's copy constructor throws. //! //! Complexity: Linear to the difference between size() and new_size. void resize(size_type new_size) { if (new_size < this->size()){ //Destroy last elements this->erase(const_iterator(this->members_.m_start + new_size), this->end()); } else{ size_type n = new_size - this->size(); this->reserve(new_size); container_detail::default_construct_aux_proxy proxy(this->alloc(), n); priv_range_insert(this->cend().get_ptr(), n, proxy); } } //! Effects: Erases all the elements of the vector. //! //! Throws: Nothing. //! //! Complexity: Linear to the number of elements in the vector. void clear() { this->prot_destroy_all(); } //! Effects: Tries to deallocate the excess of memory created //! with previous allocations. The size of the vector is unchanged //! //! Throws: If memory allocation throws, or T's copy/move constructor throws. //! //! Complexity: Linear to size(). void shrink_to_fit() { priv_shrink_to_fit(alloc_version()); } /// @cond //Absolutely experimental. This function might change, disappear or simply crash! template void insert_ordered_at(size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it) { const size_type *dummy = 0; this->priv_insert_ordered_at(element_count, last_position_it, false, &dummy[0], last_value_it); } //Absolutely experimental. This function might change, disappear or simply crash! template void insert_ordered_at(size_type element_count, BiDirPosConstIt last_position_it, BiDirSkipConstIt last_skip_it, BiDirValueIt last_value_it) { this->priv_insert_ordered_at(element_count, last_position_it, true, last_skip_it, last_value_it); } private: iterator priv_insert(const_iterator position, const T &x) { //Just call more general insert(pos, size, value) and return iterator size_type pos_n = position - cbegin(); this->insert(position, (size_type)1, x); return iterator(this->members_.m_start + pos_n); } iterator priv_insert(const_iterator position, ::boost::rv< T > & x) { //Just call more general insert(pos, size, value) and return iterator size_type pos_n = position - cbegin(); this->insert(position ,repeat_move_it(repeat_it(x, 1)) ,repeat_move_it(repeat_it())); return iterator(this->members_.m_start + pos_n); } template void priv_push_back(const U & x) { if (this->members_.m_size < this->members_.m_capacity){ //There is more memory, just construct a new object at the end allocator_traits_type::construct ( this->alloc() , container_detail::to_raw_pointer(this->members_.m_start + this->members_.m_size) , ::boost::forward(x) ); ++this->members_.m_size; } else{ this->insert(this->cend(), ::boost::forward(x)); } } template void priv_shrink_to_fit( AllocVersion , typename container_detail::enable_if_c< container_detail::is_same::value >::type * = 0) { if(this->members_.m_capacity){ if(!size()){ this->prot_deallocate(); } else{ //Allocate a new buffer. size_type real_cap = 0; std::pair ret = this->allocation_command (allocate_new, this->size(), this->size(), real_cap, this->members_.m_start); if(real_cap < this->capacity()){ //We will reuse insert code, so create a dummy input iterator T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start)); container_detail::advanced_insert_aux_proxy, T*> proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it)); this->priv_range_insert_new_allocation ( container_detail::to_raw_pointer(ret.first) , real_cap , container_detail::to_raw_pointer(this->members_.m_start) , 0 , proxy); } else{ this->alloc().deallocate(ret.first, real_cap); } } } } template void priv_shrink_to_fit(AllocVersion , typename container_detail::enable_if_c< !container_detail::is_same::value >::type * = 0) { if(this->members_.m_capacity){ if(!size()){ this->prot_deallocate(); } else{ size_type received_size; if(this->alloc().allocation_command ( shrink_in_place | nothrow_allocation , this->capacity(), this->size() , received_size, this->members_.m_start).first){ this->members_.m_capacity = received_size; } } } } template void priv_range_insert(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag) { if(first != last){ const size_type n = std::distance(first, last); container_detail::advanced_insert_aux_proxy proxy(this->alloc(), first, last); priv_range_insert(pos.get_ptr(), n, proxy); } } template void priv_range_insert(const_iterator pos, InIt first, InIt last, std::input_iterator_tag) { for(;first != last; ++first){ this->emplace(pos, *first); } } void priv_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf) { //Check if we have enough memory or try to expand current memory size_type remaining = this->members_.m_capacity - this->members_.m_size; bool same_buffer_start; std::pair ret; size_type real_cap = this->members_.m_capacity; //Check if we already have room if (n <= remaining){ same_buffer_start = true; } else{ //There is not enough memory, allocate a new //buffer or expand the old one. size_type new_cap = this->next_capacity(n); ret = this->allocation_command (allocate_new | expand_fwd | expand_bwd, this->members_.m_size + n, new_cap, real_cap, this->members_.m_start); //Check for forward expansion same_buffer_start = ret.second && this->members_.m_start == ret.first; if(same_buffer_start){ this->members_.m_capacity = real_cap; } } //If we had room or we have expanded forward if (same_buffer_start){ this->priv_range_insert_expand_forward (container_detail::to_raw_pointer(pos), n, interf); } //Backwards (and possibly forward) expansion else if(ret.second){ this->priv_range_insert_expand_backwards ( container_detail::to_raw_pointer(ret.first) , real_cap , container_detail::to_raw_pointer(pos) , n , interf); } //New buffer else{ this->priv_range_insert_new_allocation ( container_detail::to_raw_pointer(ret.first) , real_cap , container_detail::to_raw_pointer(pos) , n , interf); } } //Absolutely experimental. This function might change, disappear or simply crash! template void priv_insert_ordered_at( size_type element_count, BiDirPosConstIt last_position_it , bool do_skip, BiDirSkipConstIt last_skip_it, BiDirValueIt last_value_it) { const size_type old_size_pos = this->size(); this->reserve(old_size_pos + element_count); T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start); size_type insertions_left = element_count; size_type next_pos = old_size_pos; size_type hole_size = element_count; //Exception rollback. If any copy throws before the hole is filled, values //already inserted/copied at the end of the buffer will be destroyed. typename value_traits::ArrayDestructor past_hole_values_destroyer (begin_ptr + old_size_pos + element_count, this->alloc(), size_type(0u)); //Loop for each insertion backwards, first moving the elements after the insertion point, //then inserting the element. while(insertions_left){ const size_type pos = static_cast(*(--last_position_it)); std:: _assert((pos <= old_size_pos) != 0, "Assertion failed, (" "pos <= old_size_pos" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/vector.hpp" ", line " "1501" "\n"); //If needed shift the range after the insertion point and the previous insertion point. //Function will take care if the shift crosses the size() boundary, using copy/move //or uninitialized copy/move if necessary. size_type new_hole_size = (pos != next_pos) ? priv_insert_ordered_at_shift_range(pos, next_pos, this->size(), insertions_left) : hole_size ; if(new_hole_size > 0){ //The hole was reduced by priv_insert_ordered_at_shift_range so expand exception rollback range backwards past_hole_values_destroyer.increment_size_backwards(next_pos - pos); //Insert the new value in the hole allocator_traits_type::construct(this->alloc(), begin_ptr + pos + insertions_left - 1, *(--last_value_it)); --new_hole_size; if(new_hole_size == 0){ //Hole was just filled, disable exception rollback and change vector size past_hole_values_destroyer.release(); this->members_.m_size += element_count; } else{ //The hole was reduced by the new insertion by one past_hole_values_destroyer.increment_size_backwards(size_type(1u)); } } else{ if(hole_size){ //Hole was just filled by priv_insert_ordered_at_shift_range, disable exception rollback and change vector size past_hole_values_destroyer.release(); this->members_.m_size += element_count; } //Insert the new value in the already constructed range begin_ptr[pos + insertions_left - 1] = *(--last_value_it); } if(do_skip){ size_type n = *(--last_skip_it); while(n--){ --last_value_it; } } --insertions_left; hole_size = new_hole_size; next_pos = pos; } } //Takes the range pointed by [first_pos, last_pos) and shifts it to the right //by 'shift_count'. 'limit_pos' marks the end of constructed elements. // //Precondition: first_pos <= last_pos <= limit_pos // //The shift operation might cross limit_pos so elements to moved beyond limit_pos //are uninitialized_moved with an allocator. Other elements are moved. // //The shift operation might left uninitialized elements after limit_pos //and the number of uninitialized elements is returned by the function. // //Old situation: // first_pos last_pos old_limit // | | | // ____________V_______V__________________V_____________ //| prefix | range | suffix |raw_mem ~ //|____________|_______|__________________|_____________~ // //New situation in Case A (hole_size == 0): // range is moved through move assignments // // first_pos last_pos old_limit // | | | // ____________V_______V__________________V_____________ //| prefix' | | | range |suffix'|raw_mem ~ //|________________+______|___^___|_______|_____________~ // | | // |_>_>_>_>_>^ // // //New situation in Case B (hole_size >= 0): // range is moved through uninitialized moves // // first_pos last_pos old_limit // | | | // ____________V_______V__________________V________________ //| prefix' | | | [hole] | range | //|_______________________________________|________|___^___| // | | // |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^ // //New situation in Case C (hole_size == 0): // range is moved through move assignments and uninitialized moves // // first_pos last_pos old_limit // | | | // ____________V_______V__________________V___ //| prefix' | | | range | //|___________________________________|___^___| // | | // |_>_>_>_>_>_>_>_>_>_>_>^ size_type priv_insert_ordered_at_shift_range(size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count) { std:: _assert((first_pos <= last_pos) != 0, "Assertion failed, (" "first_pos <= last_pos" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/vector.hpp" ", line " "1599" "\n"); std:: _assert((last_pos <= limit_pos) != 0, "Assertion failed, (" "last_pos <= limit_pos" "), file " "E:/boost/include/boost-1_50_0_ti/boost/container/vector.hpp" ", line " "1600" "\n"); // T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start); size_type hole_size = 0; //Case A: if((last_pos + shift_count) <= limit_pos){ //All move assigned boost::move_backward(begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + last_pos + shift_count); } //Case B: else if((first_pos + shift_count) >= limit_pos){ //All uninitialized_moved ::boost::container::uninitialized_move_alloc (this->alloc(), begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + first_pos + shift_count); hole_size = last_pos + shift_count - limit_pos; } //Case C: else{ //Some uninitialized_moved T* const limit_ptr = begin_ptr + limit_pos; T* const boundary_ptr = limit_ptr - shift_count; ::boost::container::uninitialized_move_alloc (this->alloc(), boundary_ptr, begin_ptr + last_pos, limit_ptr); //The rest is move assigned boost::move_backward(begin_ptr + first_pos, boundary_ptr, limit_ptr); } return hole_size; } private: void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf) { //n can't be 0, because there is nothing to do in that case if(!n) return; //There is enough memory T* old_finish = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size; const size_type elems_after = old_finish - pos; if (elems_after >= n){ //New elements can be just copied. //Move to uninitialized memory last objects ::boost::container::uninitialized_move_alloc (this->alloc(), old_finish - n, old_finish, old_finish); this->members_.m_size += n; //Copy previous to last objects to the initialized end boost::move_backward(pos, old_finish - n, old_finish); //Insert new objects in the pos interf.copy_remaining_to(pos); } else { //The new elements don't fit in the [pos, end()) range. Copy //to the beginning of the unallocated zone the last new elements. interf.uninitialized_copy_some_and_update(old_finish, elems_after, false); this->members_.m_size += n - elems_after; //Copy old [pos, end()) elements to the uninitialized memory ::boost::container::uninitialized_move_alloc (this->alloc(), pos, old_finish, container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size); this->members_.m_size += elems_after; //Copy first new elements in pos interf.copy_remaining_to(pos); } } void priv_range_insert_new_allocation (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf) { //n can be zero, if we want to reallocate! T *new_finish = new_start; T *old_finish; //Anti-exception rollbacks typename value_traits::ArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap); typename value_traits::ArrayDestructor constructed_values_destroyer(new_start, this->alloc(), 0u); //Initialize with [begin(), pos) old buffer //the start of the new buffer T *old_buffer = container_detail::to_raw_pointer(this->members_.m_start); if(old_buffer){ new_finish = ::boost::container::uninitialized_move_alloc (this->alloc(), container_detail::to_raw_pointer(this->members_.m_start), pos, old_finish = new_finish); constructed_values_destroyer.increment_size(new_finish - old_finish); } //Initialize new objects, starting from previous point interf.uninitialized_copy_remaining_to(old_finish = new_finish); new_finish += n; constructed_values_destroyer.increment_size(new_finish - old_finish); //Initialize from the rest of the old buffer, //starting from previous point if(old_buffer){ new_finish = ::boost::container::uninitialized_move_alloc (this->alloc(), pos, old_buffer + this->members_.m_size, new_finish); //Destroy and deallocate old elements //If there is allocated memory, destroy and deallocate if(!value_traits::trivial_dctr_after_move) this->destroy_n(old_buffer, this->members_.m_size); this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); } this->members_.m_start = new_start; this->members_.m_size = new_finish - new_start; this->members_.m_capacity = new_cap; //All construction successful, disable rollbacks constructed_values_destroyer.release(); scoped_alloc.release(); } void priv_range_insert_expand_backwards (T* new_start, size_type new_capacity, T* pos, const size_type n, advanced_insert_aux_int_t &interf) { //n can be zero to just expand capacity //Backup old data T* old_start = container_detail::to_raw_pointer(this->members_.m_start); T* old_finish = old_start + this->members_.m_size; size_type old_size = this->members_.m_size; //We can have 8 possibilities: const size_type elemsbefore = (size_type)(pos - old_start); const size_type s_before = (size_type)(old_start - new_start); //Update the vector buffer information to a safe state this->members_.m_start = new_start; this->members_.m_capacity = new_capacity; this->members_.m_size = 0; //If anything goes wrong, this object will destroy //all the old objects to fulfill previous vector state typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size); //Check if s_before is big enough to hold the beginning of old data + new data if(difference_type(s_before) >= difference_type(elemsbefore + n)){ //Copy first old values before pos, after that the new objects ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start); this->members_.m_size = elemsbefore; interf.uninitialized_copy_remaining_to(new_start + elemsbefore); this->members_.m_size += n; //Check if s_before is so big that even copying the old data + new data //there is a gap between the new data and the old data if(s_before >= (old_size + n)){ //Old situation: // _________________________________________________________ //| raw_mem | old_begin | old_end | //| __________________________________|___________|_________| // //New situation: // _________________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|__________|_________|________________________| // //Now initialize the rest of memory with the last old values ::boost::container::uninitialized_move_alloc (this->alloc(), pos, old_finish, new_start + elemsbefore + n); //All new elements correctly constructed, avoid new element destruction this->members_.m_size = old_size + n; //Old values destroyed automatically with "old_values_destroyer" //when "old_values_destroyer" goes out of scope unless the have trivial //destructor after move. if(value_traits::trivial_dctr_after_move) old_values_destroyer.release(); } //s_before is so big that divides old_end else{ //Old situation: // __________________________________________________ //| raw_mem | old_begin | old_end | //| ___________________________|___________|_________| // //New situation: // __________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|__________|_________|_________________| // //Now initialize the rest of memory with the last old values //All new elements correctly constructed, avoid new element destruction size_type raw_gap = s_before - (elemsbefore + n); //Now initialize the rest of s_before memory with the //first of elements after new values ::boost::container::uninitialized_move_alloc (this->alloc(), pos, pos + raw_gap, new_start + elemsbefore + n); //Update size since we have a contiguous buffer this->members_.m_size = old_size + s_before; //All new elements correctly constructed, avoid old element destruction old_values_destroyer.release(); //Now copy remaining last objects in the old buffer begin T *to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start); //Now destroy redundant elements except if they were moved and //they have trivial destructor after move size_type n_destroy = old_finish - to_destroy; if(!value_traits::trivial_dctr_after_move) this->destroy_n(to_destroy, n_destroy); this->members_.m_size -= n_destroy; } } else{ //Check if we have to do the insertion in two phases //since maybe s_before is not big enough and //the buffer was expanded both sides // //Old situation: // _________________________________________________ //| raw_mem | old_begin + old_end | raw_mem | //|_________|_____________________|_________________| // //New situation with do_after: // _________________________________________________ //| old_begin + new + old_end | raw_mem | //|___________________________________|_____________| // //New without do_after: // _________________________________________________ //| old_begin + new + old_end | raw_mem | //|____________________________|____________________| // bool do_after = n > s_before; //Now we can have two situations: the raw_mem of the //beginning divides the old_begin, or the new elements: if (s_before <= elemsbefore) { //The raw memory divides the old_begin group: // //If we need two phase construction (do_after) //new group is divided in new = new_beg + new_end groups //In this phase only new_beg will be inserted // //Old situation: // _________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|_________|___________|_________|_________________| // //New situation with do_after(1): //This is not definitive situation, the second phase //will include // _________________________________________________ //| old_begin | new_beg | old_end | raw_mem | //|___________|_________|_________|_________________| // //New situation without do_after: // _________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|_____|_________|_____________________| // //Copy the first part of old_begin to raw_mem T *start_n = old_start + difference_type(s_before); ::boost::container::uninitialized_move_alloc (this->alloc(), old_start, start_n, new_start); //The buffer is all constructed until old_end, //release destroyer and update size old_values_destroyer.release(); this->members_.m_size = old_size + s_before; //Now copy the second part of old_begin overwriting himself T* next = ::boost::move(start_n, pos, old_start); if(do_after){ //Now copy the new_beg elements interf.copy_some_and_update(next, s_before, true); } else{ //Now copy the all the new elements interf.copy_remaining_to(next); T* move_start = next + n; //Now displace old_end elements T* move_end = ::boost::move(pos, old_finish, move_start); //Destroy remaining moved elements from old_end except if //they have trivial destructor after being moved difference_type n_destroy = s_before - n; if(!value_traits::trivial_dctr_after_move) this->destroy_n(move_end, n_destroy); this->members_.m_size -= n_destroy; } } else { //If we have to expand both sides, //we will play if the first new values so //calculate the upper bound of new values //The raw memory divides the new elements // //If we need two phase construction (do_after) //new group is divided in new = new_beg + new_end groups //In this phase only new_beg will be inserted // //Old situation: // _______________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|_______________|___________|_________|_________________| // //New situation with do_after(): // ____________________________________________________ //| old_begin | new_beg | old_end | raw_mem | //|___________|_______________|_________|______________| // //New situation without do_after: // ______________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|_____|_________|__________________________| // //First copy whole old_begin and part of new to raw_mem ::boost::container::uninitialized_move_alloc (this->alloc(), old_start, pos, new_start); this->members_.m_size = elemsbefore; const size_type mid_n = difference_type(s_before) - elemsbefore; interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true); this->members_.m_size = old_size + s_before; //The buffer is all constructed until old_end, //release destroyer and update size old_values_destroyer.release(); if(do_after){ //Copy new_beg part interf.copy_some_and_update(old_start, s_before - mid_n, true); } else{ //Copy all new elements interf.copy_remaining_to(old_start); T* move_start = old_start + (n-mid_n); //Displace old_end T* move_end = ::boost::move(pos, old_finish, move_start); //Destroy remaining moved elements from old_end except if they //have trivial destructor after being moved difference_type n_destroy = s_before - n; if(!value_traits::trivial_dctr_after_move) this->destroy_n(move_end, n_destroy); this->members_.m_size -= n_destroy; } } //This is only executed if two phase construction is needed //This can be executed without exception handling since we //have to just copy and append in raw memory and //old_values_destroyer has been released in phase 1. if(do_after){ //The raw memory divides the new elements // //Old situation: // ______________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|______________|___________|____________|______________| // //New situation with do_after(1): // _______________________________________________________ //| old_begin + new_beg | new_end |old_end | raw_mem | //|__________________________|_________|________|_________| // //New situation with do_after(2): // ______________________________________________________ //| old_begin + new | old_end |raw | //|_______________________________________|_________|____| // const size_type n_after = n - s_before; const difference_type elemsafter = old_size - elemsbefore; //We can have two situations: if (elemsafter > difference_type(n_after)){ //The raw_mem from end will divide displaced old_end // //Old situation: // ______________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|______________|___________|____________|______________| // //New situation with do_after(1): // _______________________________________________________ //| old_begin + new_beg | new_end |old_end | raw_mem | //|__________________________|_________|________|_________| // //First copy the part of old_end raw_mem T* finish_n = old_finish - difference_type(n_after); ::boost::container::uninitialized_move_alloc (this->alloc(), finish_n, old_finish, old_finish); this->members_.m_size += n_after; //Displace the rest of old_end to the new position boost::move_backward(pos, finish_n, old_finish); //Now overwrite with new_end //The new_end part is [first + (n - n_after), last) interf.copy_remaining_to(pos); } else { //The raw_mem from end will divide new_end part // //Old situation: // _____________________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|______________|___________|____________|_____________________| // //New situation with do_after(2): // _____________________________________________________________ //| old_begin + new_beg | new_end |old_end | raw_mem | //|__________________________|_______________|________|_________| // size_type mid_last_dist = n_after - elemsafter; //First initialize data in raw memory //The new_end part is [first + (n - n_after), last) interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false); this->members_.m_size += mid_last_dist; ::boost::container::uninitialized_move_alloc (this->alloc(), pos, old_finish, old_finish + mid_last_dist); this->members_.m_size += n_after - mid_last_dist; //Now copy the part of new_end over constructed elements interf.copy_remaining_to(pos); } } } } template void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag) { //Overwrite all elements we can from [first, last) iterator cur = begin(); for ( ; first != last && cur != end(); ++cur, ++first){ *cur = *first; } if (first == last){ //There are no more elements in the sequence, erase remaining this->erase(cur, cend()); } else{ //There are more elements in the range, insert the remaining ones this->insert(this->cend(), first, last); } } template void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag) { size_type n = std::distance(first, last); if(!n){ this->prot_destroy_all(); return; } //Check if we have enough memory or try to expand current memory size_type remaining = this->members_.m_capacity - this->members_.m_size; bool same_buffer_start; std::pair ret; size_type real_cap = this->members_.m_capacity; if (n <= remaining){ same_buffer_start = true; } else{ //There is not enough memory, allocate a new buffer size_type new_cap = this->next_capacity(n); ret = this->allocation_command (allocate_new | expand_fwd | expand_bwd, this->size() + n, new_cap, real_cap, this->members_.m_start); same_buffer_start = ret.second && this->members_.m_start == ret.first; if(same_buffer_start){ this->members_.m_capacity = real_cap; } } if(same_buffer_start){ T *start = container_detail::to_raw_pointer(this->members_.m_start); if (this->size() >= n){ //There is memory, but there are more old elements than new ones //Overwrite old elements with new ones std::copy(first, last, start); //Destroy remaining old elements this->destroy_n(start + n, this->members_.m_size - n); this->members_.m_size = n; } else{ //There is memory, but there are less old elements than new ones //First overwrite some old elements with new ones FwdIt mid = first; std::advance(mid, this->size()); // iG T *end = std::copy(first, mid, start); T *end = std::copy(first, mid, start); //Initialize the remaining new elements in the uninitialized memory ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), mid, last, end); this->members_.m_size = n; } } else if(!ret.second){ typename value_traits::ArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap); ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), first, last, container_detail::to_raw_pointer(ret.first)); scoped_alloc.release(); //Destroy and deallocate old buffer if(this->members_.m_start != 0){ this->destroy_n(container_detail::to_raw_pointer(this->members_.m_start), this->members_.m_size); this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); } this->members_.m_start = ret.first; this->members_.m_size = n; this->members_.m_capacity = real_cap; } else{ //Backwards expansion //If anything goes wrong, this object will destroy old objects T *old_start = container_detail::to_raw_pointer(this->members_.m_start); size_type old_size = this->members_.m_size; typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size); //If something goes wrong size will be 0 //but holding the whole buffer this->members_.m_size = 0; this->members_.m_start = ret.first; this->members_.m_capacity = real_cap; //Backup old buffer data size_type old_offset = old_start - container_detail::to_raw_pointer(ret.first); size_type first_count = container_detail::min_value(n, old_offset); FwdIt mid = first; std::advance(mid, first_count); ::boost::container::uninitialized_copy_or_move_alloc (this->alloc(), first, mid, container_detail::to_raw_pointer(ret.first)); if(old_offset > n){ //All old elements will be destroyed by "old_values_destroyer" this->members_.m_size = n; } else{ //We have constructed objects from the new begin until //the old end so release the rollback destruction old_values_destroyer.release(); this->members_.m_start = ret.first; this->members_.m_size = first_count + old_size; //Now overwrite the old values size_type second_count = container_detail::min_value(old_size, n - first_count); FwdIt mid2 = mid; std::advance(mid2, second_count); // iG std::copy(mid, mid2, old_start); std::copy(mid, mid2, old_start); //Check if we still have to append elements in the //uninitialized end if(second_count == old_size){ // iG std::copy(mid2, last, old_start + old_size); std::copy(mid2, last, old_start + old_size); } else{ //We have to destroy some old values this->destroy_n (old_start + second_count, old_size - second_count); this->members_.m_size = n; } this->members_.m_size = n; } } } template void priv_assign_dispatch(Integer n, Integer val, container_detail::true_) { this->assign((size_type) n, (value_type)val); } template void priv_assign_dispatch(InIt first, InIt last, container_detail::false_) { //Dispatch depending on integer/iterator typedef typename std::iterator_traits::iterator_category ItCat; this->priv_assign_aux(first, last, ItCat()); } template void priv_insert_dispatch(const_iterator pos, Integer n, Integer val, container_detail::true_) { this->insert(pos, (size_type)n, (T)val); } template void priv_insert_dispatch(const_iterator pos, InIt first, InIt last, container_detail::false_) { //Dispatch depending on integer/iterator typedef typename std::iterator_traits::iterator_category ItCat; this->priv_range_insert(pos, first, last, ItCat()); } void priv_check_range(size_type n) const { //If n is out of range, throw an out_of_range exception if (n >= size()) throw std::out_of_range("vector::at"); } /// @endcond }; template inline bool operator==(const vector& x, const vector& y) { //Check first size and each element if needed return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } template inline bool operator!=(const vector& x, const vector& y) { //Check first size and each element if needed return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin()); } template inline bool operator<(const vector& x, const vector& y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } template inline void swap(vector& x, vector& y) { x.swap(y); } }} /// @cond namespace boost { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations template struct has_trivial_destructor_after_move > { static const bool value = has_trivial_destructor::value; }; */ } /// @endcond ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// namespace cont = boost::container; typedef cont::multimap Map; typedef Map::const_iterator T; typedef cont::vector V; void f() { V v; T t = T(); v.push_back(t); }