Index: config/linker-map.gnu =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/config/linker-map.gnu,v retrieving revision 1.46 diff -c -3 -p -r1.46 linker-map.gnu *** config/linker-map.gnu 30 Jul 2003 15:01:58 -0000 1.46 --- config/linker-map.gnu 13 Aug 2003 18:42:33 -0000 *************** GLIBCXX_3.4 { *** 57,63 **** std::__num_base::_S_atoms_out; std::__moneypunct_cache*; std::__numpunct_cache*; ! std::__timepunct_cache* }; # Names not in an 'extern' block are mangled names. --- 57,66 ---- std::__num_base::_S_atoms_out; std::__moneypunct_cache*; std::__numpunct_cache*; ! std::__timepunct_cache*; ! __gnu_debug::_Safe_iterator_base*; ! __gnu_debug::_Safe_sequence_base*; ! __gnu_debug::_Error_formatter* }; # Names not in an 'extern' block are mangled names. Index: docs/html/17_intro/howto.html =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/docs/html/17_intro/howto.html,v retrieving revision 1.30 diff -c -3 -p -r1.30 howto.html *** docs/html/17_intro/howto.html 28 Jul 2003 04:13:58 -0000 1.30 --- docs/html/17_intro/howto.html 13 Aug 2003 18:42:33 -0000 *************** *** 339,344 **** --- 339,356 ---- violations of the requirements of the standard. This is described in more detail here. +
_GLIBCXX_DEBUG
+
Undefined by default. Configurable. When defined, compiles + user code using the libstdc++ debug + mode. +
+
_GLIBCXX_DEBUG_PEDANTIC
+
Undefined by default. Configurable. When defined while + compiling with the libstdc++ debug + mode, makes the debug mode extremely picky by making the use + of libstdc++ extensions and libstdc++-specific behavior into + errors. +
+ +
+

Debug mode design

+

The libstdc++ debug mode replaces unsafe (but efficient) standard + containers and iterators with semantically equivalent safe standard + containers and iterators to aid in debugging user programs. The + following goals directed the design of the libstdc++ debug mode:

+ + + +

Other implementations

+

There are several existing implementations of debug modes for C++ + standard library implementations, although none of them directly + supports debugging for programs using libstdc++. The existing + implementations include:

+ + +

Debug mode design methodology

+

This section provides an overall view of the design of the + libstdc++ debug mode and details the relationship between design + decisions and the stated design goals.

+ +

The wrapper model

+

The libstdc++ debug mode uses a wrapper model where the debugging + versions of library components (e.g., iterators and containers) form + a layer on top of the release versions of the library + components. The debugging components first verify that the operation + is correct (aborting with a diagnostic if an error is found) and + will then forward to the underlying release-mode container that will + perform the actual work. This design decision ensures that we cannot + regress release-mode performance (because the release-mode + containers are left untouched) and partially enables mixing debug and release code at link time, + although that will not be discussed at this time.

+ +

Two types of wrappers are used in the implementation of the debug + mode: container wrappers and iterator wrappers. The two types of + wrappers interact to maintain relationships between iterators and + their associated containers, which are necessary to detect certain + types of standard library usage errors such as dereferencing + past-the-end iterators or inserting into a container using an + iterator from a different container.

+ +

Safe iterators

+

Iterator wrappers provide a debugging layer over any iterator that + is attached to a particular container, and will manage the + information detailing the iterator's state (singular, + dereferenceable, etc.) and tracking the container to which the + iterator is attached. Because iterators have a well-defined, common + interface the iterator wrapper is implemented with the iterator + adaptor class template __gnu_debug::_Safe_iterator, + which takes two template parameters:

+ + + +

Safe sequences (containers)

+

Container wrappers provide a debugging layer over a particular + container type. Because containers vary greatly in the member + functions they support and the semantics of those member functions + (especially in the area of iterator invalidation), container + wrappers are tailored to the container they reference, e.g., the + debugging version of std::list duplicates the entire + interface of std::list, adding additional semantic + checks and then forwarding operations to the + real std::list (a public base class of the debugging + version) as appropriate. However, all safe containers inherit from + the class template __gnu_debug::_Safe_sequence, + instantiated with the type of the safe container itself (an instance + of the curiously recurring template pattern).

+ +

The iterators of a container wrapper will be + safe iterators that reference sequences + of this type and wrap the iterators provided by the release-mode + base class. The debugging container will use only the safe + iterators within its own interface (therefore requiring the user to + use safe iterators, although this does not change correct user + code) and will communicate with the release-mode base class with + only the underlying, unsafe, release-mode iterators that the base + class exports.

+ +

The debugging version of std::list will have the + following basic structure:

+ +
+ template<typename _Tp, typename _Allocator = std::allocator<_Tp>
+   class debug-list :
+     public release-list<_Tp, _Allocator>,
+     public __gnu_debug::_Safe_sequence<debug-list<_Tp, _Allocator> >
+   {
+     typedef release-list<_Tp, _Allocator> _Base;
+     typedef debug-list<_Tp, _Allocator>   _Self;
+ 
+   public:
+     typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, _Self>       iterator;
+     typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, _Self> const_iterator;
+ 
+     // duplicate std::list interface with debugging semantics
+   };
+ 
+ +

Precondition checking

+

The debug mode operates primarily by checking the preconditions of + all standard library operations that it supports. Preconditions that + are always checked (regardless of whether or not we are in debug + mode) are checked via the __check_xxx macros defined + and documented in the source + file include/debug/debug.h. Preconditions that may or + may not be checked, depending on the debug-mode + macro _GLIBCXX_DEBUG, are checked via + the __requires_xxx macros defined and documented in the + same source file. Preconditions are validated using any additional + information available at run-time, e.g., the containers that are + associated with a particular iterator, the position of the iterator + within those containers, the distance between two iterators that may + form a valid range, etc. In the absence of suitable information, + e.g., an input iterator that is not a safe iterator, these + precondition checks will silently succeed.

+ +

The majority of precondition checks use the aforementioned macros, + which have the secondary benefit of having prewritten debug + messages that use information about the current status of the + objects involved (e.g., whether an iterator is singular or what + sequence it is attached to) along with some static information + (e.g., the names of the function parameters corresponding to the + objects involved). When not using these macros, the debug mode uses + either the debug-mode assertion + macro _GLIBCXX_DEBUG_ASSERT , its pedantic + cousin _GLIBCXX_DEBUG_PEDASSERT, or the assertion + check macro that supports more advance formulation of error + messages, _GLIBCXX_DEBUG_VERIFY. These macros are + documented more thoroughly in the debug mode source code.

+ +

Release- and debug-mode coexistence

+

The libstdc++ debug mode is the first debug mode we know of that + is able to provide the "Per-use recompilation" (4) guarantee, that + allows release-compiled and debug-compiled code to be linked and + executed together without causing unpredictable behavior. This + guarantee minimizes the recompilation that users are required to + perform, shortening the detect-compile-debug bughunting cycle + and making the debug mode easier to incorporate into development + environments by minimizing dependencies.

+ +

Achieving link- and run-time coexistence is not a trivial + implementation task. To achieve this goal we required a small + extension to the GNU C++ compiler (described in the section on + link- and run-time coexistence) and complex + organization of debug- and release-modes. The end result is that we + have achieved per-use recompilation but have had to give up some + checking of the std::basic_string class template + (namely, safe iterators). + +

Compile-time coexistence of release- and + debug-mode components

+

Both the release-mode components and the debug-mode + components need to exist within a single translation unit so that + the debug versions can wrap the release versions. However, only one + of these components should be user-visible at any particular + time with the standard name, e.g., std::list. In + release mode, we define only the release-mode version of the + component with its standard name and do not include the debugging + component at all (except, perhaps, in __gnu_debug, if + requested via the separate debugging headers). This method leaves the + behavior of release mode completely unchanged from its behavior + prior to the introduction of the libstdc++ debug mode.

+ +

In debug mode we include the release-mode container into its + natural namespace but perform renaming to an implementation-defined + name using preprocessor macros. Thus the + release-mode std::list will be renamed + to std::_Release_list during debug mode, and we will + automatically include the debugging version with the + name std::list for users to reference. This method + allows the debug- and release-mode versions of the same component to + coexist at compile-time without causing an unreasonable maintenance + burden.

+ +

Link- and run-time coexistence of release- and + debug-mode components

+

There is a problem with the simple compile-time coexistence + mechanism: if a user compiles some modules with release mode and + some modules with debug mode, the debuggable components will differ + in different translation units, violating the C++ One Definition + Rule (ODR). This violation will likely be detected at link time, + because the sizes of debug-mode containers will differ from the + sizes of release-mode containers, although in some cases (such as + dynamic linking) the error may be detected much later (or not at + all!).

+ +

Unfortunately, it is not possible to avoid violating the ODR with + most debug mode designs (see the section on alternatives for coexistence), so the + philosophy of the libstdc++ debug mode is to acknowledge that there + is an unavoidable ODR violation in this case but to ensure that the + ODR violation does not affect execution. To accomplish this, the + libstdc++ debug mode uses the aforementioned preprocessor renaming + scheme but includes an additional renaming scheme that happens at + compile-time that essentially reverses the preprocessor + renaming from the linker's point of view. Thus, in debug + mode, the release-mode list container is + named std::_Release_list but will be mangled with the + name std::list (as it was in release mode). Similarly, + the debug-mode list is named std::list + (in debug mode) but will be mangled + as std::_Debug_list. Thus the + release-mode list always compiles down to code that + uses the name std::list, and the + debug-mode list always compiles down to code that uses + the name std::_Debug_list, independent of the use of + debug mode. This has several positive effects:

+ + + +

The new link_name class attribute facilities + renaming. It may be attached to any class type (or any class + template) to override the name of the class used for name + mangling. For instance, a class named bar would + generally mangle as 3bar; if the class has + a link_name attribute that specifies the string + "wibble", then it would mangle as 6wibble.

+ +

Note that although we have hidden the ODR violation, it still + exists. For this reason we cannot easily provide safe iterators for + the std::basic_string class template, as it is present + throughout the C++ standard library. For instance, locale facets + define typedefs that include basic_string: in a mixed + debug/release program, should that typedef be based on the + debug-mode basic_string or the + release-mode basic_string? While the answer could be + "both", and the difference hidden via renaming a la the + debug/release containers, we must note two things about locale + facets:

+ +
    +
  1. They exist as shared state: one can create a facet in one + translation unit and access the facet via the same type name in a + different translation unit. This means that we cannot have two + different versions of locale facets, because the types would not be + the same across debug/release-mode translation unit barriers.
  2. + +
  3. They have virtual functions returning strings: these functions + mangle in the same way regardless of the mangling of their return + types (see above), and their precise signatures can be relied upon + by users because they may be overridden in derived classes. +
+ +

With the design of libstdc++ debug mode, we cannot effectively hide + the differences between debug and release-mode strings from the + user. Failure to hide the differences may result in unpredictable + behavior, and for this reason we have opted to only + perform basic_string changes that do not require ABI + changes. The effect on users is expected to be minimal, as there are + simple alternatives (e.g., __gnu_debug::basic_string), + and the usability benefit we gain from the ability to mix debug- and + release-compiled translation units is enormous.

+ +

Alternatives for Coexistence

+

The coexistence scheme was chosen over many alternatives, + including language-only solutions and solutions that also required + extensions to the C++ front end. The following is a partial list of + solutions, with justifications for our rejection of each.

+ + + +

Other options may exist for implementing the debug mode, many of + which have probably been considered and others that may still be + lurking. This list may be expanded over time to include other + options that we could have implemented, but in all cases the full + ramifications of the approach (as measured against the design goals + for a libstdc++ debug mode) should be considered first. The DejaGNU + testsuite includes some testcases that check for known problems with + some solutions (e.g., the using declaration solution + that breaks user specialization), and additional testcases will be + added as we are able to identify other typical problem cases. These + test cases will serve as a benchmark by which we can compare debug + mode implementations.

+ + + +
+

+ See license.html for copying conditions. + Comments and suggestions are welcome, and may be sent to + the libstdc++ mailing list. +

+ + + + Index: docs/html/test.html =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/docs/html/test.html,v retrieving revision 1.5 diff -c -3 -p -r1.5 test.html *** docs/html/test.html 5 Aug 2003 01:20:15 -0000 1.5 --- docs/html/test.html 13 Aug 2003 18:42:33 -0000 *************** *** 34,39 **** --- 34,40 ----
  • Utilities: abicheck and libv3test
  • How to write a new test case
  • Options for running the tests
  • +
  • Running debug-mode tests
  • Future
  • DejaGNU internals
  • *************** make check-target-libstdc++-v3 RUNTESTFL *** 538,543 **** --- 539,557 ---- testsuite; please see FAQ 2.4 for which files to examine.

    + +
    +

    Running debug-mode tests

    +

    To run the libstdc++ test suite under the debug mode, + edit libstdc++/scripts/testsuite_flags to add the + compile-time flag -D_GLIBCXX_DEBUG to the result + printed by the --build-cxx option. Additionally, add + the -D_GLIBCXX_DEBUG_PEDANTIC flag to turn on pedantic + checking. The libstdc++ test suite should produce precisely the same + results under debug mode that it does under release mode: any + deviation indicates an error in either the library or the test + suite.


    Future

    Index: include/Makefile.am =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/Makefile.am,v retrieving revision 1.66 diff -c -3 -p -r1.66 Makefile.am *** include/Makefile.am 11 Aug 2003 13:56:38 -0000 1.66 --- include/Makefile.am 13 Aug 2003 18:42:33 -0000 *************** ext_headers = \ *** 233,239 **** ${ext_srcdir}/hash_fun.h \ ${ext_srcdir}/hashtable.h - # This is the common subset of files that all three "C" header models use. c_base_srcdir = @C_INCLUDE_DIR@ c_base_builddir = . --- 233,238 ---- *************** c_compatibility_headers = \ *** 299,304 **** --- 298,336 ---- ${c_compatibility_srcdir}/wchar.h \ ${c_compatibility_srcdir}/wctype.h + # Debug mode headers + debug_srcdir = ${glibcxx_srcdir}/include/debug + debug_builddir = ./debug + debug_headers = \ + ${debug_srcdir}/bitset \ + ${debug_srcdir}/dbg_bitset.h \ + ${debug_srcdir}/dbg_deque.h \ + ${debug_srcdir}/dbg_hash_map.h \ + ${debug_srcdir}/dbg_hash_multimap.h \ + ${debug_srcdir}/dbg_hash_multiset.h \ + ${debug_srcdir}/dbg_hash_set.h \ + ${debug_srcdir}/dbg_list.h \ + ${debug_srcdir}/dbg_map.h \ + ${debug_srcdir}/dbg_multimap.h \ + ${debug_srcdir}/dbg_multiset.h \ + ${debug_srcdir}/dbg_set.h \ + ${debug_srcdir}/dbg_vector.h \ + ${debug_srcdir}/debug.h \ + ${debug_srcdir}/deque \ + ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/hash_map \ + ${debug_srcdir}/hash_set \ + ${debug_srcdir}/list \ + ${debug_srcdir}/map \ + ${debug_srcdir}/safe_base.h \ + ${debug_srcdir}/safe_iterator.h \ + ${debug_srcdir}/safe_iterator.tcc \ + ${debug_srcdir}/safe_sequence.h \ + ${debug_srcdir}/set \ + ${debug_srcdir}/string \ + ${debug_srcdir}/support.h \ + ${debug_srcdir}/vector + # Some of the different "C" header models need extra files. # Some "C" header schemes require the "C" compatibility headers. # For --enable-cheaders=c_std *************** endif *** 360,366 **** # CLEANFILES and all-local are kept up-to-date. allstamped = \ stamp-std stamp-bits stamp-c_base stamp-c_compatibility \ ! stamp-backward stamp-ext stamp-host # List of all files that are created by explicit building, editing, or # catenation. --- 392,398 ---- # CLEANFILES and all-local are kept up-to-date. allstamped = \ stamp-std stamp-bits stamp-c_base stamp-c_compatibility \ ! stamp-backward stamp-ext stamp-debug stamp-host # List of all files that are created by explicit building, editing, or # catenation. *************** stamp-ext: ${ext_headers} *** 439,444 **** --- 471,483 ---- echo `date` > stamp-ext ;\ fi + stamp-debug: ${debug_headers} + @if [ ! -d "${debug_builddir}" ]; then \ + mkdir -p ${debug_builddir} ;\ + fi ;\ + (cd ${debug_builddir} && @LN_S@ $? . || true) ;\ + echo `date` > stamp-debug + stamp-${host_alias}: @if [ ! -d ${host_builddir} ]; then \ mkdir -p ${host_builddir} ;\ *************** install-headers: *** 547,552 **** --- 586,594 ---- $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} for file in ${std_headers_rename}; do \ $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${debug_builddir} + for file in ${debug_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${debug_builddir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${host_builddir} for file in ${host_headers} ${host_headers_extra} \ ${thread_host_headers}; do \ Index: include/bits/basic_string.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/basic_string.h,v retrieving revision 1.38 diff -c -3 -p -r1.38 basic_string.h *** include/bits/basic_string.h 22 Jul 2003 17:57:50 -0000 1.38 --- include/bits/basic_string.h 13 Aug 2003 18:42:33 -0000 *************** *** 43,48 **** --- 43,49 ---- #pragma GCC system_header #include + #include namespace std { *************** namespace std *** 608,614 **** */ const_reference operator[] (size_type __pos) const ! { return _M_data()[__pos]; } /** * @brief Subscript access to the data contained in the %string. --- 609,618 ---- */ const_reference operator[] (size_type __pos) const ! { ! _GLIBCXX_DEBUG_ASSERT(__pos <= size()); ! return _M_data()[__pos]; ! } /** * @brief Subscript access to the data contained in the %string. *************** namespace std *** 623,628 **** --- 627,633 ---- reference operator[](size_type __pos) { + _GLIBCXX_DEBUG_ASSERT(__pos < size()); _M_leak(); return _M_data()[__pos]; } *************** namespace std *** 729,735 **** */ basic_string& append(const _CharT* __s) ! { return this->append(__s, traits_type::length(__s)); } /** * @brief Append multiple characters. --- 734,743 ---- */ basic_string& append(const _CharT* __s) ! { ! __glibcxx_requires_string(__s); ! return this->append(__s, traits_type::length(__s)); ! } /** * @brief Append multiple characters. *************** namespace std *** 810,816 **** */ basic_string& assign(const _CharT* __s) ! { return this->assign(__s, traits_type::length(__s)); } /** * @brief Set value to multiple characters. --- 818,827 ---- */ basic_string& assign(const _CharT* __s) ! { ! __glibcxx_requires_string(__s); ! return this->assign(__s, traits_type::length(__s)); ! } /** * @brief Set value to multiple characters. *************** namespace std *** 942,948 **** */ basic_string& insert(size_type __pos, const _CharT* __s) ! { return this->insert(__pos, __s, traits_type::length(__s)); } /** * @brief Insert multiple characters. --- 953,962 ---- */ basic_string& insert(size_type __pos, const _CharT* __s) ! { ! __glibcxx_requires_string(__s); ! return this->insert(__pos, __s, traits_type::length(__s)); ! } /** * @brief Insert multiple characters. *************** namespace std *** 983,988 **** --- 997,1003 ---- iterator insert(iterator __p, _CharT __c) { + _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); const size_type __pos = __p - _M_ibegin(); this->insert(_M_check(__pos), size_type(1), __c); _M_rep()->_M_set_leaked(); *************** namespace std *** 1043,1048 **** --- 1058,1065 ---- iterator erase(iterator __position) { + _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() + && __position < _M_iend()); const size_type __i = __position - _M_ibegin(); this->replace(__position, __position + 1, _M_data(), _M_data()); _M_rep()->_M_set_leaked(); *************** namespace std *** 1064,1069 **** --- 1081,1088 ---- iterator erase(iterator __first, iterator __last) { + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); const size_type __i = __first - _M_ibegin(); this->replace(__first, __last, _M_data(), _M_data()); _M_rep()->_M_set_leaked(); *************** namespace std *** 1150,1156 **** */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s) ! { return this->replace(__pos, __n1, __s, traits_type::length(__s)); } /** * @brief Replace characters with multiple characters. --- 1169,1178 ---- */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s) ! { ! __glibcxx_requires_string(__s); ! return this->replace(__pos, __n1, __s, traits_type::length(__s)); ! } /** * @brief Replace characters with multiple characters. *************** namespace std *** 1187,1193 **** */ basic_string& replace(iterator __i1, iterator __i2, const basic_string& __str) ! { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } /** * @brief Replace range of characters with C substring. --- 1209,1219 ---- */ basic_string& replace(iterator __i1, iterator __i2, const basic_string& __str) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! return this->replace(__i1, __i2, __str._M_data(), __str.size()); ! } /** * @brief Replace range of characters with C substring. *************** namespace std *** 1205,1211 **** */ basic_string& replace(iterator __i1, iterator __i2, ! const _CharT* __s, size_type __n) { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); } /** --- 1231,1237 ---- */ basic_string& replace(iterator __i1, iterator __i2, ! const _CharT* __s, size_type __n) { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); } /** *************** namespace std *** 1223,1229 **** */ basic_string& replace(iterator __i1, iterator __i2, const _CharT* __s) ! { return this->replace(__i1, __i2, __s, traits_type::length(__s)); } /** * @brief Replace range of characters with multiple characters --- 1249,1260 ---- */ basic_string& replace(iterator __i1, iterator __i2, const _CharT* __s) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! __glibcxx_requires_string(__s); ! return this->replace(__i1, __i2, __s, traits_type::length(__s)); ! } /** * @brief Replace range of characters with multiple characters *************** namespace std *** 1241,1247 **** */ basic_string& replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) ! { return _M_replace_aux(__i1, __i2, __n, __c); } /** * @brief Replace range of characters with range. --- 1272,1282 ---- */ basic_string& replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! return _M_replace_aux(__i1, __i2, __n, __c); ! } /** * @brief Replace range of characters with range. *************** namespace std *** 1261,1290 **** basic_string& replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2) ! { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; ! return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); } // Specializations for the common case of pointer and iterator: // useful to avoid the overhead of temporary buffering in _M_replace. basic_string& ! replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) ! { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, ! __k1, __k2 - __k1); } basic_string& ! replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2) ! { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, ! __k1, __k2 - __k1); } basic_string& ! replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) ! { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } basic_string& ! replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2) ! { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } --- 1296,1350 ---- basic_string& replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! __glibcxx_requires_valid_range(__k1, __k2); ! typedef typename _Is_integer<_InputIterator>::_Integral _Integral; ! return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); ! } // Specializations for the common case of pointer and iterator: // useful to avoid the overhead of temporary buffering in _M_replace. basic_string& ! replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! __glibcxx_requires_valid_range(__k1, __k2); ! return this->replace(__i1 - _M_ibegin(), __i2 - __i1, ! __k1, __k2 - __k1); ! } basic_string& ! replace(iterator __i1, iterator __i2, ! const _CharT* __k1, const _CharT* __k2) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! __glibcxx_requires_valid_range(__k1, __k2); ! return this->replace(__i1 - _M_ibegin(), __i2 - __i1, ! __k1, __k2 - __k1); ! } basic_string& ! replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! __glibcxx_requires_valid_range(__k1, __k2); ! return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } basic_string& ! replace(iterator __i1, iterator __i2, ! const_iterator __k1, const_iterator __k2) ! { ! _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 ! && __i2 <= _M_iend()); ! __glibcxx_requires_valid_range(__k1, __k2); ! return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } *************** namespace std *** 1459,1465 **** */ size_type find(const _CharT* __s, size_type __pos = 0) const ! { return this->find(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. --- 1519,1528 ---- */ size_type find(const _CharT* __s, size_type __pos = 0) const ! { ! __glibcxx_requires_string(__s); ! return this->find(__s, __pos, traits_type::length(__s)); ! } /** * @brief Find position of a character. *************** namespace std *** 1514,1520 **** */ size_type rfind(const _CharT* __s, size_type __pos = npos) const ! { return this->rfind(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. --- 1577,1586 ---- */ size_type rfind(const _CharT* __s, size_type __pos = npos) const ! { ! __glibcxx_requires_string(__s); ! return this->rfind(__s, __pos, traits_type::length(__s)); ! } /** * @brief Find last position of a character. *************** namespace std *** 1569,1575 **** */ size_type find_first_of(const _CharT* __s, size_type __pos = 0) const ! { return this->find_first_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. --- 1635,1644 ---- */ size_type find_first_of(const _CharT* __s, size_type __pos = 0) const ! { ! __glibcxx_requires_string(__s); ! return this->find_first_of(__s, __pos, traits_type::length(__s)); ! } /** * @brief Find position of a character. *************** namespace std *** 1627,1633 **** */ size_type find_last_of(const _CharT* __s, size_type __pos = npos) const ! { return this->find_last_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. --- 1696,1705 ---- */ size_type find_last_of(const _CharT* __s, size_type __pos = npos) const ! { ! __glibcxx_requires_string(__s); ! return this->find_last_of(__s, __pos, traits_type::length(__s)); ! } /** * @brief Find last position of a character. *************** namespace std *** 1686,1692 **** */ size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const ! { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a different character. --- 1758,1767 ---- */ size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const ! { ! __glibcxx_requires_string(__s); ! return this->find_first_not_of(__s, __pos, traits_type::length(__s)); ! } /** * @brief Find position of a different character. *************** namespace std *** 1742,1748 **** */ size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const ! { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a different character. --- 1817,1826 ---- */ size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const ! { ! __glibcxx_requires_string(__s); ! return this->find_last_not_of(__s, __pos, traits_type::length(__s)); ! } /** * @brief Find last position of a different character. Index: include/bits/basic_string.tcc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/basic_string.tcc,v retrieving revision 1.41 diff -c -3 -p -r1.41 basic_string.tcc *** include/bits/basic_string.tcc 5 Jul 2003 04:05:34 -0000 1.41 --- include/bits/basic_string.tcc 13 Aug 2003 18:42:34 -0000 *************** *** 45,50 **** --- 45,60 ---- namespace std { + template + inline bool + __is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template + inline bool + __is_null_pointer(const _Type&) + { return false; } + template const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: *************** namespace std *** 141,148 **** if (__beg == __end && __a == _Alloc()) return _S_empty_rep()._M_refdata(); ! // NB: Not required, but considered best practice. ! if (__builtin_expect(__beg == _InIterator(), 0)) __throw_logic_error("basic_string::_S_construct NULL not valid"); const size_type __dnew = static_cast(std::distance(__beg, __end)); --- 151,158 ---- if (__beg == __end && __a == _Alloc()) return _S_empty_rep()._M_refdata(); ! // NB: Not required, but considered best practice. ! if (__builtin_expect(std::__is_null_pointer(__beg), 0)) __throw_logic_error("basic_string::_S_construct NULL not valid"); const size_type __dnew = static_cast(std::distance(__beg, __end)); *************** namespace std *** 215,226 **** --- 225,238 ---- __str._M_fold(__pos, __n), __a), __a) { } + // TBD: DPG annotate template basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) { } + // TBD: DPG annotate template basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _CharT* __s, const _Alloc& __a) *************** namespace std *** 233,239 **** basic_string(size_type __n, _CharT __c, const _Alloc& __a) : _M_dataplus(_S_construct(__n, __c, __a), __a) { } ! template template basic_string<_CharT, _Traits, _Alloc>:: --- 245,252 ---- basic_string(size_type __n, _CharT __c, const _Alloc& __a) : _M_dataplus(_S_construct(__n, __c, __a), __a) { } ! ! // TBD: DPG annotate template template basic_string<_CharT, _Traits, _Alloc>:: *************** namespace std *** 275,280 **** --- 288,294 ---- basic_string<_CharT, _Traits, _Alloc>:: assign(const _CharT* __s, size_type __n) { + __glibcxx_requires_string_len(__s, __n); if (__n > this->max_size()) __throw_length_error("basic_string::assign"); if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) *************** namespace std *** 313,318 **** --- 327,333 ---- basic_string<_CharT, _Traits, _Alloc>:: insert(size_type __pos, const _CharT* __s, size_type __n) { + __glibcxx_requires_string_len(__s, __n); const size_type __size = this->size(); if (__pos > __size) __throw_out_of_range("basic_string::insert"); *************** namespace std *** 350,355 **** --- 365,371 ---- replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) { + __glibcxx_requires_string_len(__s, __n2); const size_type __size = this->size(); if (__pos > __size) __throw_out_of_range("basic_string::replace"); *************** namespace std *** 730,735 **** --- 746,752 ---- basic_string<_CharT, _Traits, _Alloc>:: append(const _CharT* __s, size_type __n) { + __glibcxx_requires_string_len(__s, __n); const size_type __len = __n + this->size(); if (__len > this->capacity()) this->reserve(__len); *************** namespace std *** 752,757 **** --- 769,775 ---- operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { + __glibcxx_requires_string(__lhs); typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; const __size_type __len = _Traits::length(__lhs); *************** namespace std *** 786,791 **** --- 804,811 ---- if (__n > this->size() - __pos) __n = this->size() - __pos; + + __glibcxx_requires_string_len(__s, __n); traits_type::copy(__s, _M_data() + __pos, __n); // 21.3.5.7 par 3: do not append null. (good.) *************** namespace std *** 797,802 **** --- 817,824 ---- basic_string<_CharT, _Traits, _Alloc>:: find(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); size_t __xpos = __pos; const _CharT* __data = _M_data(); *************** namespace std *** 830,835 **** --- 852,859 ---- basic_string<_CharT, _Traits, _Alloc>:: rfind(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); if (__n <= __size) { *************** namespace std *** 869,874 **** --- 893,900 ---- basic_string<_CharT, _Traits, _Alloc>:: find_first_of(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); + for (; __n && __pos < this->size(); ++__pos) { const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); *************** namespace std *** 883,888 **** --- 909,916 ---- basic_string<_CharT, _Traits, _Alloc>:: find_last_of(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); if (__size && __n) { *************** namespace std *** 903,908 **** --- 931,938 ---- basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); + size_t __xpos = __pos; for (; __xpos < this->size(); ++__xpos) if (!traits_type::find(__s, __n, _M_data()[__xpos])) *************** namespace std *** 927,932 **** --- 957,964 ---- basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); if (__size) { *************** namespace std *** 1007,1012 **** --- 1039,1046 ---- basic_string<_CharT, _Traits, _Alloc>:: compare(const _CharT* __s) const { + __glibcxx_requires_string(__s); + const size_type __size = this->size(); const size_type __osize = traits_type::length(__s); const size_type __len = std::min(__size, __osize); *************** namespace std *** 1022,1027 **** --- 1056,1063 ---- basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos, size_type __n1, const _CharT* __s) const { + __glibcxx_requires_string(__s); + const size_type __size = this->size(); if (__pos > __size) __throw_out_of_range("basic_string::compare"); *************** namespace std *** 1041,1046 **** --- 1077,1084 ---- compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const { + __glibcxx_requires_string_len(__s, __n2); + const size_type __size = this->size(); if (__pos > __size) __throw_out_of_range("basic_string::compare"); Index: include/bits/deque.tcc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/deque.tcc,v retrieving revision 1.10 diff -c -3 -p -r1.10 deque.tcc *** include/bits/deque.tcc 14 Jul 2003 02:52:04 -0000 1.10 --- include/bits/deque.tcc 13 Aug 2003 18:42:34 -0000 *************** *** 61,66 **** --- 61,70 ---- #ifndef _DEQUE_TCC #define _DEQUE_TCC 1 + #ifdef _GLIBCXX_DEBUG + # define deque _Release_deque + #endif + namespace std { template *************** namespace std *** 708,712 **** --- 712,720 ---- this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef deque + #endif #endif Index: include/bits/list.tcc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/list.tcc,v retrieving revision 1.7 diff -c -3 -p -r1.7 list.tcc *** include/bits/list.tcc 6 Jul 2003 00:58:52 -0000 1.7 --- include/bits/list.tcc 13 Aug 2003 18:42:34 -0000 *************** *** 61,66 **** --- 61,70 ---- #ifndef _LIST_TCC #define _LIST_TCC 1 + #ifdef _GLIBCXX_DEBUG + # define list _Release_list + #endif + namespace std { template *************** namespace std *** 399,403 **** --- 403,411 ---- } } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef list + #endif #endif /* _LIST_TCC */ Index: include/bits/stl_algo.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_algo.h,v retrieving revision 1.35 diff -c -3 -p -r1.35 stl_algo.h *** include/bits/stl_algo.h 15 Jul 2003 07:30:19 -0000 1.35 --- include/bits/stl_algo.h 13 Aug 2003 18:42:35 -0000 *************** *** 63,74 **** #include #include // for _Temporary_buffer // See concept_check.h for the __glibcxx_*_requires macros. namespace std { - /** * @brief Find the median of three values. * @param a A value. --- 63,74 ---- #include #include // for _Temporary_buffer + #include // See concept_check.h for the __glibcxx_*_requires macros. namespace std { /** * @brief Find the median of three values. * @param a A value. *************** namespace std *** 153,158 **** --- 153,159 ---- { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __f(*__first); return __f; *************** namespace std *** 295,300 **** --- 296,302 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); return std::find(__first, __last, __val, std::__iterator_category(__first)); } *************** namespace std *** 315,320 **** --- 317,323 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); return std::find_if(__first, __last, __pred, std::__iterator_category(__first)); } *************** namespace std *** 334,339 **** --- 337,343 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __last; _ForwardIterator __next = __first; *************** namespace std *** 365,370 **** --- 369,375 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __last; _ForwardIterator __next = __first; *************** namespace std *** 393,398 **** --- 398,404 ---- __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator>::value_type >) __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); typename iterator_traits<_InputIterator>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (*__first == __value) *************** namespace std *** 416,421 **** --- 422,428 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); typename iterator_traits<_InputIterator>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (__pred(*__first)) *************** namespace std *** 458,464 **** __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) ! // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; --- 465,472 ---- __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) ! __glibcxx_requires_valid_range(__first1, __last1); ! __glibcxx_requires_valid_range(__first2, __last2); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; *************** namespace std *** 531,536 **** --- 539,546 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) *************** namespace std *** 603,608 **** --- 613,619 ---- __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); if (__count <= 0) return __first; *************** namespace std *** 651,656 **** --- 662,668 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); if (__count <= 0) return __first; *************** namespace std *** 708,713 **** --- 720,726 ---- __glibcxx_function_requires(_ConvertibleConcept< typename iterator_traits<_ForwardIterator2>::value_type, typename iterator_traits<_ForwardIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) std::iter_swap(__first1, __first2); *************** namespace std *** 739,744 **** --- 752,758 ---- __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _UnaryOperation" __typeof__(__unary_op(*__first))>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first, ++__result) *__result = __unary_op(*__first); *************** namespace std *** 775,780 **** --- 789,795 ---- __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _BinaryOperation" __typeof__(__binary_op(*__first1,*__first2))>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) *__result = __binary_op(*__first1, *__first2); *************** namespace std *** 804,809 **** --- 819,825 ---- typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_function_requires(_ConvertibleConcept<_Tp, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (*__first == __old_value) *************** namespace std *** 833,838 **** --- 849,855 ---- typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (__pred(*__first)) *************** namespace std *** 865,870 **** --- 882,888 ---- typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first, ++__result) *__result = *__first == __old_value ? __new_value : *__first; *************** namespace std *** 898,903 **** --- 916,922 ---- typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first, ++__result) *__result = __pred(*__first) ? __new_value : *__first; *************** namespace std *** 923,928 **** --- 942,948 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_GeneratorConcept<_Generator, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) *__first = __gen(); *************** namespace std *** 977,982 **** --- 997,1003 ---- typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (!(*__first == __value)) { *************** namespace std *** 1011,1016 **** --- 1032,1038 ---- typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (!__pred(*__first)) { *************** namespace std *** 1047,1052 **** --- 1069,1075 ---- typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); __first = std::find(__first, __last, __value); _ForwardIterator __i = __first; *************** namespace std *** 1079,1084 **** --- 1102,1108 ---- __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); __first = std::find_if(__first, __last, __pred); _ForwardIterator __i = __first; *************** namespace std *** 1207,1212 **** --- 1231,1237 ---- typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); typedef typename iterator_traits<_OutputIterator>::iterator_category _IterType; *************** namespace std *** 1239,1244 **** --- 1264,1270 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); typedef typename iterator_traits<_OutputIterator>::iterator_category _IterType; *************** namespace std *** 1267,1272 **** --- 1293,1299 ---- __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); __first = std::adjacent_find(__first, __last); return std::unique_copy(__first, __last, __first); *************** namespace std *** 1296,1301 **** --- 1323,1329 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); __first = std::adjacent_find(__first, __last, __binary_pred); return std::unique_copy(__first, __last, __first, __binary_pred); *************** namespace std *** 1352,1357 **** --- 1380,1386 ---- // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) + __glibcxx_requires_valid_range(__first, __last); std::__reverse(__first, __last, std::__iterator_category(__first)); } *************** namespace std *** 1379,1384 **** --- 1408,1414 ---- __glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); while (__first != __last) { --__last; *************** namespace std *** 1563,1568 **** --- 1593,1600 ---- { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); typedef typename iterator_traits<_ForwardIterator>::iterator_category _IterType; std::__rotate(__first, __middle, __last, _IterType()); *************** namespace std *** 1594,1599 **** --- 1626,1633 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); return std::copy(__first, __middle, copy(__middle, __last, __result)); } *************** namespace std *** 1637,1642 **** --- 1671,1677 ---- // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return; for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) *************** namespace std *** 1664,1669 **** --- 1699,1705 ---- // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return; for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) *************** namespace std *** 1753,1758 **** --- 1789,1795 ---- __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); return std::__partition(__first, __last, __pred, std::__iterator_category(__first)); } *************** namespace std *** 1853,1858 **** --- 1890,1896 ---- __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __first; *************** namespace std *** 2119,2124 **** --- 2157,2164 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); std::make_heap(__first, __middle); for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) *************** namespace std *** 2159,2164 **** --- 2199,2206 ---- _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); std::make_heap(__first, __middle, __comp); for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) *************** namespace std *** 2199,2204 **** --- 2241,2248 ---- __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>) __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) __glibcxx_function_requires(_LessThanComparableConcept<_InputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); if (__result_first == __result_last) return __result_last; _RandomAccessIterator __result_real_last = __result_first; *************** namespace std *** 2255,2260 **** --- 2299,2306 ---- __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _OutputValueType, _OutputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); if (__result_first == __result_last) return __result_last; _RandomAccessIterator __result_real_last = __result_first; *************** namespace std *** 2355,2360 **** --- 2401,2407 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first != __last) { std::__introsort_loop(__first, __last, __lg(__last - __first) * 2); *************** namespace std *** 2386,2391 **** --- 2433,2439 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first != __last) { std::__introsort_loop(__first, __last, __lg(__last - __first) * 2, __comp); *************** namespace std *** 2418,2423 **** --- 2466,2472 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); _DistanceType __len = std::distance(__first, __last); _DistanceType __half; *************** namespace std *** 2463,2468 **** --- 2512,2518 ---- // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _Tp>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); _DistanceType __len = std::distance(__first, __last); _DistanceType __half; *************** namespace std *** 2505,2510 **** --- 2555,2561 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); _DistanceType __len = std::distance(__first, __last); _DistanceType __half; *************** namespace std *** 2550,2555 **** --- 2601,2607 ---- // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); _DistanceType __len = std::distance(__first, __last); _DistanceType __half; *************** namespace std *** 2735,2740 **** --- 2787,2794 ---- typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) { if (*__first2 < *__first1) { *************** namespace std *** 2788,2793 **** --- 2842,2849 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first2, *__first1)) { *************** namespace std *** 3150,3155 **** --- 3206,3213 ---- __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_sorted(__first, __middle); + __glibcxx_requires_sorted(__middle, __last); if (__first == __middle || __middle == __last) return; *************** namespace std *** 3203,3208 **** --- 3261,3268 ---- _BidirectionalIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>) + __glibcxx_requires_sorted_pred(__first, __middle, __comp); + __glibcxx_requires_sorted_pred(__middle, __last, __comp); if (__first == __middle || __middle == __last) return; *************** namespace std *** 3289,3294 **** --- 3349,3355 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); _Temporary_buffer<_RandomAccessIterator, _ValueType> buf(__first, __last); if (buf.begin() == 0) *************** namespace std *** 3326,3331 **** --- 3387,3393 ---- _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); _Temporary_buffer<_RandomAccessIterator, _ValueType> buf(__first, __last); if (buf.begin() == 0) *************** namespace std *** 3361,3366 **** --- 3423,3430 ---- // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); while (__last - __first > 3) { _RandomAccessIterator __cut = *************** namespace std *** 3405,3410 **** --- 3469,3476 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); while (__last - __first > 3) { _RandomAccessIterator __cut = *************** namespace std *** 3449,3454 **** --- 3515,3521 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); _DistanceType __len = std::distance(__first, __last); _DistanceType __half; *************** namespace std *** 3504,3509 **** --- 3571,3577 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _Tp>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); _DistanceType __len = std::distance(__first, __last); _DistanceType __half; *************** namespace std *** 3552,3557 **** --- 3620,3626 ---- __glibcxx_function_requires(_SameTypeConcept<_Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); _ForwardIterator __i = std::lower_bound(__first, __last, __val); return __i != __last && !(__val < *__i); *************** namespace std *** 3583,3588 **** --- 3652,3658 ---- typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); return __i != __last && !__comp(__val, *__i); *************** namespace std *** 3622,3627 **** --- 3692,3699 ---- typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) if (*__first2 < *__first1) *************** namespace std *** 3667,3672 **** --- 3739,3746 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first2, *__first1)) *************** namespace std *** 3712,3717 **** --- 3786,3793 ---- typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) { if (*__first1 < *__first2) { *************** namespace std *** 3768,3773 **** --- 3844,3851 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first1, *__first2)) { *************** namespace std *** 3820,3825 **** --- 3898,3905 ---- typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) if (*__first1 < *__first2) *************** namespace std *** 3872,3877 **** --- 3952,3959 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) *************** namespace std *** 3921,3926 **** --- 4003,4010 ---- typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) if (*__first1 < *__first2) { *************** namespace std *** 3976,3981 **** --- 4060,4067 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) { *************** namespace std *** 4024,4029 **** --- 4110,4117 ---- typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) if (*__first1 < *__first2) { *************** namespace std *** 4081,4086 **** --- 4169,4176 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) { *************** namespace std *** 4117,4122 **** --- 4207,4213 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __first; _ForwardIterator __result = __first; *************** namespace std *** 4144,4149 **** --- 4235,4241 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __first; _ForwardIterator __result = __first; *************** namespace std *** 4166,4171 **** --- 4258,4264 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __first; _ForwardIterator __result = __first; *************** namespace std *** 4193,4198 **** --- 4286,4292 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __first; _ForwardIterator __result = __first; *************** namespace std *** 4224,4229 **** --- 4318,4324 ---- __glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; *************** namespace std *** 4276,4281 **** --- 4371,4377 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_BidirectionalIterator>::value_type, typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; *************** namespace std *** 4324,4329 **** --- 4420,4426 ---- __glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; *************** namespace std *** 4376,4381 **** --- 4473,4479 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_BidirectionalIterator>::value_type, typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; *************** namespace std *** 4431,4436 **** --- 4529,4536 ---- __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); for ( ; __first1 != __last1; ++__first1) for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) *************** namespace std *** 4469,4474 **** --- 4569,4576 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_InputIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); for ( ; __first1 != __last1; ++__first1) for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) *************** namespace std *** 4629,4634 **** --- 4731,4738 ---- __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); return std::__find_end(__first1, __last1, __first2, __last2, std::__iterator_category(__first1), *************** namespace std *** 4674,4679 **** --- 4778,4785 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); return std::__find_end(__first1, __last1, __first2, __last2, std::__iterator_category(__first1), Index: include/bits/stl_algobase.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_algobase.h,v retrieving revision 1.26 diff -c -3 -p -r1.26 stl_algobase.h *** include/bits/stl_algobase.h 15 Jul 2003 07:30:19 -0000 1.26 --- include/bits/stl_algobase.h 13 Aug 2003 18:42:35 -0000 *************** *** 74,79 **** --- 74,80 ---- #include #include #include + #include namespace std { *************** namespace std *** 333,338 **** --- 334,340 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); typedef typename _Is_normal_iterator<_InputIterator>::_Normal __Normal; return std::__copy_ni1(__first, __last, __result, __Normal()); *************** namespace std *** 471,476 **** --- 473,479 ---- __glibcxx_function_requires(_ConvertibleConcept< typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type>) + __glibcxx_requires_valid_range(__first, __last); typedef typename _Is_normal_iterator<_BI1>::_Normal __Normal; return std::__copy_backward_input_normal_iterator(__first, __last, __result, *************** namespace std *** 495,500 **** --- 498,504 ---- { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) *__first = __value; *************** namespace std *** 527,532 **** --- 531,537 ---- inline void fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) { + __glibcxx_requires_valid_range(__first, __last); unsigned char __tmp = __c; std::memset(__first, __tmp, __last - __first); } *************** namespace std *** 534,539 **** --- 539,545 ---- inline void fill(signed char* __first, signed char* __last, const signed char& __c) { + __glibcxx_requires_valid_range(__first, __last); signed char __tmp = __c; std::memset(__first, static_cast(__tmp), __last - __first); } *************** namespace std *** 541,546 **** --- 547,553 ---- inline void fill(char* __first, char* __last, const char& __c) { + __glibcxx_requires_valid_range(__first, __last); char __tmp = __c; std::memset(__first, static_cast(__tmp), __last - __first); } *************** namespace std *** 594,599 **** --- 601,607 ---- typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); while (__first1 != __last1 && *__first1 == *__first2) { *************** namespace std *** 625,630 **** --- 633,639 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { *************** namespace std *** 655,660 **** --- 664,670 ---- __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) if (!(*__first1 == *__first2)) *************** namespace std *** 684,689 **** --- 694,700 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) if (!__binary_pred(*__first1, *__first2)) *************** namespace std *** 717,722 **** --- 728,735 ---- typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); for (;__first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) { *************** namespace std *** 749,754 **** --- 762,769 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); for ( ; __first1 != __last1 && __first2 != __last2 ; ++__first1, ++__first2) *************** namespace std *** 767,772 **** --- 782,790 ---- const unsigned char* __first2, const unsigned char* __last2) { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + const size_t __len1 = __last1 - __first1; const size_t __len2 = __last2 - __first2; const int __result = std::memcmp(__first1, __first2, std::min(__len1, __len2)); *************** namespace std *** 777,782 **** --- 795,803 ---- lexicographical_compare(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + #if CHAR_MAX == SCHAR_MAX return std::lexicographical_compare((const signed char*) __first1, (const signed char*) __last1, Index: include/bits/stl_bvector.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_bvector.h,v retrieving revision 1.28 diff -c -3 -p -r1.28 stl_bvector.h *** include/bits/stl_bvector.h 14 Jul 2003 02:52:04 -0000 1.28 --- include/bits/stl_bvector.h 13 Aug 2003 18:42:35 -0000 *************** *** 61,66 **** --- 61,70 ---- #ifndef _BVECTOR_H #define _BVECTOR_H 1 + #ifdef _GLIBCXX_DEBUG + # define vector _Release_vector + #endif + namespace std { typedef unsigned long _Bit_type; *************** namespace std *** 342,348 **** { template ! class vector : public _Bvector_base<_Alloc> { public: typedef bool value_type; --- 346,353 ---- { template ! class _GLIBCXX_RELEASE_CLASS(vector) ! : public _Bvector_base<_Alloc> { public: typedef bool value_type; *************** template *** 727,732 **** --- 732,741 ---- typedef vector bit_vector; } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef vector + #endif #endif /* _BVECTOR_H */ Index: include/bits/stl_deque.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_deque.h,v retrieving revision 1.42 diff -c -3 -p -r1.42 stl_deque.h *** include/bits/stl_deque.h 14 Jul 2003 02:52:04 -0000 1.42 --- include/bits/stl_deque.h 13 Aug 2003 18:42:36 -0000 *************** *** 65,70 **** --- 65,74 ---- #include #include + #ifdef _GLIBCXX_DEBUG + # define deque _Release_deque + #endif + namespace std { /** *************** namespace std *** 635,641 **** * @endif */ template > ! class deque : protected _Deque_base<_Tp, _Alloc> { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) --- 639,646 ---- * @endif */ template > ! class _GLIBCXX_RELEASE_CLASS(deque) ! : protected _Deque_base<_Tp, _Alloc> { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) *************** namespace std *** 1527,1530 **** --- 1532,1540 ---- } } // namespace std + #ifdef _GLIBCXX_DEBUG + # undef deque + # include + #endif + #endif /* _DEQUE_H */ Index: include/bits/stl_heap.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_heap.h,v retrieving revision 1.13 diff -c -3 -p -r1.13 stl_heap.h *** include/bits/stl_heap.h 15 Jul 2003 07:30:19 -0000 1.13 --- include/bits/stl_heap.h 13 Aug 2003 18:42:36 -0000 *************** *** 60,67 **** --- 60,112 ---- #ifndef _STL_HEAP_H #define _STL_HEAP_H 1 + #include + namespace std { + // is_heap, a predicate testing whether or not a range is + // a heap. This function is an extension, not part of the C++ + // standard. + template + bool + __is_heap(_RandomAccessIterator __first, _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__first[__parent] < __first[__child]) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template + bool + __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp, + _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__comp(__first[__parent], __first[__child])) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. *************** namespace std *** 101,106 **** --- 146,153 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last - 1); std::__push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), _ValueType(*(__last - 1))); *************** namespace std *** 145,150 **** --- 192,199 ---- // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last - 1, __comp); std::__push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), _ValueType(*(__last - 1)), __comp); *************** namespace std *** 200,205 **** --- 249,256 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last); std::__pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1))); } *************** namespace std *** 256,261 **** --- 307,314 ---- // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; std::__pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)), __comp); *************** namespace std *** 282,287 **** --- 335,341 ---- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__last - __first < 2) return; _DistanceType __len = __last - __first; *************** namespace std *** 317,323 **** // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) ! if (__last - __first < 2) return; _DistanceType __len = __last - __first; _DistanceType __parent = (__len - 2)/2; --- 371,378 ---- // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) ! __glibcxx_requires_valid_range(__first, __last); ! if (__last - __first < 2) return; _DistanceType __len = __last - __first; _DistanceType __parent = (__len - 2)/2; *************** namespace std *** 347,352 **** --- 402,409 ---- _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last); while (__last - __first > 1) std::pop_heap(__first, __last--); *************** namespace std *** 370,375 **** --- 427,434 ---- // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); while (__last - __first > 1) std::pop_heap(__first, __last--, __comp); Index: include/bits/stl_list.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_list.h,v retrieving revision 1.30 diff -c -3 -p -r1.30 stl_list.h *** include/bits/stl_list.h 15 Jul 2003 06:15:57 -0000 1.30 --- include/bits/stl_list.h 13 Aug 2003 18:42:36 -0000 *************** *** 63,68 **** --- 63,72 ---- #include + #ifdef _GLIBCXX_DEBUG + # define list _Release_list + #endif + namespace std { // Supporting structures are split into common and templated types; the *************** namespace std *** 361,367 **** * @endif */ template > ! class list : protected _List_base<_Tp, _Alloc> { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) --- 365,371 ---- * @endif */ template > ! class _GLIBCXX_RELEASE_CLASS(list) : protected _List_base<_Tp, _Alloc> { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) *************** namespace std *** 1175,1179 **** --- 1179,1188 ---- swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) { __x.swap(__y); } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef list + # include + #endif #endif /* _LIST_H */ Index: include/bits/stl_map.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_map.h,v retrieving revision 1.18 diff -c -3 -p -r1.18 stl_map.h *** include/bits/stl_map.h 5 Jul 2003 04:05:35 -0000 1.18 --- include/bits/stl_map.h 13 Aug 2003 18:42:36 -0000 *************** *** 63,68 **** --- 63,72 ---- #include + #ifdef _GLIBCXX_DEBUG + # define map _Release_map + #endif + namespace std { /** *************** namespace std *** 88,94 **** */ template , typename _Alloc = allocator > > ! class map { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) --- 92,98 ---- */ template , typename _Alloc = allocator > > ! class _GLIBCXX_RELEASE_CLASS(map) { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) *************** namespace std *** 654,658 **** --- 658,667 ---- swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef map + # include + #endif #endif /* _MAP_H */ Index: include/bits/stl_multimap.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_multimap.h,v retrieving revision 1.18 diff -c -3 -p -r1.18 stl_multimap.h *** include/bits/stl_multimap.h 5 Jul 2003 04:05:35 -0000 1.18 --- include/bits/stl_multimap.h 13 Aug 2003 18:42:37 -0000 *************** *** 63,68 **** --- 63,72 ---- #include + #ifdef _GLIBCXX_DEBUG + # define multimap _Release_multimap + #endif + namespace std { // Forward declaration of operators < and ==, needed for friend declaration. *************** namespace std *** 102,108 **** * @endif */ template ! class multimap { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) --- 106,112 ---- * @endif */ template ! class _GLIBCXX_RELEASE_CLASS(multimap) { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) *************** namespace std *** 633,637 **** --- 637,646 ---- multimap<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef multimap + # include + #endif #endif /* _MULTIMAP_H */ Index: include/bits/stl_multiset.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_multiset.h,v retrieving revision 1.14 diff -c -3 -p -r1.14 stl_multiset.h *** include/bits/stl_multiset.h 5 Jul 2003 04:05:35 -0000 1.14 --- include/bits/stl_multiset.h 13 Aug 2003 18:42:37 -0000 *************** *** 63,68 **** --- 63,72 ---- #include + #ifdef _GLIBCXX_DEBUG + # define multiset _Release_multiset + #endif + namespace std { *************** inline bool operator<(const multiset<_Ke *** 81,87 **** const multiset<_Key,_Compare,_Alloc>& __y); template ! class multiset { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) --- 85,91 ---- const multiset<_Key,_Compare,_Alloc>& __y); template ! class _GLIBCXX_RELEASE_CLASS(multiset) { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) *************** inline void swap(multiset<_Key,_Compare, *** 269,273 **** --- 273,282 ---- } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef multiset + # include + #endif #endif /* _MULTISET_H */ Index: include/bits/stl_numeric.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_numeric.h,v retrieving revision 1.13 diff -c -3 -p -r1.13 stl_numeric.h *** include/bits/stl_numeric.h 5 Jul 2003 04:05:35 -0000 1.13 --- include/bits/stl_numeric.h 13 Aug 2003 18:42:37 -0000 *************** *** 61,66 **** --- 61,68 ---- #ifndef _STL_NUMERIC_H #define _STL_NUMERIC_H 1 + #include + namespace std { *************** namespace std *** 70,75 **** --- 72,78 ---- { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __init = __init + *__first; *************** namespace std *** 83,88 **** --- 86,92 ---- { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __init = __binary_op(__init, *__first); *************** namespace std *** 97,102 **** --- 101,107 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) __init = __init + (*__first1 * *__first2); *************** namespace std *** 114,119 **** --- 119,125 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); *************** namespace std *** 130,135 **** --- 136,142 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; *************** namespace std *** 151,156 **** --- 158,164 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; *************** namespace std *** 172,177 **** --- 180,186 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; *************** namespace std *** 194,199 **** --- 203,209 ---- // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; Index: include/bits/stl_queue.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_queue.h,v retrieving revision 1.18 diff -c -3 -p -r1.18 stl_queue.h *** include/bits/stl_queue.h 5 Jul 2003 04:05:35 -0000 1.18 --- include/bits/stl_queue.h 13 Aug 2003 18:42:37 -0000 *************** *** 62,67 **** --- 62,68 ---- #define _QUEUE_H 1 #include + #include namespace std { *************** namespace std *** 158,185 **** * %queue. */ reference ! front() { return c.front(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %queue. */ const_reference ! front() const { return c.front(); } /** * Returns a read/write reference to the data at the last element of the * %queue. */ reference ! back() { return c.back(); } /** * Returns a read-only (constant) reference to the data at the last * element of the %queue. */ const_reference ! back() const { return c.back(); } /** * @brief Add data to the end of the %queue. --- 159,202 ---- * %queue. */ reference ! front() ! { ! __glibcxx_requires_nonempty(); ! return c.front(); ! } /** * Returns a read-only (constant) reference to the data at the first * element of the %queue. */ const_reference ! front() const ! { ! __glibcxx_requires_nonempty(); ! return c.front(); ! } /** * Returns a read/write reference to the data at the last element of the * %queue. */ reference ! back() ! { ! __glibcxx_requires_nonempty(); ! return c.back(); ! } /** * Returns a read-only (constant) reference to the data at the last * element of the %queue. */ const_reference ! back() const ! { ! __glibcxx_requires_nonempty(); ! return c.back(); ! } /** * @brief Add data to the end of the %queue. *************** namespace std *** 204,210 **** * needed, it should be retrieved before pop() is called. */ void ! pop() { c.pop_front(); } }; --- 221,231 ---- * needed, it should be retrieved before pop() is called. */ void ! pop() ! { ! __glibcxx_requires_nonempty(); ! c.pop_front(); ! } }; *************** namespace std *** 354,359 **** --- 375,381 ---- const _Sequence& __s = _Sequence()) : c(__s), comp(__x) { + __glibcxx_requires_valid_range(__first, __last); c.insert(c.end(), __first, __last); std::make_heap(c.begin(), c.end(), comp); } *************** namespace std *** 373,379 **** * element of the %queue. */ const_reference ! top() const { return c.front(); } /** * @brief Add data to the %queue. --- 395,405 ---- * element of the %queue. */ const_reference ! top() const ! { ! __glibcxx_requires_nonempty(); ! return c.front(); ! } /** * @brief Add data to the %queue. *************** namespace std *** 411,416 **** --- 437,443 ---- void pop() { + __glibcxx_requires_nonempty(); try { std::pop_heap(c.begin(), c.end(), comp); Index: include/bits/stl_set.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_set.h,v retrieving revision 1.14 diff -c -3 -p -r1.14 stl_set.h *** include/bits/stl_set.h 5 Jul 2003 04:05:35 -0000 1.14 --- include/bits/stl_set.h 13 Aug 2003 18:42:37 -0000 *************** *** 63,68 **** --- 63,72 ---- #include + #ifdef _GLIBCXX_DEBUG + # define set _Release_set + #endif + namespace std { *************** inline bool operator<(const set<_Key,_Co *** 82,88 **** template ! class set { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) --- 86,92 ---- template ! class _GLIBCXX_RELEASE_CLASS(set) { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) *************** inline void swap(set<_Key,_Compare,_Allo *** 266,270 **** --- 270,279 ---- } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef set + # include + #endif #endif /* _SET_H */ Index: include/bits/stl_stack.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_stack.h,v retrieving revision 1.14 diff -c -3 -p -r1.14 stl_stack.h *** include/bits/stl_stack.h 5 Jul 2003 04:05:35 -0000 1.14 --- include/bits/stl_stack.h 13 Aug 2003 18:42:37 -0000 *************** *** 62,67 **** --- 62,68 ---- #define _STACK_H 1 #include + #include namespace std { *************** namespace std *** 153,166 **** * %stack. */ reference ! top() { return c.back(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %stack. */ const_reference ! top() const { return c.back(); } /** * @brief Add data to the top of the %stack. --- 154,175 ---- * %stack. */ reference ! top() ! { ! __glibcxx_requires_nonempty(); ! return c.back(); ! } /** * Returns a read-only (constant) reference to the data at the first * element of the %stack. */ const_reference ! top() const ! { ! __glibcxx_requires_nonempty(); ! return c.back(); ! } /** * @brief Add data to the top of the %stack. *************** namespace std *** 185,191 **** * needed, it should be retrieved before pop() is called. */ void ! pop() { c.pop_back(); } }; --- 194,204 ---- * needed, it should be retrieved before pop() is called. */ void ! pop() ! { ! __glibcxx_requires_nonempty(); ! c.pop_back(); ! } }; Index: include/bits/stl_vector.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_vector.h,v retrieving revision 1.40 diff -c -3 -p -r1.40 stl_vector.h *** include/bits/stl_vector.h 14 Jul 2003 02:52:04 -0000 1.40 --- include/bits/stl_vector.h 13 Aug 2003 18:42:37 -0000 *************** *** 65,70 **** --- 65,74 ---- #include #include + #ifdef _GLIBCXX_DEBUG + # define vector _Release_vector + #endif + namespace std { /// @if maint Primary default version. @endif *************** namespace std *** 183,189 **** * Subscripting ( @c [] ) access is also provided as with C-style arrays. */ template > ! class vector : protected _Vector_base<_Tp, _Alloc> { // Concept requirements. __glibcxx_class_requires(_Tp, _SGIAssignableConcept) --- 187,194 ---- * Subscripting ( @c [] ) access is also provided as with C-style arrays. */ template > ! class _GLIBCXX_RELEASE_CLASS(vector) ! : protected _Vector_base<_Tp, _Alloc> { // Concept requirements. __glibcxx_class_requires(_Tp, _SGIAssignableConcept) *************** namespace std *** 967,971 **** --- 972,981 ---- swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y) { __x.swap(__y); } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef vector + # include + #endif #endif /* _VECTOR_H */ Index: include/bits/stream_iterator.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stream_iterator.h,v retrieving revision 1.4 diff -c -3 -p -r1.4 stream_iterator.h *** include/bits/stream_iterator.h 5 Jul 2003 04:05:36 -0000 1.4 --- include/bits/stream_iterator.h 13 Aug 2003 18:42:37 -0000 *************** *** 37,42 **** --- 37,44 ---- #pragma GCC system_header + #include + namespace std { template() const { return &(operator*()); } istream_iterator& operator++() ! { _M_read(); return *this; } istream_iterator operator++(int) { istream_iterator __tmp = *this; _M_read(); return __tmp; --- 67,99 ---- { } const _Tp& ! operator*() const ! { ! __glibcxx_requires_cond(_M_ok, ! _M_message(__gnu_debug::__dbg_msg_deref_istream) ! ._M_iterator(*this)); ! return _M_value; ! } const _Tp* operator->() const { return &(operator*()); } istream_iterator& operator++() ! { ! __glibcxx_requires_cond(_M_ok, ! _M_message(__gnu_debug::__dbg_msg_inc_istream) ! ._M_iterator(*this)); ! _M_read(); ! return *this; ! } istream_iterator operator++(int) { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__dbg_msg_inc_istream) + ._M_iterator(*this)); istream_iterator __tmp = *this; _M_read(); return __tmp; *************** namespace std *** 138,143 **** --- 155,163 ---- ostream_iterator& operator=(const _Tp& __value) { + __glibcxx_requires_cond(_M_stream != 0, + _M_message(__gnu_debug::__dbg_msg_output_ostream) + ._M_iterator(*this)); *_M_stream << __value; if (_M_string) *_M_stream << _M_string; return *this; Index: include/bits/streambuf_iterator.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/streambuf_iterator.h,v retrieving revision 1.11 diff -c -3 -p -r1.11 streambuf_iterator.h *** include/bits/streambuf_iterator.h 5 Jul 2003 04:05:36 -0000 1.11 --- include/bits/streambuf_iterator.h 13 Aug 2003 18:42:37 -0000 *************** *** 39,44 **** --- 39,45 ---- #pragma GCC system_header #include + #include // NB: Should specialize copy, find algorithms for streambuf iterators. *************** namespace std *** 82,92 **** // NB: The result of operator*() on an end of stream is undefined. char_type operator*() const ! { return traits_type::to_char_type(_M_get()); } istreambuf_iterator& operator++() { const int_type __eof = traits_type::eof(); if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof)) _M_sbuf = 0; --- 83,105 ---- // NB: The result of operator*() on an end of stream is undefined. char_type operator*() const ! { ! #ifdef _GLIBCXX_DEBUG_PEDANTIC ! // Dereferencing a past-the-end istreambuf_iterator is a ! // libstdc++ extension ! __glibcxx_requires_cond(!_M_at_eof(), ! _M_message(__gnu_debug::__dbg_msg_deref_istreambuf) ! ._M_iterator(*this)); ! #endif ! return traits_type::to_char_type(_M_get()); ! } istreambuf_iterator& operator++() { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__dbg_msg_inc_istreambuf) + ._M_iterator(*this)); const int_type __eof = traits_type::eof(); if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof)) _M_sbuf = 0; *************** namespace std *** 98,103 **** --- 111,120 ---- istreambuf_iterator operator++(int) { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__dbg_msg_inc_istreambuf) + ._M_iterator(*this)); + const int_type __eof = traits_type::eof(); istreambuf_iterator __old = *this; if (_M_sbuf *************** namespace std *** 116,123 **** equal(const istreambuf_iterator& __b) const { const int_type __eof = traits_type::eof(); ! bool __thiseof = traits_type::eq_int_type(_M_get(), __eof); ! bool __beof = traits_type::eq_int_type(__b._M_get(), __eof); return (__thiseof && __beof || (!__thiseof && !__beof)); } #endif --- 133,140 ---- equal(const istreambuf_iterator& __b) const { const int_type __eof = traits_type::eof(); ! bool __thiseof = _M_at_eof(); ! bool __beof = __b._M_at_eof(); return (__thiseof && __beof || (!__thiseof && !__beof)); } #endif *************** namespace std *** 137,142 **** --- 154,166 ---- _M_sbuf = 0; } return __ret; + } + + bool + _M_at_eof() const + { + const int_type __eof = traits_type::eof(); + return traits_type::eq_int_type(_M_get(), __eof); } }; Index: include/bits/vector.tcc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/vector.tcc,v retrieving revision 1.10 diff -c -3 -p -r1.10 vector.tcc *** include/bits/vector.tcc 14 Jul 2003 02:52:04 -0000 1.10 --- include/bits/vector.tcc 13 Aug 2003 18:42:37 -0000 *************** *** 61,66 **** --- 61,70 ---- #ifndef _VECTOR_TCC #define _VECTOR_TCC 1 + #ifdef _GLIBCXX_DEBUG + # define vector _Release_vector + #endif + namespace std { template *************** namespace std *** 453,457 **** --- 457,465 ---- } } } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef vector + #endif #endif /* _VECTOR_TCC */ Index: include/debug/bitset =================================================================== RCS file: include/debug/bitset diff -N include/debug/bitset *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/bitset 13 Aug 2003 18:42:37 -0000 *************** *** 0 **** --- 1,48 ---- + // Debugging bitset implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_BITSET_H + #define _GLIBCXX_EXT_DEBUG_BITSET_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have a debug implementation in std::, so import it + namespace __gnu_debug + { + using std::bitset; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_BITSET_H */ Index: include/debug/dbg_bitset.h =================================================================== RCS file: include/debug/dbg_bitset.h diff -N include/debug/dbg_bitset.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_bitset.h 13 Aug 2003 18:42:37 -0000 *************** *** 0 **** --- 1,294 ---- + // Debugging bitset implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_BITSET_H + #define _GLIBCXX_DEBUG_BITSET_H + + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template + class _GLIBCXX_DEBUG_CLASS(bitset) + : public _GLIBCXX_DEBUG_BASE(std, bitset)<_Nb>, + public __gnu_debug::_Safe_sequence_base + { + typedef _GLIBCXX_DEBUG_BASE(std, bitset)<_Nb> _Base; + typedef __gnu_debug::_Safe_sequence_base _Safe_base; + + public: + // bit reference: + class reference + : private _Base::reference, public __gnu_debug::_Safe_iterator_base + { + typedef typename _Base::reference _Base_ref; + + friend class bitset; + reference(); + + reference(const _Base_ref& __base, bitset* __seq) + : _Base_ref(__base), _Safe_iterator_base(__seq, false) + { } + + public: + reference(const reference& __x) + : _Base_ref(__x), _Safe_iterator_base(__x, false) + { } + + reference& + operator=(bool __x) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__dbg_msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + reference& + operator=(const reference& __x) + { + _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(), + _M_message(::__gnu_debug::__dbg_msg_bad_bitset_read) + ._M_iterator(__x)); + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__dbg_msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + bool + operator~() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__dbg_msg_bad_bitset_read) + ._M_iterator(*this)); + return ~(*static_cast(this)); + } + + operator bool() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__dbg_msg_bad_bitset_read) + ._M_iterator(*this)); + return *static_cast(this); + } + + reference& + flip() + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__dbg_msg_bad_bitset_flip) + ._M_iterator(*this)); + _Base_ref::flip(); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() : _Base() { } + + bitset(unsigned long __val) : _Base(__val) { } + + template + explicit + bitset(const std::basic_string<_CharT,_Traits,_Allocator>& __str, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __pos = 0, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __n = (std::basic_string<_CharT,_Traits,_Allocator>::npos)) + : _Base(__str, __pos, __n) + { } + + bitset(const _Base& __x) : _Base(__x), _Safe_base() { } + + // 23.3.5.2 bitset operations: + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + _M_base() &= __rhs; + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + _M_base() != __rhs; + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + _M_base() ^= __rhs; + return *this; + } + + bitset<_Nb>& + operator<<=(size_t __pos) + { + _M_base() <<= __pos; + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __pos) + { + _M_base() >>= __pos; + return *this; + } + + bitset<_Nb>& + set() + { + _Base::set(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 186. bitset::set() second parameter should be bool + bitset<_Nb>& + set(size_t __pos, bool __val = true) + { + _Base::set(__pos, __val); + return *this; + } + + bitset<_Nb>& + reset() + { + _Base::reset(); + return *this; + } + + bitset<_Nb>& + reset(size_t __pos) + { + _Base::reset(__pos); + return *this; + } + + bitset<_Nb> operator~() const { return bitset(~_M_base()); } + + bitset<_Nb>& + flip() + { + _Base::flip(); + return *this; + } + + bitset<_Nb>& + flip(size_t __pos) + { + _Base::flip(__pos); + return *this; + } + + // element access: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + reference + operator[](size_t __pos) + { + __glibcxx_check_subscript(__pos); + return reference(_M_base()[__pos], this); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + bool + operator[](size_t __pos) const + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::to_ulong; + + template + std::basic_string<_CharT, _Traits, _Allocator> + to_string() const + { return _M_base().template to_string<_CharT, _Traits, _Allocator>(); } + + using _Base::count; + using _Base::size; + + bool + operator==(const bitset<_Nb>& __rhs) const + { return _M_base() == __rhs; } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return _M_base() != __rhs; } + + using _Base::test; + using _Base::any; + using _Base::none; + + bitset<_Nb> + operator<<(size_t __pos) const + { return bitset<_Nb>(_M_base() << __pos); } + + bitset<_Nb> + operator>>(size_t __pos) const + { return bitset<_Nb>(_M_base() >> __pos); } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + }; + + template + bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) &= __y; } + + template + bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) |= __y; } + + template + bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) ^= __y; } + + template + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { return __is >> __x._M_base(); } + + template + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) + { return __os << __x._M_base(); } + + } + + #endif /* _GLIBCXX_DEBUG_BITSET_H */ Index: include/debug/dbg_deque.h =================================================================== RCS file: include/debug/dbg_deque.h diff -N include/debug/dbg_deque.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_deque.h 13 Aug 2003 18:42:37 -0000 *************** *** 0 **** --- 1,380 ---- + // Debugging deque implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_DEQUE_H + #define _GLIBCXX_DEBUG_DEQUE_H + + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template > + class _GLIBCXX_DEBUG_CLASS(deque) + : public _GLIBCXX_DEBUG_BASE(std, deque)<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(std, deque)<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.1.1 construct/copy/destroy: + explicit deque(const _Allocator& __a = _Allocator()) + : _Base(__a) + { } + + explicit deque(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) + { } + + template + deque(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { } + + deque(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~deque() { } + + deque<_Tp,_Allocator>& + operator=(const deque<_Tp,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.1.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + bool __invalidate_all = __sz > this->size(); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + + _Base::resize(__sz, __c); + + if (__invalidate_all) + this->_M_invalidate_all(); + } + + using _Base::empty; + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.1.3 modifiers: + void + push_front(const _Tp& __x) + { + _Base::push_front(__x); + this->_M_invalidate_all(); + } + + void + push_back(const _Tp& __x) + { + _Base::push_back(__x); + this->_M_invalidate_all(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + typename _Base::iterator __result = _Base::insert(__position.base(),__x); + this->_M_invalidate_all(); + return iterator(__result, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + this->_M_invalidate_all(); + } + + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + this->_M_invalidate_all(); + } + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + if (__position == begin() || __position == end()-1) + { + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + else + { + typename _Base::iterator __result = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__result, this); + } + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + if (__first == begin() || __last == end()-1) + { + this->_M_detach_singular(); + for (iterator __position = __first; __position != __last; ) + { + iterator __victim = __position++; + __victim._M_invalidate(); + } + try + { return iterator(_Base::erase(__first.base(), __last.base()), + this); } + catch (...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + else + { + typename _Base::iterator __result = + _Base::erase(__first.base(), __last.base()); + this->_M_invalidate_all(); + return iterator(__result, this); + } + } + + void + swap(deque<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + }; + + template + inline bool + operator==(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + } + + #endif /* _GLIBCXX_DEBUG_DEQUE_H */ Index: include/debug/dbg_hash_map.h =================================================================== RCS file: include/debug/dbg_hash_map.h diff -N include/debug/dbg_hash_map.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_hash_map.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,273 ---- + // Debugging hash_map implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_HASH_MAP_H + #define _GLIBCXX_DEBUG_HASH_MAP_H + + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(__gnu_cxx) + { + + template, + class _EqualKey = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class _GLIBCXX_DEBUG_CLASS(hash_map) + : public _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_map)<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_map)<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_map() { } + + explicit hash_map(size_type __n) : _Base(__n) { } + + hash_map(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template + hash_map(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + hash_map(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_map& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() { return iterator(_Base::begin(), this); } + iterator end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + std::pair + insert(const value_type& __obj) + { + std::pair __result = + _Base::insert(__obj); + return std::make_pair(iterator(__result.first, this), __result.second); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair + insert_noresize(const value_type& __obj) + { + std::pair __result = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__result.first, this), __result.second); + } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::operator[]; + using _Base::count; + + std::pair + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__key); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__result.first, this), + const_iterator(__result.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } + + } + + #endif /* _GLIBCXX_DEBUG_HASH_MAP_H */ Index: include/debug/dbg_hash_multimap.h =================================================================== RCS file: include/debug/dbg_hash_multimap.h diff -N include/debug/dbg_hash_multimap.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_hash_multimap.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,263 ---- + // Debugging hash_multimap implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_HASH_MULTIMAP_H + #define _GLIBCXX_DEBUG_HASH_MULTIMAP_H + + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(__gnu_cxx) + { + + template, + class _EqualKey = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class _GLIBCXX_DEBUG_CLASS(hash_multimap) + : public _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_multimap)<_Value,_Tp,_HashFcn, + _EqualKey,_Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_multimap)<_Value,_Tp,_HashFcn, + _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multimap() { } + + explicit hash_multimap(size_type __n) : _Base(__n) { } + + hash_multimap(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multimap& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() { return iterator(_Base::begin(), this); } + iterator end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__key); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__result.first, this), + const_iterator(__result.second, this)); + } + + size_type + erase(const key_type& __key) + { + std::pair __victims = this->equal_range(__key); + size_t __num_victims = 0; + while (__victims.first != __victims.second) { + this->erase(__victims.first++); + ++__num_victims; + } + return __num_victims; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } + + } + + #endif /* _GLIBCXX_DEBUG_HASH_MULTIMAP_H */ Index: include/debug/dbg_hash_multiset.h =================================================================== RCS file: include/debug/dbg_hash_multiset.h diff -N include/debug/dbg_hash_multiset.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_hash_multiset.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,240 ---- + // Debugging hash_multiset implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_HASH_MULTISET_H + #define _GLIBCXX_DEBUG_HASH_MULTISET_H + + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(__gnu_cxx) + { + + template, + class _EqualKey = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class _GLIBCXX_DEBUG_CLASS(hash_multiset) + : public _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_multiset)<_Value, _HashFcn, + _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_multiset)<_Value,_HashFcn, + _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multiset() { } + + explicit hash_multiset(size_type __n) : _Base(__n) { } + + hash_multiset(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + hash_multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multiset& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() const { return iterator(_Base::begin(), this); } + iterator end() const { return iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__key); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + size_type + erase(const key_type& __key) + { + size_type __count = 0; + std::pair __victims = this->equal_range(__key); + while (__victims.first != __victims.second) + { + this->erase(__victims++); + ++__count; + } + return __count; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } + + } + + #endif /* _GLIBCXX_DEBUG_HASH_MULTISET_H */ Index: include/debug/dbg_hash_set.h =================================================================== RCS file: include/debug/dbg_hash_set.h diff -N include/debug/dbg_hash_set.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_hash_set.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,245 ---- + // Debugging hash_set implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_HASH_SET_H + #define _GLIBCXX_DEBUG_HASH_SET_H + + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(__gnu_cxx) + { + + template, + class _EqualKey = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class _GLIBCXX_DEBUG_CLASS(hash_set) + : public _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_set)<_Value, _HashFcn, + _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(__gnu_cxx, hash_set)<_Value, _HashFcn, + _EqualKey, _Alloc> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_set() { } + + explicit hash_set(size_type __n) : _Base(__n) { } + + hash_set(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template + hash_set(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + hash_set(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_set& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() const { return iterator(_Base::begin(), this); } + iterator end() const { return iterator(_Base::end(), this); } + + std::pair + insert(const value_type& __obj) + { + std::pair __result = + _Base::insert(__obj); + return std::make_pair(iterator(__result.first, this), __result.second); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair + insert_noresize(const value_type& __obj) + { + std::pair __result = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__result.first, this), __result.second); + } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__key); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } + + } + + #endif /* _GLIBCXX_DEBUG_HASH_SET_H */ Index: include/debug/dbg_list.h =================================================================== RCS file: include/debug/dbg_list.h diff -N include/debug/dbg_list.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_list.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,502 ---- + // Debugging list implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_LIST_H + #define _GLIBCXX_DEBUG_LIST_H + + #include + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template > + class _GLIBCXX_DEBUG_CLASS(list) + : public _GLIBCXX_DEBUG_BASE(std, list)<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(std, list)<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.2.1 construct/copy/destroy: + explicit list(const _Allocator& __a = _Allocator()) + : _Base(__a) + { } + + explicit list(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) + { } + + template + list(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + + list(const list& __x) : _Base(__x), _Safe_base() { } + + list(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~list() { } + + list& + operator=(const list& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.2.2 capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + this->_M_detach_singular(); + + // if __sz < size(), invalidate all iterators in [begin+__sz, end()) + iterator __victim = begin(); + iterator __end = end(); + for (size_type __i = __sz; __victim != __end && __i > 0; --__i) + ++__victim; + + while (__victim != __end) + { + iterator __real_victim = __victim++; + __real_victim._M_invalidate(); + } + + try + { + _Base::resize(__sz, __c); + } + catch(...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + + // element access: + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.2.3 modifiers: + using _Base::push_front; + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + using _Base::push_back; + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + } + + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + + iterator + erase(iterator __position, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__position, __last); + for (iterator __victim = __position; __victim != __last; ) + { + iterator __old = __victim; + ++__victim; + __old._M_invalidate(); + } + return iterator(_Base::erase(__position.base(), __last.base()), this); + } + + void + swap(list& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + // 23.2.2.4 list operations: + void + splice(iterator __position, list& __x) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this, + _M_message(::__gnu_debug::__dbg_msg_self_splice) + ._M_sequence(*this, "this")); + this->splice(__position, __x, __x.begin(), __x.end()); + } + + void + splice(iterator __position, list& __x, iterator __i) + { + __glibcxx_check_insert(__position); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__dbg_msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x, "__x")); + _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(), + _M_message(::__gnu_debug::__dbg_msg_splice_bad) + ._M_iterator(__i, "__i")); + _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x), + _M_message(::__gnu_debug::__dbg_msg_splice_other) + ._M_iterator(__i, "__i")._M_sequence(__x, "__x")); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__i); + _Base::splice(__position.base(), __x._M_base(), __i.base()); + } + + void + splice(iterator __position, list& __x, iterator __first, iterator __last) + { + __glibcxx_check_insert(__position); + __glibcxx_check_valid_range(__first, __last); + _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x), + _M_message(::__gnu_debug::__dbg_msg_splice_other) + ._M_sequence(__x, "x")._M_iterator(__first, "first")); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__dbg_msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x)); + + for (iterator __tmp = __first; __tmp != __last; ) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position, + _M_message(::__gnu_debug::__dbg_msg_splice_overlap) + ._M_iterator(__tmp, "position")._M_iterator(__first, "first") + ._M_iterator(__last, "last")); + iterator __victim = __tmp++; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__victim); + } + + _Base::splice(__position.base(), __x._M_base(), __first.base(), + __last.base()); + } + + void + remove(const _Tp& __value) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (*__x == __value) + __x = erase(__x); + else + ++__x; + } + } + + template + void + remove_if(_Predicate __pred) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (__pred(*__x)) + __x = erase(__x); + else + ++__x; + } + } + + void + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + void + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + void + merge(list& __x) + { + __glibcxx_check_sorted(_Base::begin(), _Base::end()); + __glibcxx_check_sorted(__x.begin().base(), __x.end().base()); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base()); + } + + template + void + merge(list& __x, _Compare __comp) + { + __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp); + __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(), + __comp); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base(), __comp); + } + + void + sort() { _Base::sort(); } + + template + void + sort(_StrictWeakOrdering __pred) + { _Base::sort(__pred); } + + using _Base::reverse; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + } + + #endif /* _GLIBCXX_DEBUG_LIST_H */ Index: include/debug/dbg_map.h =================================================================== RCS file: include/debug/dbg_map.h diff -N include/debug/dbg_map.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_map.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,327 ---- + // Debugging map implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_MAP_H + #define _GLIBCXX_DEBUG_MAP_H + + #include + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template, + typename _Allocator = std::allocator > > + class _GLIBCXX_DEBUG_CLASS(map) + : public _GLIBCXX_DEBUG_BASE(std, map)<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(std, map)<_Key, _Tp, _Compare, _Allocator> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit map(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) + { } + + template + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a), + _Safe_base() + { } + + map(const map<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() + { } + + map(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~map() { } + + map<_Key,_Tp,_Compare,_Allocator>& + operator=(const map<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 133. map missing get_allocator() + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // 23.3.1.2 element access: + using _Base::operator[]; + + // modifiers: + std::pair + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __result = _Base::insert(__x); + return std::pair(iterator(__result.first, this), + __result.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(map<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 map operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__result.first, this), + const_iterator(__result.second, this)); + } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs, + map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + } + + #endif /* _GLIBCXX_DEBUG_MAP_H */ Index: include/debug/dbg_multimap.h =================================================================== RCS file: include/debug/dbg_multimap.h diff -N include/debug/dbg_multimap.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_multimap.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,317 ---- + // Debugging multimap implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_MULTIMAP_H + #define _GLIBCXX_DEBUG_MULTIMAP_H + + #include + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template, + typename _Allocator = std::allocator > > + class _GLIBCXX_DEBUG_CLASS(multimap) + : public _GLIBCXX_DEBUG_BASE(std, multimap)<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(std, multimap)<_Key, _Tp, _Compare, _Allocator> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit multimap(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) + { } + + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) + { } + + multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() + { } + + multimap(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multimap() { } + + multimap<_Key,_Tp,_Compare,_Allocator>& + operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 multimap operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__result.first, this), + const_iterator(__result.second, this)); + } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + } + + #endif /* _GLIBCXX_DEBUG_MULTIMAP_H */ Index: include/debug/dbg_multiset.h =================================================================== RCS file: include/debug/dbg_multiset.h diff -N include/debug/dbg_multiset.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_multiset.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,323 ---- + // Debugging multiset implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_MULTISET_H + #define _GLIBCXX_DEBUG_MULTISET_H + + #include + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template, + class _Allocator = std::allocator<_Key> > + class _GLIBCXX_DEBUG_CLASS(multiset) + : public _GLIBCXX_DEBUG_BASE(std, multiset)<_Key, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(std, multiset)<_Key, _Compare, _Allocator> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit multiset(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) + { } + + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) + { } + + multiset(const multiset<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() + { } + + multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multiset() { } + + multiset<_Key,_Compare,_Allocator>& + operator=(const multiset<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multiset<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // multiset operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__result.first, this), + const_iterator(__result.second, this)); + } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + void + swap(multiset<_Key,_Compare,_Allocator>& __x, + multiset<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } + + } + + #endif /* _GLIBCXX_DEBUG_MULTISET_H */ Index: include/debug/dbg_set.h =================================================================== RCS file: include/debug/dbg_set.h diff -N include/debug/dbg_set.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_set.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,327 ---- + // Debugging set implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_SET_H + #define _GLIBCXX_DEBUG_SET_H + + #include + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template, + class _Allocator = std::allocator<_Key> > + class _GLIBCXX_DEBUG_CLASS(set) + : public _GLIBCXX_DEBUG_BASE(std, set)<_Key,_Compare,_Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(std, set)<_Key,_Compare,_Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit set(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) + { } + + template + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) + { } + + set(const set<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() + { } + + set(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~set() { } + + set<_Key,_Compare,_Allocator>& + operator=(const set<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + std::pair + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __result = _Base::insert(__x); + return std::pair(iterator(__result.first, this), + __result.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + while (__first != __last) + this->erase(__first++); + } + + void + swap(set<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // set operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(iterator(__result.first, this), + iterator(__result.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __result = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__result.first, this), + const_iterator(__result.second, this)); + } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + void + swap(set<_Key,_Compare,_Allocator>& __x, + set<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } + + } + + #endif /* _GLIBCXX_DEBUG_SET_H */ Index: include/debug/dbg_vector.h =================================================================== RCS file: include/debug/dbg_vector.h diff -N include/debug/dbg_vector.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/dbg_vector.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,409 ---- + // Debugging vector implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_VECTOR_H + #define _GLIBCXX_DEBUG_VECTOR_H + + #include + #include + + namespace _GLIBCXX_NAMESPACE_DEBUG(std) + { + + template > + class _GLIBCXX_DEBUG_CLASS(vector) + : public _GLIBCXX_DEBUG_BASE(std, vector)<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_DEBUG_BASE(std, vector)<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + public: + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.4.1 construct/copy/destroy: + explicit vector(const _Allocator& __a = _Allocator()) + : _Base(__a), _M_guaranteed_capacity(0) + { } + + explicit vector(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) + { } + + template + vector(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a), + _M_guaranteed_capacity(0) + { _M_update_guaranteed_capacity(); } + + vector(const vector<_Tp,_Allocator>& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) + { } + + /// Construction from a release-mode vector + vector(const _Base& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) + { } + + ~vector() { } + + vector<_Tp,_Allocator>& + operator=(const vector<_Tp,_Allocator>& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + assign(size_type __n, const _Tp& __u) + { + _Base::assign(__n, __u); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.4.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + bool __realloc = _M_requires_reallocation(__sz); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + _Base::resize(__sz, __c); + if (__realloc) + this->_M_invalidate_all(); + } + + using _Base::capacity; + using _Base::empty; + + void + reserve(size_type __n) + { + bool __realloc = _M_requires_reallocation(__n); + _Base::reserve(__n); + if (__n > _M_guaranteed_capacity) + _M_guaranteed_capacity = __n; + if (__realloc) + this->_M_invalidate_all(); + } + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.4.3 modifiers: + void + push_back(const _Tp& __x) + { + bool __realloc = _M_requires_reallocation(this->size() + 1); + _Base::push_back(__x); + if (__realloc) + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end() - 1; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + 1); + difference_type __offset = __position - begin(); + typename _Base::iterator __result = _Base::insert(__position.base(),__x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + return iterator(__result, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + __n); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __n, __x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + + /* Hard to guess if invalidation will occur, because __last + - __first can't be calculated in all cases, so we just + punt here by checking if it did occur. */ + typename _Base::iterator __old_begin = _M_base().begin(); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __first, __last); + + if (_M_base().begin() != __old_begin) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + difference_type __offset = __position - begin(); + typename _Base::iterator __result = _Base::erase(__position.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__result, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + difference_type __offset = __first - begin(); + typename _Base::iterator __result = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__result, this); + } + + void + swap(vector<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + size_type _M_guaranteed_capacity; + + bool + _M_requires_reallocation(size_type __elements) + { + #ifdef _GLIBCXX_DEBUG_PEDANTIC + return __elements > this->capacity(); + #else + return __elements > _M_guaranteed_capacity; + #endif + } + + void + _M_update_guaranteed_capacity() + { + if (this->size() > _M_guaranteed_capacity) + _M_guaranteed_capacity = this->size(); + } + }; + + template + inline bool + operator==(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + } + + #endif /* _GLIBCXX_DEBUG_VECTOR_H */ Index: include/debug/debug.h =================================================================== RCS file: include/debug/debug.h diff -N include/debug/debug.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/debug.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,531 ---- + // Debugging support implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_DEBUG_H + #define _GLIBCXX_DEBUG_DEBUG_H + + #include + + /** + * Macros used by the implementation to verify certain + * properties. These macros may only be used directly by the debug + * wrappers. Note that these are macros (instead of the more obviously + * "correct" choice of making them functions) because we need line and + * file information at the call site, to minimize the distance between + * the user error and where the error is reported. + * + */ + #define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ + do { \ + if (! (_Condition)) \ + ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ + ._ErrorMessage._M_error(); \ + } while (false) + + // Verify that [_First, _Last) forms a valid iterator range. + #define __glibcxx_check_valid_range(_First,_Last) \ + _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \ + _M_message(::__gnu_debug::__dbg_msg_valid_range) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + + /** Verify that we can insert into *this with the iterator _Position. + * Insertion into a container at a specific position requires that + * the iterator be nonsingular (i.e., either dereferenceable or + * past-the-end) and that it reference the sequence we are inserting + * into. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. + */ + #define __glibcxx_check_insert(_Position) \ + _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__dbg_msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ + _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__dbg_msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + + /** Verify that we can insert the values in the iterator range + * [_First, _Last) into *this with the iterator _Position. Insertion + * into a container at a specific position requires that the iterator + * be nonsingular (i.e., either dereferenceable or past-the-end), + * that it reference the sequence we are inserting into, and that the + * iterator range [_First, Last) is a valid (possibly empty) + * range. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. + * + * @tbd We would like to be able to check for noninterference of + * _Position and the range [_First, _Last), but that can't (in + * general) be done. + */ + #define __glibcxx_check_insert_range(_Position,_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last); \ + _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__dbg_msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ + _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__dbg_msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + + /** Verify that we can erase the element referenced by the iterator + * _Position. We can erase the element if the _Position iterator is + * dereferenceable and references this sequence. + */ + #define __glibcxx_check_erase(_Position) \ + _GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ + _M_message(::__gnu_debug::__dbg_msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ + _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__dbg_msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + + /** Verify that we can erase the elements in the iterator range + * [_First, _Last). We can erase the elements if [_First, _Last) is a + * valid iterator range within this sequence. + */ + #define __glibcxx_check_erase_range(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last); \ + _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ + _M_message(::__gnu_debug::__dbg_msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + + // Verify that the subscript _N is less than the container's size. + #define __glibcxx_check_subscript(_N) \ + _GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ + _M_message(::__gnu_debug::__dbg_msg_subscript_oob) \ + ._M_sequence(*this, "this") \ + ._M_integer(_N, #_N) \ + ._M_integer(this->size(), "size")) + + // Verify that the container is nonempty + #define __glibcxx_check_nonempty() \ + _GLIBCXX_DEBUG_VERIFY(! this->empty(), \ + _M_message(::__gnu_debug::__dbg_msg_empty) \ + ._M_sequence(*this, "this")) + + // Verify that the < operator for elements in the sequence is a + // StrictWeakOrdering by checking that it is irreflexive. + #define __glibcxx_check_strict_weak_ordering(_First,_Last) \ + _GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) + + // Verify that the predicate is StrictWeakOrdering by checking that it + // is irreflexive. + #define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ + _GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) + + + // Verify that the iterator range [_First, _Last) is sorted + #define __glibcxx_check_sorted(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last); \ + __glibcxx_check_strict_weak_ordering(_First,_Last); \ + _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \ + _M_message(::__gnu_debug::__dbg_msg_unsorted) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + + /** Verify that the iterator range [_First, _Last) is sorted by the + predicate _Pred. */ + #define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ + __glibcxx_check_valid_range(_First,_Last); \ + __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ + _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__dbg_msg_unsorted_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + + /** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value. */ + #define __glibcxx_check_partitioned(_First,_Last,_Value) \ + __glibcxx_check_valid_range(_First,_Last); \ + _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value), \ + _M_message(::__gnu_debug::__dbg_msg_unpartitioned) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Value)) + + /** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value and predicate _Pred. */ + #define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ + __glibcxx_check_valid_range(_First,_Last); \ + _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value, _Pred), \ + _M_message(::__gnu_debug::__dbg_msg_unpartitioned_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred) \ + ._M_string(#_Value)) + + // Verify that the iterator range [_First, _Last) is a heap + #define __glibcxx_check_heap(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last); \ + _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \ + _M_message(::__gnu_debug::__dbg_msg_not_heap) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + + /** Verify that the iterator range [_First, _Last) is a heap + w.r.t. the predicate _Pred. */ + #define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ + __glibcxx_check_valid_range(_First,_Last); \ + _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__dbg_msg_not_heap_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + + #ifdef _GLIBCXX_DEBUG_PEDANTIC + # define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) + # define __glibcxx_check_string_len(_String,_Len) \ + _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) + #else + # define __glibcxx_check_string(_String) + # define __glibcxx_check_string_len(_String,_Len) + #endif + + /** Macros used by the implementation outside of debug wrappers to + * verify certain properties. The __glibcxx_requires_xxx macros are + * merely wrappers around the __glibcxx_check_xxx wrappers when we + * are compiling with debug mode, but disappear when we are in + * release mode so that there is no checking performed in, e.g., the + * standard library algorithms. + */ + #ifdef _GLIBCXX_DEBUG + # define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition) + + # ifdef _GLIBXX_DEBUG_PEDANTIC + # define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition) + # else + # define _GLIBCXX_DEBUG_PEDASSERT(_Condition) + # endif + + # define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) + # define __glibcxx_requires_valid_range(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last) + # define __glibcxx_requires_sorted(_First,_Last) \ + __glibcxx_check_sorted(_First,_Last) + # define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \ + __glibcxx_check_sorted_pred(_First,_Last,_Pred) + # define __glibcxx_requires_partitioned(_First,_Last,_Value) \ + __glibcxx_check_partitioned(_First,_Last,_Value) + # define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \ + __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) + # define __glibcxx_requires_heap(_First,_Last) \ + __glibcxx_check_heap(_First,_Last) + # define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \ + __glibcxx_check_heap_pred(_First,_Last,_Pred) + # define __glibcxx_requires_nonempty() __glibcxx_check_nonempty() + # define __glibcxx_requires_string(_String) __glibcxx_check_string(_String) + # define __glibcxx_requires_string_len(_String,_Len) \ + __glibcxx_check_string_len(_String,_Len) + # define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N) + #else + # define _GLIBCXX_DEBUG_ASSERT(_Condition) + # define _GLIBCXX_DEBUG_PEDASSERT(_Condition) + # define __glibcxx_requires_cond(_Cond,_Msg) + # define __glibcxx_requires_valid_range(_First,_Last) + # define __glibcxx_requires_sorted(_First,_Last) + # define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) + # define __glibcxx_requires_partitioned(_First,_Last,_Value) + # define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) + # define __glibcxx_requires_heap(_First,_Last) + # define __glibcxx_requires_heap_pred(_First,_Last,_Pred) + # define __glibcxx_requires_nonempty() + # define __glibcxx_requires_string(_String) + # define __glibcxx_requires_string_len(_String,_Len) + # define __glibcxx_requires_subscript(_N) + #endif + + #include // TBD: temporary + + #include // for ptrdiff_t + #include // for iterator_traits, categories + #include // for _Is_integer + + namespace __gnu_debug + { + template class _Safe_iterator; + + // An arbitrary iterator pointer is not singular + inline bool __check_singular_aux(const void*) { return false; } + + // We may have an iterator that derives from _Safe_iterator_base but isn't + // a _Safe_iterator. + template + inline bool + __check_singular(_Iterator& __x) + { return __gnu_debug::__check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_singular(); } + + /** Assume that some arbitrary iterator is dereferenceable, because we + can't prove that it isn't. */ + template + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** If the distance between two random access iterators is + * nonnegative, assume the range is valid. + */ + template + inline bool + __valid_range_aux2(const _RandomAccessIterator& __first, + const _RandomAccessIterator& __last, + std::random_access_iterator_tag) + { return __last - __first >= 0; } + + /** Can't test for a valid range with input iterators, because + * iteration may be destructive. So we just assume that the range + * is valid. + */ + template + inline bool + __valid_range_aux2(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + /** We say that integral types for a valid range, and defer to other + * routines to realize what to do with integral types instead of + * iterators. + */ + template + inline bool + __valid_range_aux(const _Integral&, const _Integral&, __true_type) + { return true; } + + /** We have iterators, so figure out what kind of iterators that are + * to see if we can check the range ahead of time. + */ + template + inline bool + __valid_range_aux(const _InputIterator& __first, + const _InputIterator& __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); + } + + /** Don't know what these iterators are, or if they are even + * iterators (we may get an integral type for InputIterator), so + * see if they are integral and pass them on to the next phase + * otherwise. + */ + template + inline bool + __valid_range(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return __gnu_debug::__valid_range_aux(__first, __last, _Integral()); + } + + /** Safe iterators know how to check if they form a valid range. */ + template + inline bool + __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, + const _Safe_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } + + /* Checks that [first, last) is a valid range, and then returns + * __first. This routine is useful when we can't use a separate + * assertion statement because, e.g., we are in a constructor. + */ + template + inline _InputIterator + __check_valid_range(const _InputIterator& __first, + const _InputIterator& __last) + { + _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last)); + return __first; + } + + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s, const _Integer& __n) + { + #ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); + #endif + return __s; + } + + /** Checks that __s is non-NULL and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s) + { + #ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0); + #endif + return __s; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + _Predicate, std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__pred(*__next, *__first)) + return false; + } + + return true; + } + + // Determine if a sequence is sorted + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, _Category()); + } + + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last, + _Predicate __pred) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, __pred, + _Category()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 270. Binary search requirements overly strict + // Determine if a sequence is partitioned w.r.t. this element + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + while (__first != __last && *__first < __value) + ++__first; + while (__first != __last && !(*__first < __value)) + ++__first; + return __first == __last; + } + + // Determine if a sequence is partitioned w.r.t. this element + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value, _Pred __pred) + { + while (__first != __last && __pred(*__first, __value)) + ++__first; + while (__first != __last && !__pred(*__first, __value)) + ++__first; + return __first == __last; + } + } // namespace __gnu_debug + + #ifdef _GLIBCXX_DEBUG + // We need the error formatter + # include + #endif + + #endif /* _GLIBCXX_DEBUG_DEBUG_H */ Index: include/debug/deque =================================================================== RCS file: include/debug/deque diff -N include/debug/deque *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/deque 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,48 ---- + // Debugging deque implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_DEQUE_H + #define _GLIBCXX_EXT_DEBUG_DEQUE_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have a debug implementation in std::, so pull it in. + namespace __gnu_debug + { + using std::deque; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_DEQUE_H */ Index: include/debug/formatter.h =================================================================== RCS file: include/debug/formatter.h diff -N include/debug/formatter.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/formatter.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,387 ---- + // Debug-mode error formatting implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_FORMATTER_H + #define _GLIBCXX_DEBUG_FORMATTER_H + + #include + #include + + namespace __gnu_cxx + { + + /** Determine if the two types are the same. */ + template + struct __is_same + { + static const bool value = false; + }; + + template + struct __is_same<_Type, _Type> + { + static const bool value = true; + }; + + template struct __truth {}; + + } // namespace __gnu_cxx + + namespace __gnu_debug + { + using namespace std; + + class _Safe_sequence_base; + template class _Safe_iterator; + template class _Safe_sequence; + + enum _Debug_msg_id + { + // General checks + __dbg_msg_valid_range, + __dbg_msg_insert_singular, + __dbg_msg_insert_different, + __dbg_msg_erase_bad, + __dbg_msg_erase_different, + __dbg_msg_subscript_oob, + __dbg_msg_empty, + __dbg_msg_unpartitioned, + __dbg_msg_unpartitioned_pred, + __dbg_msg_unsorted, + __dbg_msg_unsorted_pred, + __dbg_msg_not_heap, + __dbg_msg_not_heap_pred, + // std::bitset checks + __dbg_msg_bad_bitset_write, + __dbg_msg_bad_bitset_read, + __dbg_msg_bad_bitset_flip, + // std::list checks + __dbg_msg_self_splice, + __dbg_msg_splice_alloc, + __dbg_msg_splice_bad, + __dbg_msg_splice_other, + __dbg_msg_splice_overlap, + // iterator checks + __dbg_msg_init_singular, + __dbg_msg_init_copy_singular, + __dbg_msg_init_const_singular, + __dbg_msg_copy_singular, + __dbg_msg_bad_deref, + __dbg_msg_bad_inc, + __dbg_msg_bad_dec, + __dbg_msg_iter_subscript_oob, + __dbg_msg_advance_oob, + __dbg_msg_retreat_oob, + __dbg_msg_iter_compare_bad, + __dbg_msg_compare_different, + __dbg_msg_iter_order_bad, + __dbg_msg_order_different, + __dbg_msg_distance_bad, + __dbg_msg_distance_different, + // istream_iterator + __dbg_msg_deref_istream, + __dbg_msg_inc_istream, + // ostream_iterator + __dbg_msg_output_ostream, + // istreambuf_iterator + __dbg_msg_deref_istreambuf, + __dbg_msg_inc_istreambuf + }; + + class _Error_formatter + { + /// Whether an iterator is constant, mutable, or unknown + enum _Constness + { + __unknown_constness, + __const_iterator, + __mutable_iterator, + __last_constness + }; + + // The state of the iterator (fine-grained), if we know it. + enum _Iterator_state + { + __unknown_state, + __singular, // singular, may still be attached to a sequence + __begin, // dereferenceable, and at the beginning + __middle, // dereferenceable, not at the beginning + __end, // past-the-end, may be at beginning if sequence empty + __last_state + }; + + // Tags denoting the type of parameter for construction + struct _Is_iterator {}; + struct _Is_sequence {}; + + // A parameter that may be referenced by an error message + struct _Parameter + { + enum + { + __unused_param, + __iterator, + __sequence, + __integer, + __string + } _M_kind; + + union + { + // When _M_kind == __iterator + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + _Constness _M_constness; + _Iterator_state _M_state; + const void* _M_sequence; + const type_info* _M_seq_type; + } _M_iterator; + + // When _M_kind == __sequence + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + } _M_sequence; + + // When _M_kind == __integer + struct + { + const char* _M_name; + long _M_value; + } _M_integer; + + // When _M_kind == __string + struct + { + const char* _M_name; + const char* _M_value; + } _M_string; + } _M_variant; + + _Parameter() : _M_kind(__unused_param) { } + + _Parameter(long __value, const char* __name) + : _M_kind(__integer) + { + _M_variant._M_integer._M_name = __name; + _M_variant._M_integer._M_value = __value; + } + + _Parameter(const char* __value, const char* __name) + : _M_kind(__string) + { + _M_variant._M_string._M_name = __name; + _M_variant._M_string._M_value = __value; + } + + template + _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it, + const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = + __gnu_cxx::__is_same<_Safe_iterator<_Iterator, _Sequence>, + typename _Sequence::iterator>:: + value? __mutable_iterator : __const_iterator; + _M_variant._M_iterator._M_sequence = __it._M_get_sequence(); + _M_variant._M_iterator._M_seq_type = &typeid(_Sequence); + + if (__it._M_singular()) + _M_variant._M_iterator._M_state = __singular; + else + { + bool __is_begin = __it._M_is_begin(); + bool __is_end = __it._M_is_end(); + if (__is_end) + _M_variant._M_iterator._M_state = __end; + else if (__is_begin) + _M_variant._M_iterator._M_state = __begin; + else + _M_variant._M_iterator._M_state = __middle; + } + } + + template + _Parameter(const _Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __mutable_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(_Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __const_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(const _Iterator& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator) + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __unknown_constness; + _M_variant._M_iterator._M_state = + __gnu_debug::__check_singular(__it)? __singular : __unknown_state; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(const _Safe_sequence<_Sequence>& __seq, + const char* __name, _Is_sequence) + : _M_kind(__sequence) + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = + static_cast(&__seq); + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + template + _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence) + : _M_kind(__sequence) + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = &__seq; + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + void + _M_print_field(const _Error_formatter* __formatter, + const char* __name) const; + + void + _M_print_description(const _Error_formatter* __formatter) const; + }; + friend struct _Parameter; + + public: + template + const _Error_formatter& + _M_iterator(const _Iterator& __it, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__it, __name, + _Is_iterator()); + return *this; + } + + const _Error_formatter& + _M_integer(long __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + const _Error_formatter& + _M_string(const char* __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + template + const _Error_formatter& + _M_sequence(const _Sequence& __seq, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name, + _Is_sequence()); + return *this; + } + + const _Error_formatter& + _M_message(const char* __text) const + { _M_text = __text; return *this; } + + const _Error_formatter& + _M_message(_Debug_msg_id __id) const; + + void + _M_error() const; + + private: + _Error_formatter(const char* __file, size_t __line) + : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), + _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) + { } + + void + _M_print_word(const char* __word) const; + + void + _M_print_string(const char* __string) const; + + enum { __max_parameters = 9 }; + + const char* _M_file; + size_t _M_line; + mutable _Parameter _M_parameters[__max_parameters]; + mutable size_t _M_num_parameters; + mutable const char* _M_text; + mutable size_t _M_max_length; + enum { _M_indent = 4 } ; + mutable size_t _M_column; + mutable bool _M_first_line; + mutable bool _M_wordwrap; + + public: + static _Error_formatter + _M_at(const char* __file, size_t __line) + { return _Error_formatter(__file, __line); } + }; + } // namespace __gnu_debug + + #endif /* _GLIBCXX_DEBUG_FORMATTER_H */ Index: include/debug/hash_map =================================================================== RCS file: include/debug/hash_map diff -N include/debug/hash_map *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/hash_map 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,50 ---- + // Debugging hash_map/hash_multimap implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_HASH_MAP_H + #define _GLIBCXX_EXT_DEBUG_HASH_MAP_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have a debug implementation in __gnu_cxx::, so pull it in. + namespace __gnu_debug + { + using __gnu_cxx::hash_map; + using __gnu_cxx::hash_multimap; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_HASH_MAP_H */ Index: include/debug/hash_set =================================================================== RCS file: include/debug/hash_set diff -N include/debug/hash_set *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/hash_set 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,50 ---- + // Debugging hash_set/hash_multiset implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_HASH_SET_H + #define _GLIBCXX_EXT_DEBUG_HASH_SET_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have debug implementations in __gnu_cxx::, so pull them in. + namespace __gnu_debug + { + using __gnu_cxx::hash_set; + using __gnu_cxx::hash_multiset; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_HASH_SET_H */ Index: include/debug/list =================================================================== RCS file: include/debug/list diff -N include/debug/list *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/list 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,48 ---- + // Debugging list implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_LIST_H + #define _GLIBCXX_EXT_DEBUG_LIST_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have a debug implementation in std::, so pull it in. + namespace __gnu_debug + { + using std::list; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_LIST_H */ Index: include/debug/map =================================================================== RCS file: include/debug/map diff -N include/debug/map *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/map 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,50 ---- + // Debugging map/multimap implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_MAP_H + #define _GLIBCXX_EXT_DEBUG_MAP_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have a debug implementation in std::, so pull it in. + namespace __gnu_debug + { + using std::map; + using std::multimap; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_MAP_H */ Index: include/debug/safe_base.h =================================================================== RCS file: include/debug/safe_base.h diff -N include/debug/safe_base.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/safe_base.h 13 Aug 2003 18:42:38 -0000 *************** *** 0 **** --- 1,200 ---- + // Safe sequence/iterator base implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_SAFE_BASE_H + #define _GLIBCXX_DEBUG_SAFE_BASE_H + + namespace __gnu_debug + { + class _Safe_sequence_base; + + /** \brief Basic functionality for a "safe" iterator. + * + * The %_Safe_iterator_base base class implements the functionality + * of a safe iterator that is not specific to a particular iterator + * type. It contains a pointer back to the sequence it references + * along with iterator version information and pointers to form a + * doubly-linked list of iterators referenced by the container. + * + * This class must not perform any operations that can throw an + * exception, or the exception guarantees of derived iterators will + * be broken. + */ + class _Safe_iterator_base + { + public: + /** The sequence this iterator references; may be NULL to indicate + a singular iterator. */ + _Safe_sequence_base* _M_sequence; + + /** The version number of this iterator. The sentinel value 0 is + used to indicate an invalidated iterator (i.e., one that is + singular because of an operation on the container). This + version number must equal the version number in the sequence + referenced by _M_sequence for the iterator to be + non-singular. */ + unsigned int _M_version; + + /** Pointer to the previous iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_prior; + + /** Pointer to the next iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_next; + + protected: + /** Initializes the iterator and makes it singular. */ + _Safe_iterator_base() + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { } + + /** Initialize the iterator to reference the sequence pointed to + by @p__seq. @p __constant is true when we are initializing a + constant iterator, and false if it is a mutable iterator. Note + that @p __seq may be NULL, in which case the iterator will be + singular. Otherwise, the iterator will reference @p __seq and + be nonsingular. */ + _Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); } + + /** Initializes the iterator to reference the same sequence that + @p __x does. @p __constant is true if this is a constant + iterator, and false if it is mutable. */ + _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(__x._M_sequence, __constant); } + + ~_Safe_iterator_base() { this->_M_detach(); } + + public: + /** Attaches this iterator to the given sequence, detaching it + * from whatever sequence it was attached to originally. If the + * new sequence is the NULL pointer, the iterator is left + * unattached. + */ + void _M_attach(_Safe_sequence_base* __seq, bool __constant); + + /** Detach the iterator for whatever sequence it is attached to, + * if any. + */ + void _M_detach(); + + /** Determines if we are attached to the given sequence. */ + bool _M_attached_to(const _Safe_sequence_base* __seq) const + { return _M_sequence == __seq; } + + /** Is this iterator singular? */ + bool _M_singular() const; + + /** Can we compare this iterator to the given iterator @p __x? + Returns true if both iterators are nonsingular and reference + the same sequence. */ + bool _M_can_compare(const _Safe_iterator_base& __x) const; + }; + + /** + * @brief Base class that supports tracking of iterators that + * reference a sequence. + * + * The %_Safe_sequence_base class provides basic support for + * tracking iterators into a sequence. Sequences that track + * iterators must derived from %_Safe_sequence_base publicly, so + * that safe iterators (which inherit _Safe_iterator_base) can + * attach to them. This class contains two linked lists of + * iterators, one for constant iterators and one for mutable + * iterators, and a version number that allows very fast + * invalidation of all iterators that reference the container. + * + * This class must ensure that no operation on it may throw an + * exception, otherwise "safe" sequences may fail to provide the + * exception-safety guarantees required by the C++ standard. + */ + class _Safe_sequence_base + { + public: + /// The list of mutable iterators that reference this container + _Safe_iterator_base* _M_iterators; + + /// The list of constant iterators that reference this container + _Safe_iterator_base* _M_const_iterators; + + /// The container version number. This number may never be 0. + mutable unsigned int _M_version; + + protected: + // Initialize with a version number of 1 and no iterators + _Safe_sequence_base() + : _M_iterators(0), _M_const_iterators(0), _M_version(1) + { } + + /** Notify all iterators that reference this sequence that the + sequence is being destroyed. */ + ~_Safe_sequence_base() + { this->_M_detach_all(); } + + /** Detach all iterators, leaving them singular. */ + void + _M_detach_all(); + + /** Detach all singular iterators. + * @post for all iterators i attached to this sequence, + * i->_M_version == _M_version. + */ + void + _M_detach_singular(); + + /** Revalidates all attached singular iterators. This method + * may be used to validate iterators that were invalidated + * before (but for some reasion, such as an exception, need to + * become valid again). + */ + void + _M_revalidate_singular(); + + /** Swap this sequence with the given sequence. This operation + also swaps ownership of the iterators, so that when the + operation is complete all iterators that originally + referenced one container now reference the other + container. */ + void + _M_swap(_Safe_sequence_base& __x); + + public: + /** Invalidates all iterators. */ + void + _M_invalidate_all() const + { if (++_M_version == 0) _M_version = 1; } + }; + + } // namespace __gnu_debug + + #endif /* _GLIBCXX_DEBUG_SAFE_BASE_H */ Index: include/debug/safe_iterator.h =================================================================== RCS file: include/debug/safe_iterator.h diff -N include/debug/safe_iterator.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/safe_iterator.h 13 Aug 2003 18:42:39 -0000 *************** *** 0 **** --- 1,589 ---- + // Safe iterator implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H + #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H + + #include + #include + #include + #include + + namespace __gnu_debug + { + using namespace std; + + /** Iterators that derive from _Safe_iterator_base but that aren't + _Safe_iterators can be determined singular or non-singular via + _Safe_iterator_base. */ + inline bool __check_singular_aux(const _Safe_iterator_base* __x) + { return __x->_M_singular(); } + + /** \brief Safe iterator wrapper. + * + * The class template %_Safe_iterator is a wrapper around an + * iterator that tracks the iterator's movement among sequences and + * checks that operations performed on the "safe" iterator are + * legal. In additional to the basic iterator operations (which are + * validated, and then passed to the underlying iterator), + * %_Safe_iterator has member functions for iterator invalidation, + * attaching/detaching the iterator from sequences, and querying + * the iterator's state. + */ + template + class _Safe_iterator : public _Safe_iterator_base + { + typedef _Safe_iterator _Self; + + /** The precision to which we can calculate the distance between + * two iterators. + */ + enum _Distance_precision + { + __dp_equality, //< Can compare iterator equality, only + __dp_sign, //< Can determine equality and ordering + __dp_exact //< Can determine distance precisely + }; + + /// The underlying iterator + _Iterator _M_current; + + /// Determine if this is a constant iterator. + bool _M_constant() const + { + typedef typename _Sequence::const_iterator const_iterator; + return __gnu_cxx::__is_same::value; + } + + typedef iterator_traits<_Iterator> _Traits; + + public: + typedef typename _Traits::iterator_category iterator_category; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; + + /// @post the iterator is singular and unattached + _Safe_iterator() : _M_current() { } + + /** + * @brief Safe iterator construction from an unsafe iterator and + * its sequence. + * + * @pre @p seq is not NULL + * @post this is not singular + */ + _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) + : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__dbg_msg_init_singular) + ._M_iterator(*this, "this")); + } + + /** + * @brief Copy construction. + * @pre @p x is not singular + */ + _Safe_iterator(const _Safe_iterator& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__dbg_msg_init_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Converting constructor from a mutable iterator to a + * constant iterator. + * + * @pre @p x is not singular + */ + template + _Safe_iterator(const _Safe_iterator<_MutableIterator, _Sequence>& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__dbg_msg_init_const_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Copy assignment. + * @pre @p x is not singular + */ + _Safe_iterator& operator=(const _Safe_iterator& __x) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__dbg_msg_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + _M_current = __x._M_current; + this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); + return *this; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + */ + reference operator*() const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__dbg_msg_bad_deref) + ._M_iterator(*this, "this")); + return *_M_current; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + * @todo Make this correct w.r.t. iterators that return proxies + * @todo Use addressof() instead of & operator + */ + pointer operator->() const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__dbg_msg_bad_deref) + ._M_iterator(*this, "this")); + return &*_M_current; + } + + // ------ Input iterator requirements ------ + /** + * @brief Iterator preincrement + * @pre iterator is incrementable + */ + _Safe_iterator& operator++() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__dbg_msg_bad_inc) + ._M_iterator(*this, "this")); + ++_M_current; + return *this; + } + + /** + * @brief Iterator postincrement + * @pre iterator is incrementable + */ + _Safe_iterator operator++(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__dbg_msg_bad_inc) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + ++_M_current; + return __tmp; + } + + // ------ Bidirectional iterator requirements ------ + /** + * @brief Iterator predecrement + * @pre iterator is decrementable + */ + _Safe_iterator& operator--() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__dbg_msg_bad_dec) + ._M_iterator(*this, "this")); + --_M_current; + return *this; + } + + /** + * @brief Iterator postdecrement + * @pre iterator is decrementable + */ + _Safe_iterator operator--(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__dbg_msg_bad_dec) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + --_M_current; + return __tmp; + } + + // ------ Random access iterator requirements ------ + reference operator[](const difference_type& __n) const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) + && this->_M_can_advance(__n+1), + _M_message(__dbg_msg_iter_subscript_oob) + ._M_iterator(*this)._M_integer(__n)); + + return _M_current[__n]; + } + + _Safe_iterator& operator+=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), + _M_message(__dbg_msg_advance_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += __n; + return *this; + } + + _Safe_iterator operator+(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp += __n; + return __tmp; + } + + _Safe_iterator& operator-=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), + _M_message(__dbg_msg_retreat_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += -__n; + return *this; + } + + _Safe_iterator operator-(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp -= __n; + return __tmp; + } + + // ------ Utilities ------ + /** + * @brief Return the underlying iterator + */ + _Iterator base() const { return _M_current; } + + /** + * @brief Conversion to underlying non-debug iterator to allow + * better interaction with non-debug containers. + */ + operator _Iterator() const { return _M_current; } + + /** Attach iterator to the given sequence. */ + void _M_attach(const _Sequence* __seq) + { + _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), + _M_constant()); + } + + /** Invalidate the iterator, making it singular. */ + void _M_invalidate(); + + /// Is the iterator dereferenceable? + bool _M_dereferenceable() const + { return !this->_M_singular() && !_M_is_end(); } + + /// Is the iterator incrementable? + bool _M_incrementable() const { return this->_M_dereferenceable(); } + + // Is the iterator decrementable? + bool _M_decrementable() const + { return !_M_singular() && !_M_is_begin(); } + + // Can we advance the iterator @p __n steps (@p __n may be negative) + bool _M_can_advance(const difference_type& __n) const; + + // Is the iterator range [*this, __rhs) valid? + template + bool + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; + + // The sequence this iterator references. + const _Sequence* _M_get_sequence() const + { return static_cast(_M_sequence); } + + /** Determine the distance between two iterators with some known + * precision. + */ + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) + { + typedef typename iterator_traits<_Iterator1>::iterator_category + _Category; + return _M_get_distance(__lhs, __rhs, _Category()); + } + + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::random_access_iterator_tag) + { + return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); + } + + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::forward_iterator_tag) + { + return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, + __dp_equality); + } + + /// Is this iterator equal to the sequence's begin() iterator? + bool _M_is_begin() const + { return *this == static_cast(_M_sequence)->begin(); } + + /// Is this iterator equal to the sequence's end() iterator? + bool _M_is_end() const + { return *this == static_cast(_M_sequence)->end(); } + }; + + template + inline bool + operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template + inline bool + operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template + inline bool + operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template + inline bool + operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template + inline bool + operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template + inline bool + operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template + inline bool + operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template + inline bool + operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template + inline bool + operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template + inline bool + operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template + inline bool + operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + template + inline bool + operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type + operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__dbg_msg_distance_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__dbg_msg_distance_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() - __rhs.base(); + } + + template + inline _Safe_iterator<_Iterator, _Sequence> + operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, + const _Safe_iterator<_Iterator, _Sequence>& __i) + { return __i + __n; } + } // namespace __gnu_debug + + #ifndef _GLIBCXX_EXPORT_TEMPLATE + # include + #endif + + #endif /* _GLIBCXX_DEBUG_SAFE_ITERATOR_H */ + + Index: include/debug/safe_iterator.tcc =================================================================== RCS file: include/debug/safe_iterator.tcc diff -N include/debug/safe_iterator.tcc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/safe_iterator.tcc 13 Aug 2003 18:42:39 -0000 *************** *** 0 **** --- 1,140 ---- + // Debugging iterator implementation (out of line) -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + /** @file safe_iterator.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + + #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC + #define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC + + namespace __gnu_debug + { + template + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_can_advance(const difference_type& __n) const + { + typedef typename _Sequence::const_iterator const_iterator; + + if (this->_M_singular()) + return false; + if (__n == 0) + return true; + if (__n < 0) + { + const_iterator __begin = + static_cast(_M_sequence)->begin(); + pair __dist = + this->_M_get_distance(__begin, *this); + bool __ok = (__dist.second == __dp_exact && __dist.first >= -__n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + else + { + const_iterator __end = + static_cast(_M_sequence)->end(); + pair __dist = + this->_M_get_distance(*this, __end); + bool __ok = (__dist.second == __dp_exact && __dist.first >= __n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + } + + template + template + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const + { + if (!_M_can_compare(__rhs)) + return false; + + /* Determine if we can order the iterators without the help of + the container */ + pair __dist = + this->_M_get_distance(*this, __rhs); + switch (__dist.second) { + case __dp_equality: + if (__dist.first == 0) + return true; + break; + + case __dp_sign: + case __dp_exact: + return __dist.first >= 0; + } + + /* We can only test for equality, but check if one of the + iterators is at an extreme. */ + if (_M_is_begin() || __rhs._M_is_end()) + return true; + else if (_M_is_end() || __rhs._M_is_begin()) + return false; + + // Assume that this is a valid range; we can't check anything else + return true; + } + + template + void + _Safe_iterator<_Iterator, _Sequence>:: + _M_invalidate() + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + if (!this->_M_singular()) + { + for (_Safe_iterator_base* iter = _M_sequence->_M_iterators; iter; ) + { + iterator* __victim = static_cast(iter); + iter = iter->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + for (_Safe_iterator_base* iter = _M_sequence->_M_const_iterators; + iter; /* increment in loop */) + { + const_iterator* __victim = static_cast(iter); + iter = iter->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + _M_version = 0; + } + } + } // namespace __gnu_debug + + #endif /* _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC */ + Index: include/debug/safe_sequence.h =================================================================== RCS file: include/debug/safe_sequence.h diff -N include/debug/safe_sequence.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/safe_sequence.h 13 Aug 2003 18:42:39 -0000 *************** *** 0 **** --- 1,182 ---- + // Safe sequence implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H + #define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H + + #include + #include + + namespace __gnu_debug + { + using namespace std; + + template class _Safe_iterator; + + /** A simple function object that returns true if the passed-in + value is not equal to the stored value. It saves typing over + using both bind1st and not_equal. */ + template + class _Not_equal_to + { + _Type __value; + + public: + explicit _Not_equal_to(const _Type& __v) : __value(__v) { } + + bool + operator()(const _Type& __x) const + { return __value != __x; } + }; + + /** A function object that returns true when the given random access + iterator is at least @c n steps away from the given iterator. */ + template + class _After_nth_from + { + typedef typename std::iterator_traits<_Iterator>::difference_type + difference_type; + + _Iterator _M_base; + difference_type _M_n; + + public: + _After_nth_from(const difference_type& __n, const _Iterator& __base) + : _M_base(__base), _M_n(__n) + { } + + bool + operator()(const _Iterator& __x) const + { return __x - _M_base >= _M_n; } + }; + + /** + * @brief Base class for constructing a "safe" sequence type that + * tracks iterators that reference it. + * + * The class template %_Safe_sequence simplifies the construction + * of "safe" sequences that track the iterators that reference the + * sequence, so that the iterators are notified of changes in the + * sequence that may affect their operation, e.g., if the + * container invalidates its iterators or is destructed. This + * class template may only be used by deriving from it and passing + * the name of the derived class as its template parameter via the + * curiously recurring template pattern. The derived class must + * have @c iterator and @const_iterator types that are + * instantiations of class template _Safe_iterator for this + * sequence. Iterators will then be tracked automatically. + */ + template + class _Safe_sequence : public _Safe_sequence_base + { + public: + /** Invalidates all iterators @c x that reference this sequence, + are not singular, and for which @c pred(x) returns @c + true. The user of this routine should be careful not to make + copies of the iterators passed to @p pred, as the copies may + interfere with the invalidation. */ + template + void + _M_invalidate_if(_Predicate __pred); + + /** Transfers all iterators that reference this memory location + to this sequence from whatever sequence they are attached + to. */ + template + void + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x); + }; + + template + template + void + _Safe_sequence<_Sequence>:: + _M_invalidate_if(_Predicate __pred) + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = _M_iterators; __iter; ) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + + for (_Safe_iterator_base* __iter = _M_const_iterators; __iter; ) + { + const_iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + } + + template + template + void + _Safe_sequence<_Sequence>:: + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x) + { + _Safe_sequence_base* __from = __x._M_sequence; + if (!__from) + return; + + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter; ) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + + for (_Safe_iterator_base* __iter = __from->_M_const_iterators; __iter;) + { + const_iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + } + } // namespace __gnu_debug + + #endif /* _GLIBCXX_DEBUG_SAFE_SEQUENCE_H */ + + Index: include/debug/set =================================================================== RCS file: include/debug/set diff -N include/debug/set *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/set 13 Aug 2003 18:42:39 -0000 *************** *** 0 **** --- 1,50 ---- + // Debugging set/multiset implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_SET_H + #define _GLIBCXX_EXT_DEBUG_SET_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have a debug implementation in std::, so pull it in. + namespace __gnu_debug + { + using std::set; + using std::multiset; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_SET_H */ Index: include/debug/string =================================================================== RCS file: include/debug/string diff -N include/debug/string *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/string 13 Aug 2003 18:42:39 -0000 *************** *** 0 **** --- 1,1008 ---- + // Debugging string implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_DEBUG_STRING_H + #define _GLIBCXX_DEBUG_STRING_H + + #include + #include + #include + + namespace __gnu_debug + { + + template, + class _Allocator = std::allocator<_CharT> > + class basic_string + : public std::basic_string<_CharT, _Traits, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::size_type size_type; + typedef typename _Allocator::difference_type difference_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::npos; + + // 21.3.1 construct/copy/destroy: + explicit basic_string(const _Allocator& __a = _Allocator()) + : _Base(__a) + { } + + // Provides conversion from a release-mode string to a debug-mode string + basic_string(const _Base& __base) : _Base(__base), _Safe_base() { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str) + : _Base(__str, 0, _Base::npos, __str.get_allocator()), _Safe_base() + { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str, size_type __pos, + size_type __n = _Base::npos, + const _Allocator& __a = _Allocator()) + : _Base(__str, __pos, __n, __a) + { } + + basic_string(const _CharT* __s, size_type __n, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) + { } + + basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s), __a) + { this->assign(__s); } + + basic_string(size_type __n, _CharT __c, + const _Allocator& __a = _Allocator()) + : _Base(__n, __c, __a) + { } + + template + basic_string(_InputIterator __begin, _InputIterator __end, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__begin, __end), __end, __a) + { } + + ~basic_string() { } + + basic_string& + operator=(const basic_string& __str) + { + *static_cast<_Base*>(this) = __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(const _CharT* __s) + { + __glibcxx_check_string(__s); + *static_cast<_Base*>(this) = __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(_CharT __c) + { + *static_cast<_Base*>(this) = __c; + this->_M_invalidate_all(); + return *this; + } + + // 21.3.2 iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 21.3.3 capacity: + using _Base::size; + using _Base::length; + using _Base::max_size; + + void + resize(size_type __n, _CharT __c) + { + _Base::resize(__n, __c); + this->_M_invalidate_all(); + } + + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + using _Base::capacity; + using _Base::reserve; + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::empty; + + // 21.3.4 element access: + const_reference + operator[](size_type __pos) const + { + _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), + _M_message(::__gnu_debug::__dbg_msg_subscript_oob) + ._M_sequence(*this, "this") + ._M_integer(__pos, "__pos") + ._M_integer(this->size(), "size")); + return _M_base()[__pos]; + } + + reference + operator[](size_type __pos) + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::at; + + // 21.3.5 modifiers: + basic_string& + operator+=(const basic_string& __str) + { + _M_base() += __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(const _CharT* __s) + { + __glibcxx_check_string(__s); + _M_base() += __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(_CharT __c) + { + _M_base() += __c; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str) + { + _Base::append(__str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::append(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::append(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::append(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(size_type __n, _CharT __c) + { + _Base::append(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + append(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::append(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 7. string clause minor problems + void + push_back(_CharT __c) + { + _Base::push_back(__c); + this->_M_invalidate_all(); + } + + basic_string& + assign(const basic_string& __x) + { + _Base::assign(__x); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::assign(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::assign(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::assign(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(size_type __n, _CharT __c) + { + _Base::assign(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str) + { + _Base::insert(__pos1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { + _Base::insert(__pos1, __str, __pos2, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { + _Base::insert(__pos, __n, __c); + this->_M_invalidate_all(); + return *this; + } + + iterator + insert(iterator __p, _CharT __c) + { + __glibcxx_check_insert(__p); + typename _Base::iterator __result = _Base::insert(__p.base(), __c); + this->_M_invalidate_all(); + return iterator(__result, this); + } + + void + insert(iterator __p, size_type __n, _CharT __c) + { + __glibcxx_check_insert(__p); + _Base::insert(__p.base(), __n, __c); + this->_M_invalidate_all(); + } + + template + void + insert(iterator __p, _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__p, __first, __last); + _Base::insert(__p.base(), __first, __last); + this->_M_invalidate_all(); + } + + basic_string& + erase(size_type __pos = 0, size_type __n = _Base::npos) + { + _Base::erase(__pos, __n); + this->_M_invalidate_all(); + return *this; + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + typename _Base::iterator __result = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__result, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + typename _Base::iterator __result = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__result, this); + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str) + { + _Base::replace(__pos1, __n1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { + _Base::replace(__pos1, __n1, __str, __pos2, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_check_string_len(__s, __n2); + _Base::replace(__pos, __n1, __s, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::replace(__pos, __n1, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { + _Base::replace(__pos, __n1, __n2, __c); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string_len(__s, __n); + _Base::replace(__i1.base(), __i2.base(), __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string(__s); + _Base::replace(__i1.base(), __i2.base(), __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __j1, _InputIterator __j2) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_valid_range(__j1, __j2); + _Base::replace(__i1.base(), __i2.base(), __j1, __j2); + this->_M_invalidate_all(); + return *this; + } + + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::copy(__s, __n, __pos); + } + + void + swap(basic_string<_CharT,_Traits,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + this->_M_invalidate_all(); + __x._M_invalidate_all(); + } + + // 21.3.6 string operations: + const _CharT* + c_str() const + { + const _CharT* __result = _Base::c_str(); + this->_M_invalidate_all(); + return __result; + } + + const _CharT* + data() const + { + const _CharT* __result = _Base::data(); + this->_M_invalidate_all(); + return __result; + } + + using _Base::get_allocator; + + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return _Base::find(__str, __pos); } + + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos, __n); + } + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos); + } + + size_type + find(_CharT __c, size_type __pos = 0) const + { return _Base::find(__c, __pos); } + + size_type + rfind(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::rfind(__str, __pos); } + + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::rfind(__s, __pos, __n); + } + + size_type + rfind(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::rfind(__s, __pos); + } + + size_type + rfind(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::rfind(__c, __pos); } + + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_of(__str, __pos); } + + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos, __n); + } + + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos); + } + + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_of(__c, __pos); } + + size_type + find_last_of(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__str, __pos); } + + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos, __n); + } + + size_type + find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos); + } + + size_type + find_last_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__c, __pos); } + + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_not_of(__str, __pos); } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::find_first_not_of(__s, __pos, __n); + } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_not_of(__s, __pos); + } + + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_not_of(__c, __pos); } + + size_type + find_last_not_of(const basic_string& __str, + size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__str, __pos); } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos, __n); + } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos); + } + + size_type + find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__c, __pos); } + + basic_string + substr(size_type __pos = 0, size_type __n = _Base::npos) const + { return basic_string(_Base::substr(__pos, __n)); } + + int + compare(const basic_string& __str) const + { return _Base::compare(__str); } + + int + compare(size_type __pos1, size_type __n1, + const basic_string& __str) const + { return _Base::compare(__pos1, __n1, __str); } + + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } + + int + compare(const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1, const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__pos1, __n1, __s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1,const _CharT* __s, + size_type __n2) const + { + __glibcxx_check_string_len(__s, __n2); + return _Base::compare(__pos1, __n1, __s, __n2); + } + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + using _Safe_base::_M_invalidate_all; + }; + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(_CharT __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + _CharT __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs == __rhs._M_base(); + } + + template + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() == __rhs; + } + + template + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs != __rhs._M_base(); + } + + template + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() != __rhs; + } + + template + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs < __rhs._M_base(); + } + + template + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() < __rhs; + } + + template + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs <= __rhs._M_base(); + } + + template + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() <= __rhs; + } + + template + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs >= __rhs._M_base(); + } + + template + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() >= __rhs; + } + + template + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs > __rhs._M_base(); + } + + template + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() > __rhs; + } + + // 21.3.7.8: + template + inline void + swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, + basic_string<_CharT,_Traits,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + template + std::basic_istream<_CharT,_Traits>& + operator>>(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __result = __is >> __str._M_base(); + __str._M_invalidate_all(); + return __result; + } + + template + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT,_Traits,_Allocator>& __str) + { return __os << __str._M_base(); } + + template + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str, + _CharT __delim) + { + std::basic_istream<_CharT,_Traits>& __result = getline(__is, + __str._M_base(), + __delim); + __str._M_invalidate_all(); + return __result; + } + + template + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __result = getline(__is, + __str._M_base()); + __str._M_invalidate_all(); + return __result; + } + + typedef basic_string string; + + # ifdef _GLIBCXX_USE_WCHAR_T + typedef basic_string wstring; + # endif + + } // namespace __gnu_debug + + #endif /* _GLIBCXX_DEBUG_STRING_H */ Index: include/debug/support.h =================================================================== RCS file: include/debug/support.h diff -N include/debug/support.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/support.h 13 Aug 2003 18:42:39 -0000 *************** *** 0 **** --- 1,44 ---- + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + #ifndef _GLIBCXX_DEBUG_SUPPORT_H + #define _GLIBCXX_DEBUG_SUPPORT_H + + // Internal macros + #ifdef _GLIBCXX_DEBUG + # define _GLIBCXX_NAMESPACE_DEBUG(_Ns) _Ns + # define _GLIBCXX_DEBUG_BASE(_Ns, _Class) _Ns::_Release_##_Class + # define _GLIBCXX_RELEASE_CLASS(_Name) __attribute__((__link_name__(#_Name))) _Release_##_Name + # define _GLIBCXX_DEBUG_CLASS(_Name) __attribute__((__link_name__("_Debug_" #_Name))) _Name + #else + # define _GLIBCXX_NAMESPACE_DEBUG(_Ns) __gnu_debug + # define _GLIBCXX_DEBUG_BASE(_Ns, _Class) _Ns::_Class + # define _GLIBCXX_RELEASE_CLASS(_Name) _Name + # define _GLIBCXX_DEBUG_CLASS(_Name) _Name + #endif + + #endif /* _GLIBCXX_DEBUG_SUPPORT_H */ Index: include/debug/vector =================================================================== RCS file: include/debug/vector diff -N include/debug/vector *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/debug/vector 13 Aug 2003 18:42:39 -0000 *************** *** 0 **** --- 1,48 ---- + // Debugging vector implementation -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #ifndef _GLIBCXX_EXT_DEBUG_VECTOR_H + #define _GLIBCXX_EXT_DEBUG_VECTOR_H + + #include + + #ifdef _GLIBCXX_DEBUG + // We already have a debug implementation in std::, so pull it in. + namespace __gnu_debug + { + using std::vector; + } // namespace __gnu_debug + + #else + // Include the debug implementation, which will reside in __gnu_debug + # include + #endif + + #endif /* _GLIBCXX_EXT_DEBUG_VECTOR_H */ Index: include/ext/algorithm =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/ext/algorithm,v retrieving revision 1.8 diff -c -3 -p -r1.8 algorithm *** include/ext/algorithm 5 Jul 2003 04:05:37 -0000 1.8 --- include/ext/algorithm 13 Aug 2003 18:42:39 -0000 *************** namespace __gnu_cxx *** 208,213 **** --- 208,215 ---- typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); } *************** namespace __gnu_cxx *** 226,231 **** --- 228,235 ---- __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator>::value_type >) __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; *************** namespace __gnu_cxx *** 241,246 **** --- 245,252 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; *************** namespace __gnu_cxx *** 262,267 **** --- 268,274 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); *************** namespace __gnu_cxx *** 297,302 **** --- 304,310 ---- typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) + __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); *************** namespace __gnu_cxx *** 378,383 **** --- 386,393 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __out_last - __out_first); *************** namespace __gnu_cxx *** 399,444 **** __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } - // is_heap, a predicate testing whether or not a range is - // a heap. This function is an extension, not part of the C++ - // standard. - - template - bool - __is_heap(_RandomAccessIterator __first, _Distance __n) - { - _Distance __parent = 0; - for (_Distance __child = 1; __child < __n; ++__child) { - if (__first[__parent] < __first[__child]) - return false; - if ((__child & 1) == 0) - ++__parent; - } - return true; - } - - template - bool - __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp, - _Distance __n) - { - _Distance __parent = 0; - for (_Distance __child = 1; __child < __n; ++__child) { - if (__comp(__first[__parent], __first[__child])) - return false; - if ((__child & 1) == 0) - ++__parent; - } - return true; - } - /** * This is an SGI extension. * @ingroup SGIextensions --- 409,422 ---- __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } /** * This is an SGI extension. * @ingroup SGIextensions *************** namespace __gnu_cxx *** 452,459 **** __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) ! return __is_heap(__first, __last - __first); } /** --- 430,438 ---- __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); ! return std::__is_heap(__first, __last - __first); } /** *************** namespace __gnu_cxx *** 471,478 **** __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) ! return __is_heap(__first, __comp, __last - __first); } // is_sorted, a predicated testing whether a range is sorted in --- 450,458 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); ! return std::__is_heap(__first, __comp, __last - __first); } // is_sorted, a predicated testing whether a range is sorted in *************** namespace __gnu_cxx *** 492,497 **** --- 472,478 ---- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; *************** namespace __gnu_cxx *** 519,524 **** --- 500,506 ---- __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; *************** namespace __gnu_cxx *** 531,537 **** return true; } - } // namespace __gnu_cxx #endif /* _EXT_ALGORITHM */ --- 513,518 ---- Index: include/ext/hash_map =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/ext/hash_map,v retrieving revision 1.15 diff -c -3 -p -r1.15 hash_map *** include/ext/hash_map 16 Jul 2003 14:23:08 -0000 1.15 --- include/ext/hash_map 13 Aug 2003 18:42:39 -0000 *************** *** 65,70 **** --- 65,75 ---- #include #include + #ifdef _GLIBCXX_DEBUG + # define hash_map _Release_hash_map + # define hash_multimap _Release_hash_multimap + #endif + namespace __gnu_cxx { using std::equal_to; *************** namespace __gnu_cxx *** 88,94 **** */ template ! class hash_map { private: typedef hashtable,_Key,_HashFcn, --- 93,99 ---- */ template ! class _GLIBCXX_RELEASE_CLASS(hash_map) { private: typedef hashtable,_Key,_HashFcn, *************** operator==(const hash_multimap<_Key,_Tp, *** 243,249 **** * @doctodo */ template ! class hash_multimap { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) --- 248,254 ---- * @doctodo */ template ! class _GLIBCXX_RELEASE_CLASS(hash_multimap) { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) *************** swap(hash_multimap<_Key,_Tp,_HashFcn,_Eq *** 384,389 **** --- 389,401 ---- } } // namespace __gnu_cxx + + #ifdef _GLIBCXX_DEBUG + # undef hash_map + # undef hash_multimap + # include + # include + #endif namespace std { Index: include/ext/hash_set =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/ext/hash_set,v retrieving revision 1.15 diff -c -3 -p -r1.15 hash_set *** include/ext/hash_set 16 Jul 2003 14:23:08 -0000 1.15 --- include/ext/hash_set 13 Aug 2003 18:42:39 -0000 *************** *** 65,70 **** --- 65,75 ---- #include #include + #ifdef _GLIBCXX_DEBUG + # define hash_set _Release_hash_set + # define hash_multiset _Release_hash_multiset + #endif + namespace __gnu_cxx { using std::equal_to; *************** namespace __gnu_cxx *** 77,83 **** template , class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > ! class hash_set; template inline bool --- 82,88 ---- template , class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > ! class hash_set; template inline bool *************** namespace __gnu_cxx *** 90,96 **** * @doctodo */ template ! class hash_set { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) --- 95,101 ---- * @doctodo */ template ! class _GLIBCXX_RELEASE_CLASS(hash_set) { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) *************** template , class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > ! class hash_multiset; template inline bool --- 237,243 ---- class _HashFcn = hash<_Value>, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > ! class hash_multiset; template inline bool *************** operator==(const hash_multiset<_Val,_Has *** 246,252 **** * @doctodo */ template ! class hash_multiset { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) --- 251,257 ---- * @doctodo */ template ! class _GLIBCXX_RELEASE_CLASS(hash_multiset) { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) *************** swap(hash_multiset<_Val,_HashFcn,_EqualK *** 376,381 **** --- 381,393 ---- } } // namespace __gnu_cxx + + #ifdef _GLIBCXX_DEBUG + # undef hash_set + # undef hash_multiset + # include + # include + #endif namespace std { Index: include/std/std_bitset.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_bitset.h,v retrieving revision 1.19 diff -c -3 -p -r1.19 std_bitset.h *** include/std/std_bitset.h 23 Jul 2003 15:28:43 -0000 1.19 --- include/std/std_bitset.h 13 Aug 2003 18:42:39 -0000 *************** *** 64,69 **** --- 64,73 ---- #define _GLIBCXX_BITSET_WORDS(__n) \ ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD) + #ifdef _GLIBCXX_DEBUG + # define bitset _Release_bitset + #endif + namespace std { /** *************** namespace std *** 601,607 **** * @endif */ template ! class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> { private: typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; --- 605,612 ---- * @endif */ template ! class _GLIBCXX_RELEASE_CLASS(bitset) ! : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> { private: typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; *************** namespace std *** 1208,1213 **** --- 1213,1223 ---- } //@} } // namespace std + + #ifdef _GLIBCXX_DEBUG + # undef bitset + # include + #endif #undef _GLIBCXX_BITSET_WORDS #undef _GLIBCXX_BITSET_BITS_PER_WORD Index: include/std/std_memory.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_memory.h,v retrieving revision 1.10 diff -c -3 -p -r1.10 std_memory.h *** include/std/std_memory.h 23 Jul 2003 15:28:43 -0000 1.10 --- include/std/std_memory.h 13 Aug 2003 18:42:39 -0000 *************** *** 57,62 **** --- 57,63 ---- #include //for iterator_traits #include #include + #include namespace std { *************** namespace std *** 259,265 **** * what happens when you dereference one of those...) */ element_type& ! operator*() const throw() { return *_M_ptr; } /** * @brief Smart pointer dereferencing. --- 260,270 ---- * what happens when you dereference one of those...) */ element_type& ! operator*() const throw() ! { ! _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); ! return *_M_ptr; ! } /** * @brief Smart pointer dereferencing. *************** namespace std *** 268,274 **** * automatically cause to be dereferenced. */ element_type* ! operator->() const throw() { return _M_ptr; } /** * @brief Bypassing the smart pointer. --- 273,283 ---- * automatically cause to be dereferenced. */ element_type* ! operator->() const throw() ! { ! _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); ! return _M_ptr; ! } /** * @brief Bypassing the smart pointer. Index: include/std/std_valarray.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_valarray.h,v retrieving revision 1.9 diff -c -3 -p -r1.9 std_valarray.h *** include/std/std_valarray.h 23 Jul 2003 15:28:43 -0000 1.9 --- include/std/std_valarray.h 13 Aug 2003 18:42:39 -0000 *************** *** 46,51 **** --- 46,52 ---- #include #include #include + #include namespace std { *************** namespace std *** 221,232 **** template inline const _Tp& valarray<_Tp>::operator[](size_t __i) const ! { return _M_data[__i]; } template inline _Tp& valarray<_Tp>::operator[](size_t __i) ! { return _M_data[__i]; } } // std:: --- 222,239 ---- template inline const _Tp& valarray<_Tp>::operator[](size_t __i) const ! { ! __glibcxx_requires_subscript(__i); ! return _M_data[__i]; ! } template inline _Tp& valarray<_Tp>::operator[](size_t __i) ! { ! __glibcxx_requires_subscript(__i); ! return _M_data[__i]; ! } } // std:: *************** namespace std *** 260,266 **** inline valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) ! { std::__valarray_copy_construct(__p, __p + __n, _M_data); } template inline --- 267,276 ---- inline valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) ! { ! _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0); ! std::__valarray_copy_construct(__p, __p + __n, _M_data); ! } template inline *************** namespace std *** 324,329 **** --- 334,340 ---- inline valarray<_Tp>& valarray<_Tp>::operator=(const valarray<_Tp>& __v) { + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); std::__valarray_copy(__v._M_data, _M_size, _M_data); return *this; } *************** namespace std *** 340,345 **** --- 351,357 ---- inline valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) { + _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz); std::__valarray_copy(__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); return *this; *************** namespace std *** 349,354 **** --- 361,367 ---- inline valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size()); std::__valarray_copy(__ga._M_array, _Array(__ga._M_index), _Array<_Tp>(_M_data), _M_size); return *this; *************** namespace std *** 358,363 **** --- 371,377 ---- inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz); std::__valarray_copy(__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); return *this; *************** namespace std *** 367,372 **** --- 381,387 ---- inline valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz); std::__valarray_copy(__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); return *this; *************** namespace std *** 376,381 **** --- 391,397 ---- inline valarray<_Tp>& valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) { + _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size()); std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); return *this; } *************** namespace std *** 460,465 **** --- 476,482 ---- inline _Tp valarray<_Tp>::sum() const { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); return std::__valarray_sum(_M_data, _M_data + _M_size); } *************** namespace std *** 540,545 **** --- 557,563 ---- inline _Tp valarray<_Tp>::min() const { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); return *std::min_element (_M_data, _M_data+_M_size); } *************** namespace std *** 547,552 **** --- 565,571 ---- inline _Tp valarray<_Tp>::max() const { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); return *std::max_element (_M_data, _M_data+_M_size); } *************** namespace std *** 596,601 **** --- 615,621 ---- inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ { \ + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ _Array<_Tp>(__v._M_data)); \ return *this; \ *************** _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNME *** 643,648 **** --- 663,669 ---- typename __fun<_Name, _Tp>::result_type> \ operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ { \ + _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \ typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ Index: src/Makefile.am =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/src/Makefile.am,v retrieving revision 1.130 diff -c -3 -p -r1.130 Makefile.am *** src/Makefile.am 5 Aug 2003 02:00:17 -0000 1.130 --- src/Makefile.am 13 Aug 2003 18:42:39 -0000 *************** sources = \ *** 125,130 **** --- 125,131 ---- complex_io.cc \ concept-inst.cc \ ctype.cc \ + debug.cc \ demangle.cc \ ext-inst.cc \ fstream-inst.cc \ Index: src/debug.cc =================================================================== RCS file: src/debug.cc diff -N src/debug.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- src/debug.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,604 ---- + // Debugging mode support code -*- C++ -*- + + // Copyright (C) 2003 + // Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + using namespace std; + + namespace __gnu_debug + { + const char* _S_debug_messages[] = + { + "function requires a valid iterator range [%1.name;, %2.name;)", + "attempt to insert into container with a singular iterator", + "attempt to insert into container with an iterator from a different container", + "attempt to erase from container with a %2.state; iterator", + "attempt to erase from container with an iterator from a different container", + "attempt to subscript container with out-of-bounds index %2;, but container only holds %3; elements", + "attempt to access an element in an empty container", + "elements in iterator range [%1.name;, %2.name;) are not partitioned by the value %3;", + "elements in iterator range [%1.name;, %2.name;) are not partitioned by the predicate %3; and value %4;", + "elements in iterator range [%1.name;, %2.name;) are not sorted", + "elements in iterator range [%1.name;, %2.name;) are not sorted according to the predicate %3;", + "elements in iterator range [%1.name;, %2.name;) do not form a heap", + "elements in iterator range [%1.name;, %2.name;) do not form a heap with respect to the predicate %3;", + "attempt to write through a singular bitset reference", + "attempt to read from a singular bitset reference", + "attempt to flip a singular bitset reference", + "attempt to splice a list into itself", + "attempt to splice lists with inequal allocators", + "attempt to splice elements referenced by a %1.state; iterator", + "attempt to splice an iterator from a different container", + "splice destination %1.name; occurs within source range [%2.name;, %3.name;)", + "attempt to initialize an iterator that will immediately become singular", + "attempt to copy-construct an iterator from a singular iterator", + "attempt to construct a constant iterator from a singular mutable iterator", + "attempt to copy from a singular iterator", + "attempt to dereference a %1.state; iterator", + "attempt to increment a %1.state; iterator", + "attempt to decrement a %1.state; iterator", + "attempt to subscript a %1.state; iterator %2; step from its current position, which falls outside its dereferenceable range", + "attempt to advance a %1.state; iterator %2; steps, which falls outside its valid range", + "attempt to retreat a %1.state; iterator %2; steps, which falls outside its valid range", + "attempt to compare a %1.state; iterator to a %2.state; iterator", + "attempt to compare iterators from different sequences", + "attempt to order a %1.state; iterator to a %2.state; iterator", + "attempt to order iterators from different sequences", + "attempt to compute the difference between a %1.state; iterator to a %2.state; iterator", + "attempt to compute the different between two iterators from different sequences", + "attempt to dereference an end-of-stream istream_iterator", + "attempt to increment an end-of-stream istream_iterator", + "attempt to output via an ostream_iterator with no associated stream", + "attempt to dereference an end-of-stream istreambuf_iterator (this is a GNU extension)", + "attempt to increment an end-of-stream istreambuf_iterator" + }; + + void + _Safe_sequence_base:: + _M_detach_all() + { + for (_Safe_iterator_base* iter = _M_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + old->_M_attach(0, false); + } + + for (_Safe_iterator_base* iter = _M_const_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + old->_M_attach(0, true); + } + } + + void + _Safe_sequence_base:: + _M_detach_singular() + { + for (_Safe_iterator_base* iter = _M_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + if (old->_M_singular()) + old->_M_attach(0, false); + } + + for (_Safe_iterator_base* iter = _M_const_iterators; iter; ) + { + _Safe_iterator_base* old = iter; + iter = iter->_M_next; + if (old->_M_singular()) + old->_M_attach(0, true); + } + } + + void + _Safe_sequence_base:: + _M_revalidate_singular() + { + for (_Safe_iterator_base* iter = _M_iterators; iter; + iter = iter->_M_next) + { + iter->_M_version = _M_version; + iter = iter->_M_next; + } + + for (_Safe_iterator_base* iter = _M_const_iterators; iter; + iter = iter->_M_next) + { + iter->_M_version = _M_version; + iter = iter->_M_next; + } + } + + void + _Safe_sequence_base:: + _M_swap(_Safe_sequence_base& __x) + { + swap(_M_iterators, __x._M_iterators); + swap(_M_const_iterators, __x._M_const_iterators); + swap(_M_version, __x._M_version); + for (_Safe_iterator_base* iter = _M_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = this; + for (_Safe_iterator_base* iter = __x._M_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = &__x; + for (_Safe_iterator_base* iter = _M_const_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = this; + for (_Safe_iterator_base* iter = __x._M_const_iterators; iter; iter = iter->_M_next) + iter->_M_sequence = &__x; + } + + void + _Safe_iterator_base:: + _M_attach(_Safe_sequence_base* __seq, bool __constant) + { + _M_detach(); + + // Attach to the new sequence (if there is one) + if (__seq) + { + _M_sequence = __seq; + _M_version = _M_sequence->_M_version; + _M_prior = 0; + if (__constant) + { + _M_next = _M_sequence->_M_const_iterators; + if (_M_next) + _M_next->_M_prior = this; + _M_sequence->_M_const_iterators = this; + } + else + { + _M_next = _M_sequence->_M_iterators; + if (_M_next) + _M_next->_M_prior = this; + _M_sequence->_M_iterators = this; + } + } + } + + void + _Safe_iterator_base:: + _M_detach() + { + if (_M_sequence) + { + // Remove us from this sequence's list + if (_M_prior) _M_prior->_M_next = _M_next; + if (_M_next) _M_next->_M_prior = _M_prior; + + if (_M_sequence->_M_const_iterators == this) + _M_sequence->_M_const_iterators = _M_next; + if (_M_sequence->_M_iterators == this) + _M_sequence->_M_iterators = _M_next; + } + + _M_sequence = 0; + _M_version = 0; + _M_prior = 0; + _M_next = 0; + } + + bool + _Safe_iterator_base:: + _M_singular() const + { return !_M_sequence || _M_version != _M_sequence->_M_version; } + + bool + _Safe_iterator_base:: + _M_can_compare(const _Safe_iterator_base& __x) const + { + return (! _M_singular() && !__x._M_singular() + && _M_sequence == __x._M_sequence); + } + + void + _Error_formatter::_Parameter:: + _M_print_field(const _Error_formatter* __formatter, + const char* __name) const + { + assert(this->_M_kind != _Parameter::__unused_param); + const int bufsize = 64; + char buf[bufsize]; + + if (_M_kind == __iterator) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_iterator._M_name); + __formatter->_M_print_word(_M_variant._M_iterator._M_name); + } + else if (strcmp(__name, "address") == 0) + { + snprintf(buf, bufsize, "%p", _M_variant._M_iterator._M_address); + __formatter->_M_print_word(buf); + } + else if (strcmp(__name, "type") == 0) + { + assert(_M_variant._M_iterator._M_type); + // TBD: demangle! + __formatter->_M_print_word(_M_variant._M_iterator._M_type->name()); + } + else if (strcmp(__name, "constness") == 0) + { + static const char* __constness_names[__last_constness] = + { + "", + "constant", + "mutable" + }; + __formatter->_M_print_word(__constness_names[_M_variant._M_iterator._M_constness]); + } + else if (strcmp(__name, "state") == 0) + { + static const char* __state_names[__last_state] = + { + "", + "singular", + "dereferenceable (start-of-sequence)", + "dereferenceable", + "past-the-end" + }; + __formatter->_M_print_word(__state_names[_M_variant._M_iterator._M_state]); + } + else if (strcmp(__name, "sequence") == 0) + { + assert(_M_variant._M_iterator._M_sequence); + snprintf(buf, bufsize, "%p", _M_variant._M_iterator._M_sequence); + __formatter->_M_print_word(buf); + } + else if (strcmp(__name, "seq_type") == 0) + { + // TBD: demangle! + assert(_M_variant._M_iterator._M_seq_type); + __formatter->_M_print_word(_M_variant._M_iterator._M_seq_type->name()); + } + else + assert(false); + } + else if (_M_kind == __sequence) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_sequence._M_name); + __formatter->_M_print_word(_M_variant._M_sequence._M_name); + } + else if (strcmp(__name, "address") == 0) + { + assert(_M_variant._M_sequence._M_address); + snprintf(buf, bufsize, "%p", _M_variant._M_sequence._M_address); + __formatter->_M_print_word(buf); + } + else if (strcmp(__name, "type") == 0) + { + // TBD: demangle! + assert(_M_variant._M_sequence._M_type); + __formatter->_M_print_word(_M_variant._M_sequence._M_type->name()); + } + else + assert(false); + } + else if (_M_kind == __integer) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_integer._M_name); + __formatter->_M_print_word(_M_variant._M_integer._M_name); + } + else + assert(false); + } + else if (_M_kind == __string) + { + if (strcmp(__name, "name") == 0) + { + assert(_M_variant._M_string._M_name); + __formatter->_M_print_word(_M_variant._M_string._M_name); + } + else + assert(false); + } + else + { + assert(false); + } + } + + void + _Error_formatter::_Parameter:: + _M_print_description(const _Error_formatter* __formatter) const + { + const int bufsize = 128; + char buf[bufsize]; + + if (_M_kind == __iterator) + { + __formatter->_M_print_word("iterator "); + if (_M_variant._M_iterator._M_name) + { + snprintf(buf, bufsize, "\"%s\" ", + _M_variant._M_iterator._M_name); + __formatter->_M_print_word(buf); + } + + snprintf(buf, bufsize, "@ 0x%p {\n", + _M_variant._M_iterator._M_address); + __formatter->_M_print_word(buf); + if (_M_variant._M_iterator._M_type) + { + __formatter->_M_print_word("type = "); + _M_print_field(__formatter, "type"); + + if (_M_variant._M_iterator._M_constness != __unknown_constness) + { + __formatter->_M_print_word(" ("); + _M_print_field(__formatter, "constness"); + __formatter->_M_print_word(" iterator)"); + } + __formatter->_M_print_word(";\n"); + } + + if (_M_variant._M_iterator._M_state != __unknown_state) + { + __formatter->_M_print_word(" state = "); + _M_print_field(__formatter, "state"); + __formatter->_M_print_word(";\n"); + } + + if (_M_variant._M_iterator._M_sequence) + { + __formatter->_M_print_word(" references sequence "); + if (_M_variant._M_iterator._M_seq_type) + { + __formatter->_M_print_word("with type `"); + _M_print_field(__formatter, "seq_type"); + __formatter->_M_print_word("' "); + } + + snprintf(buf, bufsize, "@ 0x%p\n", _M_variant._M_sequence._M_address); + __formatter->_M_print_word(buf); + } + __formatter->_M_print_word("}\n"); + } + else if (_M_kind == __sequence) + { + __formatter->_M_print_word("sequence "); + if (_M_variant._M_sequence._M_name) + { + snprintf(buf, bufsize, "\"%s\" ", + _M_variant._M_sequence._M_name); + __formatter->_M_print_word(buf); + } + + snprintf(buf, bufsize, "@ 0x%p {\n", + _M_variant._M_sequence._M_address); + __formatter->_M_print_word(buf); + + if (_M_variant._M_sequence._M_type) + { + __formatter->_M_print_word(" type = "); + _M_print_field(__formatter, "type"); + __formatter->_M_print_word(";\n"); + } + __formatter->_M_print_word("}\n"); + } + } + + const _Error_formatter& + _Error_formatter::_M_message(_Debug_msg_id __id) const + { return this->_M_message(_S_debug_messages[__id]); } + + void + _Error_formatter::_M_error() const + { + const int bufsize = 128; + char buf[bufsize]; + + // Emit file & line number information + _M_column = 1; + _M_wordwrap = false; + if (_M_file) + { + snprintf(buf, bufsize, "%s:", _M_file); + _M_print_word(buf); + _M_column += strlen(buf); + } + + if (_M_line > 0) + { + snprintf(buf, bufsize, "%u:", _M_line); + _M_print_word(buf); + _M_column += strlen(buf); + } + + _M_wordwrap = true; + _M_print_word("error: "); + + // Print the error message + assert(_M_text); + _M_print_string(_M_text); + _M_print_word(".\n"); + + // Emit descriptions of the objects involved in the operation + _M_wordwrap = false; + bool has_noninteger_parameters = false; + for (unsigned int i = 0; i < _M_num_parameters; ++i) + { + if (_M_parameters[i]._M_kind == _Parameter::__iterator + || _M_parameters[i]._M_kind == _Parameter::__sequence) + { + if (!has_noninteger_parameters) + { + _M_first_line = true; + _M_print_word("\nObjects involved in the operation:\n"); + has_noninteger_parameters = true; + } + _M_parameters[i]._M_print_description(this); + } + } + + abort(); + } + + void + _Error_formatter::_M_print_word(const char* __word) const + { + if (!_M_wordwrap) + { + fprintf(stderr, "%s", __word); + return; + } + + size_t __length = strlen(__word); + if (__length == 0) + return; + + if ((_M_column + __length < _M_max_length) + || (__length >= _M_max_length && _M_column == 1)) + { + // If this isn't the first line, indent + if (_M_column == 1 && !_M_first_line) + { + char spacing[_M_indent + 1]; + for (int i = 0; i < _M_indent; ++i) + spacing[i] = ' '; + spacing[_M_indent] = '\0'; + fprintf(stderr, "%s", spacing); + _M_column += _M_indent; + } + + fprintf(stderr, "%s", __word); + _M_column += __length; + + if (__word[__length - 1] == '\n') + { + _M_first_line = false; + _M_column = 1; + } + } + else + { + _M_column = 1; + _M_print_word("\n"); + _M_print_word(__word); + } + } + + void + _Error_formatter:: + _M_print_string(const char* __string) const + { + const char* __start = __string; + const char* __end = __start; + const int bufsize = 128; + char buf[bufsize]; + + while (*__start) + { + if (*__start != '%') + { + // [__start, __end) denotes the next word + __end = __start; + while (isalnum(*__end)) ++__end; + if (__start == __end) ++__end; + if (isspace(*__end)) ++__end; + + assert(__end - __start + 1< bufsize); + snprintf(buf, __end - __start + 1, "%s", __start); + _M_print_word(buf); + __start = __end; + + // Skip extra whitespace + while (*__start == ' ') ++__start; + + continue; + } + + ++__start; + assert(*__start); + if (*__start == '%') + { + _M_print_word("%"); + ++__start; + continue; + } + + // Get the parameter number + assert(*__start >= '1' && *__start <= '9'); + size_t param = *__start - '0'; + --param; + assert(param < _M_num_parameters); + + // '.' separates the parameter number from the field + // name, if there is one. + ++__start; + if (*__start != '.') + { + assert(*__start == ';'); + ++__start; + buf[0] = '\0'; + if (_M_parameters[param]._M_kind == _Parameter::__integer) + { + snprintf(buf, bufsize, "%d", + _M_parameters[param]._M_variant._M_integer._M_value); + _M_print_word(buf); + } + else if (_M_parameters[param]._M_kind == _Parameter::__string) + _M_print_string(_M_parameters[param]._M_variant._M_string._M_value); + continue; + } + + // Extract the field name we want + enum { max_field_len = 16 }; + char field[max_field_len]; + int field_idx = 0; + ++__start; + while (*__start != ';') + { + assert(*__start); + assert(field_idx < max_field_len-1); + field[field_idx++] = *__start++; + } + ++__start; + field[field_idx] = 0; + + _M_parameters[param]._M_print_field(this, field); + } + } + } // namespace __gnu_debug Index: testsuite/20_util/auto_ptr_neg.cc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/20_util/auto_ptr_neg.cc,v retrieving revision 1.2 diff -c -3 -p -r1.2 auto_ptr_neg.cc *** testsuite/20_util/auto_ptr_neg.cc 14 May 2003 04:30:40 -0000 1.2 --- testsuite/20_util/auto_ptr_neg.cc 13 Aug 2003 18:42:40 -0000 *************** main() *** 46,50 **** test01(); return 0; } ! // { dg-error "candidates" "" { target *-*-* } 216 } ! // { dg-error "std::auto_ptr" "" { target *-*-* } 338 } --- 46,50 ---- test01(); return 0; } ! // { dg-error "candidates" "" { target *-*-* } 217 } ! // { dg-error "std::auto_ptr" "" { target *-*-* } 347 } Index: testsuite/23_containers/bitset/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/bitset/invalidation/1.cc diff -N testsuite/23_containers/bitset/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/bitset/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,46 ---- + // Bitset reference invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + + using __gnu_debug::bitset; + + bool test = true; + + // Disappear + void test01() + { + bitset<32>::reference* i; + { + bitset<32> bs; + bs.flip(7); + i = new bitset<32>::reference(bs[7]); + VERIFY(*i); + } + VERIFY(i->_M_singular()); + delete i; + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/deque/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/deque/invalidation/1.cc diff -N testsuite/23_containers/deque/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/deque/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,53 ---- + // Deque iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + + using __gnu_debug::deque; + + bool test = true; + + // Assignment + void test01() + { + deque v1; + deque v2; + + deque::iterator i = v1.end(); + VERIFY(!i._M_dereferenceable() && !i._M_singular()); + + v1 = v2; + VERIFY(i._M_singular()); + + i = v1.end(); + v1.assign(v2.begin(), v2.end()); + VERIFY(i._M_singular()); + + i = v1.end(); + v1.assign(17, 42); + VERIFY(i._M_singular()); + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/deque/invalidation/2.cc =================================================================== RCS file: testsuite/23_containers/deque/invalidation/2.cc diff -N testsuite/23_containers/deque/invalidation/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/deque/invalidation/2.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,53 ---- + // Deque iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + + using __gnu_debug::deque; + + bool test = true; + + // Resize + void test02() + { + deque v(10, 17); + + deque::iterator before = v.begin() + 6; + deque::iterator at = before + 1; + deque::iterator after = at + 1; + + // Shrink + v.resize(7); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_singular()); + + // Grow + before = v.begin() + 6; + v.resize(17); + VERIFY(before._M_singular()); + } + + int main() + { + test02(); + return !test; + } Index: testsuite/23_containers/deque/invalidation/3.cc =================================================================== RCS file: testsuite/23_containers/deque/invalidation/3.cc diff -N testsuite/23_containers/deque/invalidation/3.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/deque/invalidation/3.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,62 ---- + // Deque iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + + using __gnu_debug::deque; + + bool test = true; + + // Insert + void test03() + { + deque v(10, 17); + + // Insert a single element + deque::iterator before = v.begin() + 6; + deque::iterator at = before + 1; + deque::iterator after = at; + at = v.insert(at, 42); + VERIFY(before._M_singular()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_singular()); + + // Insert multiple copies + before = v.begin() + 6; + at = before + 1; + v.insert(at, 3, 42); + VERIFY(before._M_singular()); + VERIFY(at._M_singular()); + + // Insert iterator range + static int data[] = { 2, 3, 5, 7 }; + before = v.begin() + 6; + at = before + 1; + v.insert(at, &data[0], &data[0] + 4); + VERIFY(before._M_singular()); + VERIFY(at._M_singular()); + } + + int main() + { + test03(); + return !test; + } Index: testsuite/23_containers/deque/invalidation/4.cc =================================================================== RCS file: testsuite/23_containers/deque/invalidation/4.cc diff -N testsuite/23_containers/deque/invalidation/4.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/deque/invalidation/4.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,69 ---- + // Deque iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + + using __gnu_debug::deque; + + bool test = true; + + // Erase + void test04() + { + deque v(20, 42); + + // Single element erase (middle) + deque::iterator before = v.begin(); + deque::iterator at = before + 3; + deque::iterator after = at; + at = v.erase(at); + VERIFY(before._M_singular()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_singular()); + + // Single element erase (end) + before = v.begin(); + at = before; + after = at + 1; + at = v.erase(at); + VERIFY(before._M_singular()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_dereferenceable()); + + // Multiple element erase + before = v.begin(); + at = before + 3; + v.erase(at, at + 3); + VERIFY(before._M_singular()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); + } + + int main() + { + test04(); + return !test; + } Index: testsuite/23_containers/list/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/list/invalidation/1.cc diff -N testsuite/23_containers/list/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/list/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,60 ---- + // List iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::list; + using std::advance; + + bool test = true; + + // Assignment + void test01() + { + list v1; + list v2; + + v1.push_front(17); + + list::iterator start = v1.begin(); + list::iterator finish = v1.end(); + VERIFY(start._M_dereferenceable()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + + v1 = v2; + VERIFY(start._M_singular()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + + finish = v1.end(); + v1.assign(v2.begin(), v2.end()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + + finish = v1.end(); + v1.assign(17, 42); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/list/invalidation/2.cc =================================================================== RCS file: testsuite/23_containers/list/invalidation/2.cc diff -N testsuite/23_containers/list/invalidation/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/list/invalidation/2.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,55 ---- + // List iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::list; + using std::advance; + + bool test = true; + + // Resize + void test02() + { + list v(10, 17); + + list::iterator before = v.begin(); + advance(before, 6); + list::iterator at = before; + advance(at, 1); + list::iterator after = at; + advance(after, 1); + list::iterator finish = v.end(); + + // Shrink + v.resize(7); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_singular()); + VERIFY(!finish._M_singular() && !finish._M_dereferenceable()); + } + + int main() + { + test02(); + return !test; + } Index: testsuite/23_containers/list/invalidation/3.cc =================================================================== RCS file: testsuite/23_containers/list/invalidation/3.cc diff -N testsuite/23_containers/list/invalidation/3.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/list/invalidation/3.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,78 ---- + // List iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::list; + using std::advance; + + bool test = true; + + // Erase + void test03() + { + list v(20, 42); + + // Single element erase (middle) + list::iterator before = v.begin(); + list::iterator at = before; + advance(at, 3); + list::iterator after = at; + at = v.erase(at); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_singular()); + + // Single element erase (end) + before = v.begin(); + at = before; + after = at; + ++after; + at = v.erase(at); + VERIFY(before._M_singular()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_dereferenceable()); + + // Multiple element erase + before = v.begin(); + at = before; + advance(at, 3); + after = at; + advance(after, 3); + v.erase(at, after); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + list::iterator finish = v.end(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); + VERIFY(!finish._M_singular() && !finish._M_dereferenceable()); + } + + int main() + { + test03(); + return !test; + } Index: testsuite/23_containers/list/invalidation/4.cc =================================================================== RCS file: testsuite/23_containers/list/invalidation/4.cc diff -N testsuite/23_containers/list/invalidation/4.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/list/invalidation/4.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,55 ---- + // List iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::list; + using std::advance; + + bool test = true; + + // Splice + void test04() + { + list l1(10, 17); + list l2(10, 42); + + list::iterator start2 = l2.begin(); + list::iterator end2 = start2; + advance(end2, 5); + list::iterator after2 = end2; + advance(after2, 2); + + l1.splice(l1.begin(), l2, start2, end2); + VERIFY(start2._M_dereferenceable()); + VERIFY(end2._M_dereferenceable()); + VERIFY(after2._M_dereferenceable()); + VERIFY(start2._M_attached_to(&l1)); + VERIFY(end2._M_attached_to(&l2)); + VERIFY(after2._M_attached_to(&l2)); + } + + int main() + { + test04(); + return !test; + } Index: testsuite/23_containers/list/operators/4.cc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/23_containers/list/operators/4.cc,v retrieving revision 1.1 diff -c -3 -p -r1.1 4.cc *** testsuite/23_containers/list/operators/4.cc 31 Jul 2003 18:48:44 -0000 1.1 --- testsuite/23_containers/list/operators/4.cc 13 Aug 2003 18:42:40 -0000 *************** test04() *** 76,89 **** --- 76,93 ---- CompLastLt::reset(); list0401.merge(list0402, lt); VERIFY(list0401 == list0404); + #ifndef _GLIBCXX_DEBUG VERIFY(lt.count() <= (N + M - 1)); + #endif CompLastEq eq; CompLastEq::reset(); list0401.unique(eq); VERIFY(list0401 == list0405); + #ifndef _GLIBCXX_DEBUG VERIFY(eq.count() == (N + M - 1)); + #endif } main(int argc, char* argv[]) Index: testsuite/23_containers/map/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/map/invalidation/1.cc diff -N testsuite/23_containers/map/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/map/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,52 ---- + // Map iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::map; + using std::advance; + + bool test = true; + + // Assignment + void test01() + { + map v1; + map v2; + + v1[17] = 42; + + map::iterator start = v1.begin(); + map::iterator finish = v1.end(); + VERIFY(start._M_dereferenceable()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + + v1 = v2; + VERIFY(start._M_singular()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/map/invalidation/2.cc =================================================================== RCS file: testsuite/23_containers/map/invalidation/2.cc diff -N testsuite/23_containers/map/invalidation/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/map/invalidation/2.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,71 ---- + // Map iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::map; + using std::advance; + + bool test = true; + + // Erase + void test02() + { + map v; + for (int i = 0; i < 20; ++i) + v[i] = 20-i; + + // Single element erase (middle) + map::iterator before = v.begin(); + map::iterator at = before; + advance(at, 3); + map::iterator after = at; + ++after; + v.erase(at); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_dereferenceable()); + + // Multiple element erase + before = v.begin(); + at = before; + advance(at, 3); + after = at; + advance(after, 4); + v.erase(at, after); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + map::iterator finish = v.end(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); + VERIFY(!finish._M_singular() && !finish._M_dereferenceable()); + } + + int main() + { + test02(); + return !test; + } Index: testsuite/23_containers/multimap/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/multimap/invalidation/1.cc diff -N testsuite/23_containers/multimap/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/multimap/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,53 ---- + // Multimap iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + #include + + using __gnu_debug::multimap; + using std::advance; + + bool test = true; + + // Assignment + void test01() + { + multimap v1; + multimap v2; + + v1.insert(std::make_pair(17, 42)); + + multimap::iterator start = v1.begin(); + multimap::iterator finish = v1.end(); + VERIFY(start._M_dereferenceable()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + + v1 = v2; + VERIFY(start._M_singular()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/multimap/invalidation/2.cc =================================================================== RCS file: testsuite/23_containers/multimap/invalidation/2.cc diff -N testsuite/23_containers/multimap/invalidation/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/multimap/invalidation/2.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,72 ---- + // Multimap iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + #include + + using __gnu_debug::multimap; + using std::advance; + + bool test = true; + + // Erase + void test02() + { + multimap v; + for (int i = 0; i < 20; ++i) + v.insert(std::make_pair(i, 20-i)); + + // Single element erase (middle) + multimap::iterator before = v.begin(); + multimap::iterator at = before; + advance(at, 3); + multimap::iterator after = at; + ++after; + v.erase(at); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_dereferenceable()); + + // Multiple element erase + before = v.begin(); + at = before; + advance(at, 3); + after = at; + advance(after, 4); + v.erase(at, after); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + multimap::iterator finish = v.end(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); + VERIFY(!finish._M_singular() && !finish._M_dereferenceable()); + } + + int main() + { + test02(); + return !test; + } Index: testsuite/23_containers/multiset/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/multiset/invalidation/1.cc diff -N testsuite/23_containers/multiset/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/multiset/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,52 ---- + // Multiset iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::multiset; + using std::advance; + + bool test = true; + + // Assignment + void test01() + { + multiset v1; + multiset v2; + + v1.insert(17); + + multiset::iterator start = v1.begin(); + multiset::iterator finish = v1.end(); + VERIFY(start._M_dereferenceable()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + + v1 = v2; + VERIFY(start._M_singular()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/multiset/invalidation/2.cc =================================================================== RCS file: testsuite/23_containers/multiset/invalidation/2.cc diff -N testsuite/23_containers/multiset/invalidation/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/multiset/invalidation/2.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,71 ---- + // Multiset iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::multiset; + using std::advance; + + bool test = true; + + // Erase + void test02() + { + multiset v; + for (int i = 0; i < 20; ++i) + v.insert(i); + + // Single element erase (middle) + multiset::iterator before = v.begin(); + multiset::iterator at = before; + advance(at, 3); + multiset::iterator after = at; + ++after; + v.erase(at); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_dereferenceable()); + + // Multiple element erase + before = v.begin(); + at = before; + advance(at, 3); + after = at; + advance(after, 4); + v.erase(at, after); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + multiset::iterator finish = v.end(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); + VERIFY(!finish._M_singular() && !finish._M_dereferenceable()); + } + + int main() + { + test02(); + return !test; + } Index: testsuite/23_containers/set/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/set/invalidation/1.cc diff -N testsuite/23_containers/set/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/set/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,52 ---- + // Set iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::set; + using std::advance; + + bool test = true; + + // Assignment + void test01() + { + set v1; + set v2; + + v1.insert(17); + + set::iterator start = v1.begin(); + set::iterator finish = v1.end(); + VERIFY(start._M_dereferenceable()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + + v1 = v2; + VERIFY(start._M_singular()); + VERIFY(!finish._M_dereferenceable() && !finish._M_singular()); + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/set/invalidation/2.cc =================================================================== RCS file: testsuite/23_containers/set/invalidation/2.cc diff -N testsuite/23_containers/set/invalidation/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/set/invalidation/2.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,71 ---- + // Set iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + #include + #include + #include + + using __gnu_debug::set; + using std::advance; + + bool test = true; + + // Erase + void test02() + { + set v; + for (int i = 0; i < 20; ++i) + v.insert(i); + + // Single element erase (middle) + set::iterator before = v.begin(); + set::iterator at = before; + advance(at, 3); + set::iterator after = at; + ++after; + v.erase(at); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_dereferenceable()); + + // Multiple element erase + before = v.begin(); + at = before; + advance(at, 3); + after = at; + advance(after, 4); + v.erase(at, after); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + set::iterator finish = v.end(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); + VERIFY(!finish._M_singular() && !finish._M_dereferenceable()); + } + + int main() + { + test02(); + return !test; + } Index: testsuite/23_containers/vector/invalidation/1.cc =================================================================== RCS file: testsuite/23_containers/vector/invalidation/1.cc diff -N testsuite/23_containers/vector/invalidation/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/vector/invalidation/1.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,60 ---- + // Vector iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // We need to be pedantic about reallocations for this testcase to be correct. + // { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" } + + #ifndef _GLIBCXX_DEBUG_PEDANTIC + # define _GLIBCXX_DEBUG_PEDANTIC 1 + #endif + + #include + #include + + using __gnu_debug::vector; + + bool test = true; + + // Assignment + void test01() + { + vector v1; + vector v2; + + vector::iterator i = v1.end(); + VERIFY(!i._M_dereferenceable() && !i._M_singular()); + + v1 = v2; + VERIFY(i._M_singular()); + + i = v1.end(); + v1.assign(v2.begin(), v2.end()); + VERIFY(i._M_singular()); + + i = v1.end(); + v1.assign(17, 42); + VERIFY(i._M_singular()); + } + + int main() + { + test01(); + return !test; + } Index: testsuite/23_containers/vector/invalidation/2.cc =================================================================== RCS file: testsuite/23_containers/vector/invalidation/2.cc diff -N testsuite/23_containers/vector/invalidation/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/vector/invalidation/2.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,65 ---- + // Vector iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // We need to be pedantic about reallocations for this testcase to be correct. + // { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" } + + #ifndef _GLIBCXX_DEBUG_PEDANTIC + # define _GLIBCXX_DEBUG_PEDANTIC 1 + #endif + + #include + #include + + using __gnu_debug::vector; + + bool test = true; + + // Resize + void test02() + { + vector v(10, 17); + v.reserve(20); + + vector::iterator before = v.begin() + 6; + vector::iterator at = before + 1; + vector::iterator after = at + 1; + + // Shrink + v.resize(7); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_singular()); + + // Grow, without reallocation + before = v.begin() + 6; + v.resize(17); + VERIFY(before._M_dereferenceable()); + + // Grow, with reallocation + v.resize(42); + VERIFY(before._M_singular()); + } + + int main() + { + test02(); + return !test; + } Index: testsuite/23_containers/vector/invalidation/3.cc =================================================================== RCS file: testsuite/23_containers/vector/invalidation/3.cc diff -N testsuite/23_containers/vector/invalidation/3.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/vector/invalidation/3.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,90 ---- + // Vector iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // We need to be pedantic about reallocations for this testcase to be correct. + // { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" } + + #ifndef _GLIBCXX_DEBUG_PEDANTIC + # define _GLIBCXX_DEBUG_PEDANTIC 1 + #endif + + #include + #include + + using __gnu_debug::vector; + + bool test = true; + + // Insert + void test03() + { + vector v(10, 17); + v.reserve(30); + + // Insert a single element + vector::iterator before = v.begin() + 6; + vector::iterator at = before + 1; + vector::iterator after = at; + at = v.insert(at, 42); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_singular()); + + // Insert multiple copies + before = v.begin() + 6; + at = before + 1; + v.insert(at, 3, 42); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // Insert iterator range + static int data[] = { 2, 3, 5, 7 }; + before = v.begin() + 6; + at = before + 1; + v.insert(at, &data[0], &data[0] + 4); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // Insert with reallocation + before = v.begin() + 6; + at = before + 1; + v.insert(at, 30, 17); + VERIFY(before._M_singular()); + VERIFY(at._M_singular()); + + // Single insert with reallocation + vector v2; + v2.reserve(100); + at = v2.begin(); + v2.insert(at, 100, 17); + at = v2.end() - 1; + before = v2.begin(); + VERIFY(at._M_dereferenceable()); + VERIFY(before._M_dereferenceable()); + at = v2.insert(at, 42); + VERIFY(at._M_dereferenceable()); + VERIFY(before._M_singular()); + } + + int main() + { + test03(); + return !test; + } Index: testsuite/23_containers/vector/invalidation/4.cc =================================================================== RCS file: testsuite/23_containers/vector/invalidation/4.cc diff -N testsuite/23_containers/vector/invalidation/4.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/23_containers/vector/invalidation/4.cc 13 Aug 2003 18:42:40 -0000 *************** *** 0 **** --- 1,67 ---- + // Vector iterator invalidation tests + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the + // terms of the GNU General Public License as published by the + // Free Software Foundation; either version 2, or (at your option) + // any later version. + + // This library is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + + // You should have received a copy of the GNU General Public License along + // with this library; see the file COPYING. If not, write to the Free + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // We need to be pedantic about reallocations for this testcase to be correct. + // { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" } + + #ifndef _GLIBCXX_DEBUG_PEDANTIC + # define _GLIBCXX_DEBUG_PEDANTIC 1 + #endif + + #include + #include + + using __gnu_debug::vector; + + bool test = true; + + // Erase + void test04() + { + vector v(20, 42); + + // Single element erase + vector::iterator before = v.begin(); + vector::iterator at = before + 3; + vector::iterator after = at; + at = v.erase(at); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_singular()); + + // Multiple element erase + before = v.begin(); + at = before + 3; + v.erase(at, at + 3); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); + } + + int main() + { + test04(); + return !test; + } Index: testsuite/25_algorithms/heap.cc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/25_algorithms/heap.cc,v retrieving revision 1.2 diff -c -3 -p -r1.2 heap.cc *** testsuite/25_algorithms/heap.cc 7 Aug 2001 03:38:32 -0000 1.2 --- testsuite/25_algorithms/heap.cc 13 Aug 2003 18:42:40 -0000 *************** test02() *** 95,107 **** --- 95,111 ---- for (int i = 2; i <= N; ++i) { std::push_heap(s1, s1 + i, gt); + #ifndef _GLIBCXX_DEBUG VERIFY(gt.count() <= logN); + #endif gt.reset(); } for (int i = N; i >= 2; --i) { std::pop_heap(s1, s1 + i, gt); + #ifndef _GLIBCXX_DEBUG VERIFY(gt.count() <= 2 * logN); + #endif gt.reset(); } *************** test02() *** 113,123 **** --- 117,131 ---- VERIFY(std::equal(s2, s2 + N, A)); std::make_heap(s2, s2 + N, gt); + #ifndef _GLIBCXX_DEBUG VERIFY(gt.count() <= 3 * N); + #endif gt.reset(); std::sort_heap(s2, s2 + N, gt); + #ifndef _GLIBCXX_DEBUG VERIFY(gt.count() <= N * logN); + #endif VERIFY(std::equal(s2, s2 + N, C)); } Index: testsuite/Makefile.am =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/Makefile.am,v retrieving revision 1.30 diff -c -3 -p -r1.30 Makefile.am *** testsuite/Makefile.am 8 Aug 2003 15:24:00 -0000 1.30 --- testsuite/Makefile.am 13 Aug 2003 18:42:40 -0000 *************** lists_of_files = \ *** 54,62 **** testsuite_files_interactive \ testsuite_files_performance ! ## Build support library. ! noinst_LIBRARIES = libv3test.a libv3test_a_SOURCES = testsuite_hooks.cc testsuite_allocator.cc ## Build support utilities. if GLIBCXX_TEST_ABI --- 54,74 ---- testsuite_files_interactive \ testsuite_files_performance ! ## Build support libraries. ! noinst_LIBRARIES = libv3test.a libv3test-debug.a ! libv3test_a_SOURCES = testsuite_hooks.cc testsuite_allocator.cc + libv3test_debug_a_SOURCES = testsuite_hooks_dbg.cc testsuite_allocator_dbg.cc + + testsuite_hooks_dbg.cc: ${glibcxx_srcdir}/testsuite/testsuite_hooks.cc + @LN_S@ ${glibcxx_srcdir}/testsuite/testsuite_hooks.cc testsuite_hooks_dbg.cc + testsuite_allocator_dbg.cc: ${glibcxx_srcdir}/testsuite/testsuite_allocator.cc + @LN_S@ ${glibcxx_srcdir}/testsuite/testsuite_allocator.cc testsuite_allocator_dbg.cc + + testsuite_hooks_dbg.o: testsuite_hooks_dbg.cc + $(CXXCOMPILE) -D_GLIBCXX_DEBUG -I. -c $< + testsuite_allocator_dbg.o: testsuite_allocator_dbg.cc + $(CXXCOMPILE) -D_GLIBCXX_DEBUG -I. -c $< ## Build support utilities. if GLIBCXX_TEST_ABI Index: testsuite/lib/libstdc++.exp =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/lib/libstdc++.exp,v retrieving revision 1.11 diff -c -3 -p -r1.11 libstdc++.exp *** testsuite/lib/libstdc++.exp 5 Aug 2003 01:34:28 -0000 1.11 --- testsuite/lib/libstdc++.exp 13 Aug 2003 18:42:40 -0000 *************** proc v3_target_compile { source dest typ *** 209,215 **** # Picks up the freshly-built testsuite library corresponding to the # multilib under test. lappend options "ldflags=-L${blddir}/testsuite" ! lappend options "libs=-lv3test" return [target_compile $source $dest $type $options] } --- 209,220 ---- # Picks up the freshly-built testsuite library corresponding to the # multilib under test. lappend options "ldflags=-L${blddir}/testsuite" ! ! if { [lsearch -exact $cxx_final "-D_GLIBCXX_DEBUG"] >= 0 } { ! lappend options "libs=-lv3test-debug" ! } else { ! lappend options "libs=-lv3test" ! } return [target_compile $source $dest $type $options] }