diff options
Diffstat (limited to 'libstdc++-v3/include')
63 files changed, 8411 insertions, 795 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 862b0a3a8a0..3af38b331d4 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -224,7 +224,6 @@ ext_headers = \ ${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 = . @@ -290,6 +289,34 @@ c_compatibility_headers = \ ${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}/debug.h \ + ${debug_srcdir}/deque \ + ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/hash_map \ + ${debug_srcdir}/hash_map.h \ + ${debug_srcdir}/hash_multimap.h \ + ${debug_srcdir}/hash_multiset.h \ + ${debug_srcdir}/hash_set \ + ${debug_srcdir}/hash_set.h \ + ${debug_srcdir}/list \ + ${debug_srcdir}/map \ + ${debug_srcdir}/map.h \ + ${debug_srcdir}/multimap.h \ + ${debug_srcdir}/multiset.h \ + ${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}/set.h \ + ${debug_srcdir}/string \ + ${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 @@ -350,7 +377,7 @@ endif # 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 + stamp-backward stamp-ext stamp-debug stamp-host # List of all files that are created by explicit building, editing, or # catenation. @@ -429,6 +456,15 @@ stamp-ext: ${ext_headers} fi ;\ $(STAMP) stamp-ext +stamp-debug: ${debug_headers} + @if [ ! -d "${debug_builddir}" ]; then \ + mkdir -p ${debug_builddir} ;\ + fi ;\ + if [ ! -f stamp-debug ]; then \ + (cd ${debug_builddir} && @LN_S@ $? . || true) ;\ + fi ;\ + $(STAMP) stamp-debug + stamp-${host_alias}: @if [ ! -d ${host_builddir} ]; then \ mkdir -p ${host_builddir} ;\ @@ -556,6 +592,9 @@ install-headers: $(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 \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 1db9bfcd555..cf40dcf18a0 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -491,11 +491,40 @@ c_compatibility_headers = \ ${c_compatibility_srcdir}/wctype.h +# Debug mode headers +debug_srcdir = ${glibcxx_srcdir}/include/debug +debug_builddir = ./debug +debug_headers = \ + ${debug_srcdir}/bitset \ + ${debug_srcdir}/debug.h \ + ${debug_srcdir}/deque \ + ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/hash_map \ + ${debug_srcdir}/hash_map.h \ + ${debug_srcdir}/hash_multimap.h \ + ${debug_srcdir}/hash_multiset.h \ + ${debug_srcdir}/hash_set \ + ${debug_srcdir}/hash_set.h \ + ${debug_srcdir}/list \ + ${debug_srcdir}/map \ + ${debug_srcdir}/map.h \ + ${debug_srcdir}/multimap.h \ + ${debug_srcdir}/multiset.h \ + ${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}/set.h \ + ${debug_srcdir}/string \ + ${debug_srcdir}/vector + +@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = + # Some of the different "C" header models need extra files. # Some "C" header schemes require the "C" compatibility headers. # For --enable-cheaders=c_std @GLIBCXX_C_HEADERS_C_STD_TRUE@c_base_headers_extra = ${c_base_srcdir}/cmath.tcc -@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@c_compatibility_headers_extra = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@c_compatibility_headers_extra = ${c_compatibility_headers} @@ -546,7 +575,7 @@ PCHFLAGS = -Winvalid-pch -Wno-deprecated -x c++-header $(CXXFLAGS) # 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 + stamp-backward stamp-ext stamp-debug stamp-host # List of all files that are created by explicit building, editing, or @@ -783,6 +812,15 @@ stamp-ext: ${ext_headers} fi ;\ $(STAMP) stamp-ext +stamp-debug: ${debug_headers} + @if [ ! -d "${debug_builddir}" ]; then \ + mkdir -p ${debug_builddir} ;\ + fi ;\ + if [ ! -f stamp-debug ]; then \ + (cd ${debug_builddir} && @LN_S@ $? . || true) ;\ + fi ;\ + $(STAMP) stamp-debug + stamp-${host_alias}: @if [ ! -d ${host_builddir} ]; then \ mkdir -p ${host_builddir} ;\ @@ -904,6 +942,9 @@ install-headers: $(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 \ diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 44df752ae56..7b1ba5c80fb 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -43,6 +43,7 @@ #pragma GCC system_header #include <bits/atomicity.h> +#include <debug/debug.h> namespace std { @@ -608,7 +609,10 @@ namespace std */ const_reference operator[] (size_type __pos) const - { return _M_data()[__pos]; } + { + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + return _M_data()[__pos]; + } /** * @brief Subscript access to the data contained in the %string. @@ -623,6 +627,7 @@ namespace std reference operator[](size_type __pos) { + _GLIBCXX_DEBUG_ASSERT(__pos < size()); _M_leak(); return _M_data()[__pos]; } @@ -729,7 +734,10 @@ namespace std */ basic_string& append(const _CharT* __s) - { return this->append(__s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->append(__s, traits_type::length(__s)); + } /** * @brief Append multiple characters. @@ -810,7 +818,10 @@ namespace std */ basic_string& assign(const _CharT* __s) - { return this->assign(__s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->assign(__s, traits_type::length(__s)); + } /** * @brief Set value to multiple characters. @@ -942,7 +953,10 @@ namespace std */ basic_string& insert(size_type __pos, const _CharT* __s) - { return this->insert(__pos, __s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->insert(__pos, __s, traits_type::length(__s)); + } /** * @brief Insert multiple characters. @@ -983,6 +997,7 @@ namespace std 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(); @@ -1043,6 +1058,8 @@ namespace std 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(); @@ -1064,6 +1081,8 @@ namespace std 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(); @@ -1150,7 +1169,10 @@ namespace std */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s) - { return this->replace(__pos, __n1, __s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } /** * @brief Replace characters with multiple characters. @@ -1187,7 +1209,11 @@ namespace std */ basic_string& replace(iterator __i1, iterator __i2, const basic_string& __str) - { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + { + _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. @@ -1205,7 +1231,7 @@ namespace std */ basic_string& replace(iterator __i1, iterator __i2, - const _CharT* __s, size_type __n) + const _CharT* __s, size_type __n) { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); } /** @@ -1223,7 +1249,12 @@ namespace std */ basic_string& replace(iterator __i1, iterator __i2, const _CharT* __s) - { return this->replace(__i1, __i2, __s, traits_type::length(__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 @@ -1241,7 +1272,11 @@ namespace std */ basic_string& replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) - { return _M_replace_aux(__i1, __i2, __n, __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. @@ -1261,30 +1296,55 @@ namespace std 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()); } + { + _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) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, - __k1, __k2 - __k1); } + 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) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, - __k1, __k2 - __k1); } + 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) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + 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) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + 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); } @@ -1459,7 +1519,10 @@ namespace std */ size_type find(const _CharT* __s, size_type __pos = 0) const - { return this->find(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } /** * @brief Find position of a character. @@ -1514,7 +1577,10 @@ namespace std */ size_type rfind(const _CharT* __s, size_type __pos = npos) const - { return this->rfind(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } /** * @brief Find last position of a character. @@ -1569,7 +1635,10 @@ namespace std */ size_type find_first_of(const _CharT* __s, size_type __pos = 0) const - { return this->find_first_of(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } /** * @brief Find position of a character. @@ -1627,7 +1696,10 @@ namespace std */ size_type find_last_of(const _CharT* __s, size_type __pos = npos) const - { return this->find_last_of(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } /** * @brief Find last position of a character. @@ -1686,7 +1758,10 @@ namespace std */ 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)); } + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } /** * @brief Find position of a different character. @@ -1742,7 +1817,10 @@ namespace std */ 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)); } + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } /** * @brief Find last position of a different character. @@ -2197,7 +2275,6 @@ namespace std const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) <= 0; } - /** * @brief Swap contents of two strings. * @param lhs First string. diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index ecd8f71c45e..34a373ce1a5 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -45,6 +45,16 @@ namespace std { + template<typename _Type> + inline bool + __is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template<typename _Type> + inline bool + __is_null_pointer(const _Type&) + { return false; } + template<typename _CharT, typename _Traits, typename _Alloc> const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: @@ -141,8 +151,8 @@ namespace std if (__beg == __end && __a == _Alloc()) return _S_empty_rep()._M_refdata(); - // NB: Not required, but considered best practice. - if (__builtin_expect(__beg == _InIterator(), 0)) + // NB: Not required, but considered best practice. + if (__builtin_expect(__is_null_pointer(__beg), 0)) __throw_logic_error("basic_string::_S_construct NULL not valid"); const size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); @@ -215,12 +225,14 @@ namespace std __str._M_fold(__pos, __n), __a), __a) { } + // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> 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<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _CharT* __s, const _Alloc& __a) @@ -233,7 +245,8 @@ namespace std basic_string(size_type __n, _CharT __c, const _Alloc& __a) : _M_dataplus(_S_construct(__n, __c, __a), __a) { } - + + // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>:: @@ -275,6 +288,7 @@ namespace std 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<const _CharT*>()(__s, _M_data()) @@ -313,6 +327,7 @@ namespace std 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"); @@ -350,6 +365,7 @@ namespace std 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"); @@ -727,6 +743,7 @@ namespace std 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); @@ -749,6 +766,7 @@ namespace std 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); @@ -783,6 +801,8 @@ namespace std 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.) @@ -794,6 +814,8 @@ namespace std 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(); @@ -827,6 +849,8 @@ namespace std 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) { @@ -866,6 +890,8 @@ namespace std 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]); @@ -880,6 +906,8 @@ namespace std 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) { @@ -900,6 +928,8 @@ namespace std 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])) @@ -924,6 +954,8 @@ namespace std 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) { @@ -1004,6 +1036,8 @@ namespace std 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); @@ -1019,6 +1053,8 @@ namespace std 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"); @@ -1038,6 +1074,8 @@ namespace std 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"); diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index d6ce9ed8412..6a0fb7901fa 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -51,11 +51,28 @@ # define _GLIBCXX_EXTERN_TEMPLATE 1 #endif -// To enable older, ARM-style iostreams and other anachronisms use this. -//#define _GLIBCXX_DEPRECATED 1 +// To enable debug mode. +namespace __gnu_norm +{ + using namespace std; +} -// Use corrected code from the committee library group's issues list. -//#define _GLIBCXX_RESOLVE_LIB_DEFECTS 1 +namespace __gnu_debug_def { } + +namespace __gnu_debug +{ + using namespace std; + using namespace __gnu_debug_def __attribute__ ((strong)); +} + +namespace std +{ +#ifdef _GLIBCXX_DEBUG + using namespace __gnu_debug_def __attribute__ ((strong)); +#else + using namespace __gnu_norm __attribute__ ((strong)); +#endif +} // The remainder of the prewritten config is automatic; all the // user hooks are listed above. diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index dedab6a3112..9f01eed8d68 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -61,7 +61,7 @@ #ifndef _DEQUE_TCC #define _DEQUE_TCC 1 -namespace std +namespace __gnu_norm { template <typename _Tp, typename _Alloc> deque<_Tp,_Alloc>& @@ -707,6 +707,6 @@ namespace std this->_M_start._M_set_node(__new_nstart); this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } -} // namespace std +} // namespace __gnu_norm #endif diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index 9c5a0cde607..283b0ac6838 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -61,7 +61,7 @@ #ifndef _LIST_TCC #define _LIST_TCC 1 -namespace std +namespace __gnu_norm { template<typename _Tp, typename _Alloc> void @@ -409,6 +409,6 @@ namespace std swap(__counter[__fill-1]); } } -} // namespace std +} // namespace __gnu_norm #endif /* _LIST_TCC */ diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 70ef2199536..7cb54eb63a2 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -63,12 +63,12 @@ #include <bits/stl_heap.h> #include <bits/stl_tempbuf.h> // for _Temporary_buffer +#include <debug/debug.h> // See concept_check.h for the __glibcxx_*_requires macros. namespace std { - /** * @brief Find the median of three values. * @param a A value. @@ -153,6 +153,7 @@ namespace std { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __f(*__first); return __f; @@ -295,6 +296,7 @@ namespace std __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)); } @@ -315,6 +317,7 @@ namespace std __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)); } @@ -334,6 +337,7 @@ namespace std __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; @@ -365,6 +369,7 @@ namespace std __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; @@ -393,6 +398,7 @@ namespace std __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) @@ -416,6 +422,7 @@ namespace std __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)) @@ -458,7 +465,8 @@ namespace std __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; @@ -531,6 +539,8 @@ namespace std __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) @@ -603,6 +613,7 @@ namespace std __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; @@ -651,6 +662,7 @@ namespace std __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; @@ -708,6 +720,7 @@ namespace std __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); @@ -739,6 +752,7 @@ namespace std __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); @@ -775,6 +789,7 @@ namespace std __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); @@ -804,6 +819,7 @@ namespace std 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) @@ -833,6 +849,7 @@ namespace std 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)) @@ -865,6 +882,7 @@ namespace std 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; @@ -898,6 +916,7 @@ namespace std 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; @@ -923,6 +942,7 @@ namespace std __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(); @@ -977,6 +997,7 @@ namespace std 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)) { @@ -1011,6 +1032,7 @@ namespace std 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)) { @@ -1047,6 +1069,7 @@ namespace std 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; @@ -1079,6 +1102,7 @@ namespace std __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; @@ -1207,6 +1231,7 @@ namespace std 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; @@ -1239,6 +1264,7 @@ namespace std __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; @@ -1266,7 +1292,8 @@ namespace std // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualityComparableConcept< - typename iterator_traits<_ForwardIterator>::value_type>) + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); // Skip the beginning, if already unique. __first = std::adjacent_find(__first, __last); @@ -1306,6 +1333,7 @@ namespace std __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); // Skip the beginning, if already unique. __first = std::adjacent_find(__first, __last, __binary_pred); @@ -1371,7 +1399,8 @@ namespace std { // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< - _BidirectionalIterator>) + _BidirectionalIterator>) + __glibcxx_requires_valid_range(__first, __last); std::__reverse(__first, __last, std::__iterator_category(__first)); } @@ -1399,6 +1428,7 @@ namespace std __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; @@ -1583,6 +1613,8 @@ namespace std { // 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()); @@ -1614,6 +1646,8 @@ namespace std __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)); } @@ -1657,6 +1691,7 @@ namespace std // 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) @@ -1684,6 +1719,7 @@ namespace std // 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) @@ -1773,6 +1809,7 @@ namespace std __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)); } @@ -1873,6 +1910,7 @@ namespace std __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; @@ -2139,6 +2177,8 @@ namespace std __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) @@ -2179,6 +2219,8 @@ namespace std _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) @@ -2219,6 +2261,8 @@ namespace std __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; @@ -2275,6 +2319,8 @@ namespace std __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; @@ -2375,6 +2421,7 @@ namespace std __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); @@ -2406,6 +2453,7 @@ namespace std __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); @@ -2438,6 +2486,7 @@ namespace std __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; @@ -2483,6 +2532,7 @@ namespace std // 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; @@ -2525,6 +2575,7 @@ namespace std __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; @@ -2570,6 +2621,7 @@ namespace std // 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; @@ -2755,6 +2807,8 @@ namespace std 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) { @@ -2808,6 +2862,8 @@ namespace std __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)) { @@ -3170,6 +3226,8 @@ namespace std __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; @@ -3223,6 +3281,8 @@ namespace std _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; @@ -3309,6 +3369,7 @@ namespace std __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) @@ -3346,6 +3407,7 @@ namespace std _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) @@ -3381,6 +3443,8 @@ namespace std // 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 = @@ -3425,6 +3489,8 @@ namespace std __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 = @@ -3469,6 +3535,7 @@ namespace std __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; @@ -3524,6 +3591,7 @@ namespace std __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; @@ -3572,6 +3640,7 @@ namespace std __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); @@ -3603,6 +3672,7 @@ namespace std 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); @@ -3642,6 +3712,8 @@ namespace std 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) @@ -3687,6 +3759,8 @@ namespace std __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)) @@ -3732,6 +3806,8 @@ namespace std 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) { @@ -3788,6 +3864,8 @@ namespace std __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)) { @@ -3840,6 +3918,8 @@ namespace std 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) @@ -3892,6 +3972,8 @@ namespace std __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)) @@ -3941,6 +4023,8 @@ namespace std 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) { @@ -3996,6 +4080,8 @@ namespace std __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)) { @@ -4044,6 +4130,8 @@ namespace std 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) { @@ -4101,6 +4189,8 @@ namespace std __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)) { @@ -4137,6 +4227,7 @@ namespace std __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; @@ -4164,6 +4255,7 @@ namespace std __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; @@ -4186,6 +4278,7 @@ namespace std __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; @@ -4213,6 +4306,7 @@ namespace std __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; @@ -4244,6 +4338,7 @@ namespace std __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; @@ -4296,6 +4391,7 @@ namespace std __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; @@ -4344,6 +4440,7 @@ namespace std __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; @@ -4396,6 +4493,7 @@ namespace std __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; @@ -4451,6 +4549,8 @@ namespace std __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) @@ -4489,6 +4589,8 @@ namespace std __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) @@ -4649,6 +4751,8 @@ namespace std __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), @@ -4694,6 +4798,8 @@ namespace std __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), diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 73b13591cdc..3e1a7c639c3 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -74,6 +74,7 @@ #include <bits/stl_iterator_base_funcs.h> #include <bits/stl_iterator.h> #include <bits/concept_check.h> +#include <debug/debug.h> namespace std { @@ -333,6 +334,7 @@ namespace std __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()); @@ -471,6 +473,7 @@ namespace std __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, @@ -495,6 +498,7 @@ namespace std { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) *__first = __value; @@ -527,6 +531,7 @@ namespace std 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); } @@ -534,6 +539,7 @@ namespace std 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<unsigned char>(__tmp), __last - __first); } @@ -541,6 +547,7 @@ namespace std inline void fill(char* __first, char* __last, const char& __c) { + __glibcxx_requires_valid_range(__first, __last); char __tmp = __c; std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first); } @@ -594,6 +601,7 @@ namespace std 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) { @@ -625,6 +633,7 @@ namespace std // 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)) { @@ -655,6 +664,7 @@ namespace std __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)) @@ -684,6 +694,7 @@ namespace std // 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)) @@ -717,6 +728,8 @@ namespace std 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) { @@ -749,6 +762,8 @@ namespace std // 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) @@ -767,6 +782,9 @@ namespace std 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)); @@ -777,6 +795,9 @@ namespace std 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, diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 15e0f57f166..d05f6076bb8 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -61,7 +61,7 @@ #ifndef _BVECTOR_H #define _BVECTOR_H 1 -namespace std +namespace __gnu_norm { typedef unsigned long _Bit_type; enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) }; @@ -334,13 +334,12 @@ public: ~_Bvector_base() { _Base::_M_deallocate(); } }; -} // namespace std +} // namespace __gnu_norm // Declare a partial specialization of vector<T, Alloc>. #include <bits/stl_vector.h> -namespace std +namespace __gnu_norm { - template <typename _Alloc> class vector<bool, _Alloc> : public _Bvector_base<_Alloc> { @@ -723,13 +722,8 @@ template <typename _Alloc> void clear() { erase(begin(), end()); } }; -// This typedef is non-standard. It is provided for backward compatibility. -typedef vector<bool, __alloc> bit_vector; - -} // namespace std + // This typedef is non-standard. It is provided for backward compatibility. + typedef vector<bool, __alloc> bit_vector; +} // namespace __gnu_norm #endif /* _BVECTOR_H */ - -// Local Variables: -// mode:C++ -// End: diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index b5733433bbc..2498bb6bfe6 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -65,7 +65,7 @@ #include <bits/stl_iterator_base_types.h> #include <bits/stl_iterator_base_funcs.h> -namespace std +namespace __gnu_norm { /** * @if maint @@ -96,7 +96,7 @@ namespace std * All the functions are op overloads except for _M_set_node. * @endif */ - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> struct _Deque_iterator { typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; @@ -205,7 +205,7 @@ namespace std // Note: we also provide overloads whose operands are of the same type in // order to avoid ambiguous overload resolution when std::rel_ops operators // are in scope (for additional details, see libstdc++/3628) - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) @@ -213,7 +213,7 @@ namespace std return __x._M_cur == __y._M_cur; } - template <typename _Tp, typename _RefL, typename _PtrL, + template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, @@ -222,7 +222,7 @@ namespace std return __x._M_cur == __y._M_cur; } - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) @@ -230,7 +230,7 @@ namespace std return !(__x == __y); } - template <typename _Tp, typename _RefL, typename _PtrL, + template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, @@ -239,7 +239,7 @@ namespace std return !(__x == __y); } - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) @@ -248,7 +248,7 @@ namespace std (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); } - template <typename _Tp, typename _RefL, typename _PtrL, + template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, @@ -258,7 +258,7 @@ namespace std (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); } - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) @@ -266,7 +266,7 @@ namespace std return __y < __x; } - template <typename _Tp, typename _RefL, typename _PtrL, + template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, @@ -275,7 +275,7 @@ namespace std return __y < __x; } - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) @@ -283,7 +283,7 @@ namespace std return !(__y < __x); } - template <typename _Tp, typename _RefL, typename _PtrL, + template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, @@ -292,7 +292,7 @@ namespace std return !(__y < __x); } - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) @@ -300,7 +300,7 @@ namespace std return !(__x < __y); } - template <typename _Tp, typename _RefL, typename _PtrL, + template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, @@ -313,7 +313,7 @@ namespace std // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. - template <typename _Tp, typename _RefL, typename _PtrL, + template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, @@ -325,7 +325,7 @@ namespace std (__y._M_last - __y._M_cur); } - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _Ptr> inline _Deque_iterator<_Tp, _Ref, _Ptr> operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) { @@ -345,7 +345,7 @@ namespace std * instanceless allocators. * @endif */ - template <typename _Tp, typename _Alloc, bool __is_static> + template<typename _Tp, typename _Alloc, bool __is_static> class _Deque_alloc_base { public: @@ -388,7 +388,7 @@ namespace std }; /// @if maint Specialization for instanceless allocators. @endif - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> class _Deque_alloc_base<_Tp, _Alloc, true> { public: @@ -439,7 +439,7 @@ namespace std * here. * @endif */ - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> class _Deque_base : public _Deque_alloc_base<_Tp,_Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> @@ -470,7 +470,7 @@ namespace std }; - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> _Deque_base<_Tp,_Alloc>::~_Deque_base() { if (this->_M_map) @@ -490,7 +490,7 @@ namespace std * The initial underlying memory layout is a bit complicated... * @endif */ - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> void _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) { @@ -525,7 +525,7 @@ namespace std __num_elements % __deque_buf_size(sizeof(_Tp)); } - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) { _Tp** __cur; @@ -541,7 +541,7 @@ namespace std } } - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> void _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) { @@ -634,7 +634,7 @@ namespace std * and we can use other standard algorithms as well. * @endif */ - template <typename _Tp, typename _Alloc = allocator<_Tp> > + template<typename _Tp, typename _Alloc = allocator<_Tp> > class deque : protected _Deque_base<_Tp, _Alloc> { // concept requirements @@ -1227,13 +1227,13 @@ namespace std * push_back on each value from the iterator. * @endif */ - template <typename _InputIterator> + template<typename _InputIterator> void _M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag); // called by the second initialize_dispatch above - template <typename _ForwardIterator> + template<typename _ForwardIterator> void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); @@ -1278,13 +1278,13 @@ namespace std } // called by the second assign_dispatch above - template <typename _InputIterator> + template<typename _InputIterator> void _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag); // called by the second assign_dispatch above - template <typename _ForwardIterator> + template<typename _ForwardIterator> void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) @@ -1357,13 +1357,13 @@ namespace std } // called by the second insert_dispatch above - template <typename _InputIterator> + template<typename _InputIterator> void _M_range_insert_aux(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag); // called by the second insert_dispatch above - template <typename _ForwardIterator> + template<typename _ForwardIterator> void _M_range_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); @@ -1383,7 +1383,7 @@ namespace std _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); // called by range_insert_aux for forward iterators - template <typename _ForwardIterator> + template<typename _ForwardIterator> void _M_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, @@ -1464,7 +1464,7 @@ namespace std * deques. Deques are considered equivalent if their sizes are equal, * and if corresponding elements compare equal. */ - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> inline bool operator==(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { @@ -1483,7 +1483,7 @@ namespace std * * See std::lexicographical_compare() for how the determination is made. */ - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> inline bool operator<(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { @@ -1492,39 +1492,39 @@ namespace std } /// Based on operator== - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> inline bool operator!=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__x == __y); } /// Based on operator< - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> inline bool operator>(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return __y < __x; } /// Based on operator< - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> inline bool operator<=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__y < __x); } /// Based on operator< - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> inline bool operator>=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__x < __y); } /// See std::deque::swap(). - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) { __x.swap(__y); } -} // namespace std +} // namespace __gnu_norm #endif /* _DEQUE_H */ diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h index 697f2c6f7b7..c16cbe02e6f 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -60,8 +60,53 @@ #ifndef _STL_HEAP_H #define _STL_HEAP_H 1 +#include <debug/debug.h> + 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<typename _RandomAccessIterator, typename _Distance> + 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<typename _RandomAccessIterator, typename _Distance, + typename _StrictWeakOrdering> + 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<typename _RandomAccessIterator> + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template<typename _RandomAccessIterator, typename _StrictWeakOrdering> + 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. @@ -101,6 +146,8 @@ namespace std __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))); @@ -145,6 +192,8 @@ namespace std // 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); @@ -200,6 +249,8 @@ namespace std __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))); } @@ -256,6 +307,8 @@ namespace std // 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); @@ -282,6 +335,7 @@ namespace std __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; @@ -317,7 +371,8 @@ namespace std // 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; @@ -347,6 +402,8 @@ namespace std _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--); @@ -370,6 +427,8 @@ namespace std // 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); diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 4533aee0bed..4524e9ec831 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -63,7 +63,7 @@ #include <bits/concept_check.h> -namespace std +namespace __gnu_norm { // Supporting structures are split into common and templated types; the // latter publicly inherits from the former in an effort to reduce code @@ -89,9 +89,9 @@ namespace std * @if maint * @brief Common part of a list::iterator. * - * A simple type to walk a doubly-linked list. All operations here should - * be self-explanatory after taking any decent introductory data structures - * course. + * A simple type to walk a doubly-linked list. All operations here + * should be self-explanatory after taking any decent introductory + * data structures course. * @endif */ struct _List_iterator_base @@ -233,17 +233,20 @@ namespace std { _M_node_allocator.deallocate(__p, 1); } // NOTA BENE - // The stored instance is not actually of "allocator_type"'s type. Instead - // we rebind the type to Allocator<List_node<Tp>>, which according to - // [20.1.5]/4 should probably be the same. List_node<Tp> is not the same - // size as Tp (it's two pointers larger), and specializations on Tp may go - // unused because List_node<Tp> is being bound instead. + // The stored instance is not actually of "allocator_type"'s type. + // Instead we rebind the type to Allocator<List_node<Tp>>, which + // according to [20.1.5]/4 should probably be the same. + // List_node<Tp> is not the same size as Tp (it's two pointers + // larger), and specializations on Tp may go unused because + // List_node<Tp> is being bound instead. // - // We put this to the test in get_allocator above; if the two types are - // actually different, there had better be a conversion between them. + // We put this to the test in get_allocator above; if the two + // types are actually different, there had better be a conversion + // between them. // - // None of the predefined allocators shipped with the library (as of 3.1) - // use this instantiation anyhow; they're all instanceless. + // None of the predefined allocators shipped with the library (as + // of 3.1) use this instantiation anyhow; they're all + // instanceless. typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type _M_node_allocator; @@ -329,36 +332,37 @@ namespace std * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c at and @c operator[]. * - * This is a @e doubly @e linked %list. Traversal up and down the %list - * requires linear time, but adding and removing elements (or @e nodes) is - * done in constant time, regardless of where the change takes place. - * Unlike std::vector and std::deque, random-access iterators are not - * provided, so subscripting ( @c [] ) access is not allowed. For algorithms - * which only need sequential access, this lack makes no difference. + * This is a @e doubly @e linked %list. Traversal up and down the + * %list requires linear time, but adding and removing elements (or + * @e nodes) is done in constant time, regardless of where the + * change takes place. Unlike std::vector and std::deque, + * random-access iterators are not provided, so subscripting ( @c + * [] ) access is not allowed. For algorithms which only need + * sequential access, this lack makes no difference. * - * Also unlike the other standard containers, std::list provides specialized - * algorithms %unique to linked lists, such as splicing, sorting, and - * in-place reversal. + * Also unlike the other standard containers, std::list provides + * specialized algorithms %unique to linked lists, such as + * splicing, sorting, and in-place reversal. * * @if maint * A couple points on memory allocation for list<Tp>: * - * First, we never actually allocate a Tp, we allocate List_node<Tp>'s - * and trust [20.1.5]/4 to DTRT. This is to ensure that after elements from - * %list<X,Alloc1> are spliced into %list<X,Alloc2>, destroying the memory of - * the second %list is a valid operation, i.e., Alloc1 giveth and Alloc2 - * taketh away. + * First, we never actually allocate a Tp, we allocate + * List_node<Tp>'s and trust [20.1.5]/4 to DTRT. This is to ensure + * that after elements from %list<X,Alloc1> are spliced into + * %list<X,Alloc2>, destroying the memory of the second %list is a + * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. * * Second, a %list conceptually represented as * @code * A <---> B <---> C <---> D * @endcode - * is actually circular; a link exists between A and D. The %list class - * holds (as its only data member) a private list::iterator pointing to - * @e D, not to @e A! To get to the head of the %list, we start at the tail - * and move forward by one. When this member iterator's next/previous - * pointers refer to itself, the %list is %empty. - * @endif + * is actually circular; a link exists between A and D. The %list + * class holds (as its only data member) a private list::iterator + * pointing to @e D, not to @e A! To get to the head of the %list, + * we start at the tail and move forward by one. When this member + * iterator's next/previous pointers refer to itself, the %list is + * %empty. @endif */ template<typename _Tp, typename _Alloc = allocator<_Tp> > class list : protected _List_base<_Tp, _Alloc> @@ -505,18 +509,19 @@ namespace std { this->insert(begin(), __first, __last); } /** - * No explicit dtor needed as the _Base dtor takes care of things. - * The _Base dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. + * No explicit dtor needed as the _Base dtor takes care of + * things. The _Base dtor only erases the elements, and note + * that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. Managing the pointer is the + * user's responsibilty. */ /** * @brief %List assignment operator. * @param x A %list of identical element and allocator types. * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. + * All the elements of @a x are copied, but unlike the copy + * constructor, the allocator object is not copied. */ list& operator=(const list& __x); @@ -526,13 +531,14 @@ namespace std * @param n Number of elements to be assigned. * @param val Value to be assigned. * - * This function fills a %list with @a n copies of the given value. - * Note that the assignment completely changes the %list and that the - * resulting %list's size is the same as the number of elements assigned. - * Old data may be lost. + * This function fills a %list with @a n copies of the given + * value. Note that the assignment completely changes the %list + * and that the resulting %list's size is the same as the number + * of elements assigned. Old data may be lost. */ void - assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } /** * @brief Assigns a range to a %list. @@ -568,44 +574,50 @@ namespace std begin() { return static_cast<_Node*>(this->_M_node._M_next); } /** - * Returns a read-only (constant) iterator that points to the first element - * in the %list. Iteration is done in ordinary element order. + * Returns a read-only (constant) iterator that points to the + * first element in the %list. Iteration is done in ordinary + * element order. */ const_iterator begin() const { return static_cast<_Node*>(this->_M_node._M_next); } /** - * Returns a read/write iterator that points one past the last element in - * the %list. Iteration is done in ordinary element order. + * Returns a read/write iterator that points one past the last + * element in the %list. Iteration is done in ordinary element + * order. */ iterator end() { return static_cast<_Node*>(&this->_M_node); } /** - * Returns a read-only (constant) iterator that points one past the last - * element in the %list. Iteration is done in ordinary element order. + * Returns a read-only (constant) iterator that points one past + * the last element in the %list. Iteration is done in ordinary + * element order. */ const_iterator - end() const { return const_cast<_Node *>(static_cast<const _Node*>(&this->_M_node)); } + end() const + { return const_cast<_Node *>(static_cast<const _Node*>(&this->_M_node)); } /** - * Returns a read/write reverse iterator that points to the last element in - * the %list. Iteration is done in reverse element order. + * Returns a read/write reverse iterator that points to the last + * element in the %list. Iteration is done in reverse element + * order. */ reverse_iterator rbegin() { return reverse_iterator(end()); } /** - * Returns a read-only (constant) reverse iterator that points to the last - * element in the %list. Iteration is done in reverse element order. + * Returns a read-only (constant) reverse iterator that points to + * the last element in the %list. Iteration is done in reverse + * element order. */ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } /** - * Returns a read/write reverse iterator that points to one before the - * first element in the %list. Iteration is done in reverse element - * order. + * Returns a read/write reverse iterator that points to one + * before the first element in the %list. Iteration is done in + * reverse element order. */ reverse_iterator rend() { return reverse_iterator(begin()); } @@ -621,7 +633,8 @@ namespace std // [23.2.2.2] capacity /** - * Returns true if the %list is empty. (Thus begin() would equal end().) + * Returns true if the %list is empty. (Thus begin() would equal + * end().) */ bool empty() const { return this->_M_node._M_next == &this->_M_node; } @@ -635,14 +648,14 @@ namespace std max_size() const { return size_type(-1); } /** - * @brief Resizes the %list to the specified number of elements. - * @param new_size Number of elements the %list should contain. - * @param x Data with which new elements should be populated. + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * @param x Data with which new elements should be populated. * - * This function will %resize the %list to the specified number of - * elements. If the number is smaller than the %list's current size the - * %list is truncated, otherwise the %list is extended and new elements - * are populated with given data. + * This function will %resize the %list to the specified number + * of elements. If the number is smaller than the %list's + * current size the %list is truncated, otherwise the %list is + * extended and new elements are populated with given data. */ void resize(size_type __new_size, const value_type& __x); @@ -652,9 +665,9 @@ namespace std * @param new_size Number of elements the %list should contain. * * This function will resize the %list to the specified number of - * elements. If the number is smaller than the %list's current size the - * %list is truncated, otherwise the %list is extended and new elements - * are default-constructed. + * elements. If the number is smaller than the %list's current + * size the %list is truncated, otherwise the %list is extended + * and new elements are default-constructed. */ void resize(size_type __new_size) { this->resize(__new_size, value_type()); } @@ -675,8 +688,8 @@ namespace std front() const { return *begin(); } /** - * Returns a read/write reference to the data at the last element of the - * %list. + * Returns a read/write reference to the data at the last element + * of the %list. */ reference back() { return *(--end()); } @@ -693,10 +706,11 @@ namespace std * @brief Add data to the front of the %list. * @param x Data to be added. * - * This is a typical stack operation. The function creates an element at - * the front of the %list and assigns the given data to it. Due to the - * nature of a %list this operation can be done in constant time, and - * does not invalidate iterators and references. + * This is a typical stack operation. The function creates an + * element at the front of the %list and assigns the given data + * to it. Due to the nature of a %list this operation can be + * done in constant time, and does not invalidate iterators and + * references. */ void push_front(const value_type& __x) { this->insert(begin(), __x); } @@ -704,13 +718,14 @@ namespace std /** * @brief Removes first element. * - * This is a typical stack operation. It shrinks the %list by one. - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop_front() is called. + * Note that no data is returned, and if the first element's data + * is needed, it should be retrieved before pop_front() is + * called. */ void pop_front() { this->erase(begin()); } @@ -719,10 +734,11 @@ namespace std * @brief Add data to the end of the %list. * @param x Data to be added. * - * This is a typical stack operation. The function creates an element at - * the end of the %list and assigns the given data to it. Due to the - * nature of a %list this operation can be done in constant time, and - * does not invalidate iterators and references. + * This is a typical stack operation. The function creates an + * element at the end of the %list and assigns the given data to + * it. Due to the nature of a %list this operation can be done + * in constant time, and does not invalidate iterators and + * references. */ void push_back(const value_type& __x) { this->insert(end(), __x); } @@ -730,13 +746,13 @@ namespace std /** * @brief Removes last element. * - * This is a typical stack operation. It shrinks the %list by one. - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. * - * Note that no data is returned, and if the last element's data is - * needed, it should be retrieved before pop_back() is called. + * Note that no data is returned, and if the last element's data + * is needed, it should be retrieved before pop_back() is called. */ void pop_back() @@ -751,10 +767,10 @@ namespace std * @param x Data to be inserted. * @return An iterator that points to the inserted data. * - * This function will insert a copy of the given value before the specified - * location. - * Due to the nature of a %list this operation can be done in constant - * time, and does not invalidate iterators and references. + * This function will insert a copy of the given value before the + * specified location. Due to the nature of a %list this + * operation can be done in constant time, and does not + * invalidate iterators and references. */ iterator insert(iterator __position, const value_type& __x); @@ -765,11 +781,12 @@ namespace std * @param n Number of elements to be inserted. * @param x Data to be inserted. * - * This function will insert a specified number of copies of the given data - * before the location specified by @a position. + * This function will insert a specified number of copies of the + * given data before the location specified by @a position. * - * Due to the nature of a %list this operation can be done in constant - * time, and does not invalidate iterators and references. + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. */ void insert(iterator __position, size_type __n, const value_type& __x) @@ -781,16 +798,17 @@ namespace std * @param first An input iterator. * @param last An input iterator. * - * This function will insert copies of the data in the range - * [@a first,@a last) into the %list before the location specified by @a - * position. + * This function will insert copies of the data in the range [@a + * first,@a last) into the %list before the location specified by + * @a position. * * Due to the nature of a %list this operation can be done in constant * time, and does not invalidate iterators and references. */ template<typename _InputIterator> void - insert(iterator __position, _InputIterator __first, _InputIterator __last) + insert(iterator __position, _InputIterator __first, + _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename _Is_integer<_InputIterator>::_Integral _Integral; @@ -805,13 +823,12 @@ namespace std * This function will erase the element at the given position and thus * shorten the %list by one. * - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. - * The user is also cautioned that - * this function only erases the element, and that if the element is itself - * a pointer, the pointed-to memory is not touched in any way. Managing - * the pointer is the user's responsibilty. + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the element, and that if the element + * is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibilty. */ iterator erase(iterator __position); @@ -824,16 +841,16 @@ namespace std * @return An iterator pointing to the element pointed to by @a last * prior to erasing (or end()). * - * This function will erase the elements in the range @a [first,last) and - * shorten the %list accordingly. + * This function will erase the elements in the range @a + * [first,last) and shorten the %list accordingly. * - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. - * The user is also cautioned that - * this function only erases the elements, and that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. */ iterator erase(iterator __first, iterator __last) @@ -847,18 +864,19 @@ namespace std * @brief Swaps data with another %list. * @param x A %list of the same element and allocator types. * - * This exchanges the elements between two lists in constant time. - * Note that the global std::swap() function is specialized such that - * std::swap(l1,l2) will feed to this function. + * This exchanges the elements between two lists in constant + * time. Note that the global std::swap() function is + * specialized such that std::swap(l1,l2) will feed to this + * function. */ void swap(list& __x); /** - * Erases all the elements. Note that this function only erases the - * elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. + * Erases all the elements. Note that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. */ void clear() { _Base::__clear(); } @@ -869,8 +887,9 @@ namespace std * @param position Iterator referencing the element to insert before. * @param x Source list. * - * The elements of @a x are inserted in constant time in front of the - * element referenced by @a position. @a x becomes an empty list. + * The elements of @a x are inserted in constant time in front of + * the element referenced by @a position. @a x becomes an empty + * list. */ void splice(iterator __position, list& __x) @@ -885,8 +904,8 @@ namespace std * @param x Source list. * @param i Iterator referencing the element to move. * - * Removes the element in list @a x referenced by @a i and inserts it into the - * current list before @a position. + * Removes the element in list @a x referenced by @a i and + * inserts it into the current list before @a position. */ void splice(iterator __position, list&, iterator __i) @@ -904,8 +923,8 @@ namespace std * @param first Iterator referencing the start of range in x. * @param last Iterator referencing the end of range in x. * - * Removes elements in the range [first,last) and inserts them before - * @a position in constant time. + * Removes elements in the range [first,last) and inserts them + * before @a position in constant time. * * Undefined if @a position is in [first,last). */ @@ -920,11 +939,11 @@ namespace std * @brief Remove all elements equal to value. * @param value The value to remove. * - * Removes every element in the list equal to @a value. Remaining - * elements stay in list order. Note that this function only erases the - * elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. + * Removes every element in the list equal to @a value. + * Remaining elements stay in list order. Note that this + * function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. */ void remove(const _Tp& __value); @@ -933,11 +952,12 @@ namespace std * @brief Remove all elements satisfying a predicate. * @param Predicate Unary predicate function or object. * - * Removes every element in the list for which the predicate returns - * true. Remaining elements stay in list order. Note that this function - * only erases the elements, and that if the elements themselves are - * pointers, the pointed-to memory is not touched in any way. Managing - * the pointer is the user's responsibilty. + * Removes every element in the list for which the predicate + * returns true. Remaining elements stay in list order. Note + * that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. */ template<typename _Predicate> void @@ -946,11 +966,12 @@ namespace std /** * @brief Remove consecutive duplicate elements. * - * For each consecutive set of elements with the same value, remove all - * but the first one. Remaining elements stay in list order. Note that - * this function only erases the elements, and that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. + * For each consecutive set of elements with the same value, + * remove all but the first one. Remaining elements stay in list + * order. Note that this function only erases the elements, and + * that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. Managing the pointer is the + * user's responsibilty. */ void unique(); @@ -960,11 +981,12 @@ namespace std * @param BinaryPredicate Binary predicate function or object. * * For each consecutive set of elements [first,last) that satisfy - * predicate(first,i) where i is an iterator in [first,last), remove all - * but the first one. Remaining elements stay in list order. Note that - * this function only erases the elements, and that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. + * predicate(first,i) where i is an iterator in [first,last), + * remove all but the first one. Remaining elements stay in list + * order. Note that this function only erases the elements, and + * that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. Managing the pointer is the + * user's responsibilty. */ template<typename _BinaryPredicate> void @@ -975,9 +997,9 @@ namespace std * @param x Sorted list to merge. * * Assumes that both @a x and this list are sorted according to - * operator<(). Merges elements of @a x into this list in sorted order, - * leaving @a x empty when complete. Elements in this list precede - * elements in @a x that are equal. + * operator<(). Merges elements of @a x into this list in sorted + * order, leaving @a x empty when complete. Elements in this + * list precede elements in @a x that are equal. */ void merge(list& __x); @@ -988,9 +1010,10 @@ namespace std * @param StrictWeakOrdering Comparison function definining sort order. * * Assumes that both @a x and this list are sorted according to - * StrictWeakOrdering. Merges elements of @a x into this list in sorted - * order, leaving @a x empty when complete. Elements in this list precede - * elements in @a x that are equivalent according to StrictWeakOrdering(). + * StrictWeakOrdering. Merges elements of @a x into this list in + * sorted order, leaving @a x empty when complete. Elements in + * this list precede elements in @a x that are equivalent + * according to StrictWeakOrdering(). */ template<typename _StrictWeakOrdering> void @@ -1007,8 +1030,8 @@ namespace std /** * @brief Sort the elements. * - * Sorts the elements of this list in NlogN time. Equivalent elements - * remain in list order. + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. */ void sort(); @@ -1016,8 +1039,8 @@ namespace std /** * @brief Sort the elements according to comparison function. * - * Sorts the elements of this list in NlogN time. Equivalent elements - * remain in list order. + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. */ template<typename _StrictWeakOrdering> void @@ -1026,7 +1049,7 @@ namespace std protected: // Internal assign functions follow. - // called by the range assign to implement [23.1.1]/9 + // Called by the range assign to implement [23.1.1]/9 template<typename _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) @@ -1035,20 +1058,21 @@ namespace std static_cast<value_type>(__val)); } - // called by the range assign to implement [23.1.1]/9 + // Called by the range assign to implement [23.1.1]/9 template<typename _InputIterator> void - _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type); + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); - // Called by assign(n,t), and the range assign when it turns out to be the - // same thing. + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. void _M_fill_assign(size_type __n, const value_type& __val); // Internal insert functions follow. - // called by the range insert to implement [23.1.1]/9 + // Called by the range insert to implement [23.1.1]/9 template<typename _Integer> void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, @@ -1058,7 +1082,7 @@ namespace std static_cast<value_type>(__x)); } - // called by the range insert to implement [23.1.1]/9 + // Called by the range insert to implement [23.1.1]/9 template<typename _InputIterator> void _M_insert_dispatch(iterator __pos, @@ -1069,8 +1093,8 @@ namespace std insert(__pos, *__first); } - // Called by insert(p,n,x), and the range insert when it turns out to be - // the same thing. + // Called by insert(p,n,x), and the range insert when it turns out + // to be the same thing. void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { @@ -1105,9 +1129,9 @@ namespace std * @param y A %list of the same type as @a x. * @return True iff the size and elements of the lists are equal. * - * This is an equivalence relation. It is linear in the size of the - * lists. Lists are considered equivalent if their sizes are equal, - * and if corresponding elements compare equal. + * This is an equivalence relation. It is linear in the size of + * the lists. Lists are considered equivalent if their sizes are + * equal, and if corresponding elements compare equal. */ template<typename _Tp, typename _Alloc> inline bool @@ -1174,6 +1198,6 @@ namespace std inline void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) { __x.swap(__y); } -} // namespace std +} // namespace __gnu_norm #endif /* _LIST_H */ diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index 7b15dccae1d..9895cad0446 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -63,7 +63,7 @@ #include <bits/concept_check.h> -namespace std +namespace __gnu_norm { /** * @brief A standard container made up of (key,value) pairs, which can be @@ -653,6 +653,6 @@ namespace std inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } -} // namespace std +} // namespace __gnu_norm #endif /* _MAP_H */ diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index ebc7ff9137b..4d892283bce 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -63,7 +63,7 @@ #include <bits/concept_check.h> -namespace std +namespace __gnu_norm { // Forward declaration of operators < and ==, needed for friend declaration. @@ -632,6 +632,6 @@ namespace std swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, multimap<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } -} // namespace std +} // namespace __gnu_norm #endif /* _MULTIMAP_H */ diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index 49d8c4ea4f7..d85c910a4e0 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -63,7 +63,7 @@ #include <bits/concept_check.h> -namespace std +namespace __gnu_norm { // Forward declaration of operators < and ==, needed for friend declaration. @@ -256,6 +256,6 @@ inline void swap(multiset<_Key,_Compare,_Alloc>& __x, __x.swap(__y); } -} // namespace std +} // namespace __gnu_norm #endif /* _MULTISET_H */ diff --git a/libstdc++-v3/include/bits/stl_numeric.h b/libstdc++-v3/include/bits/stl_numeric.h index 4aa92edf91d..7b901a54315 100644 --- a/libstdc++-v3/include/bits/stl_numeric.h +++ b/libstdc++-v3/include/bits/stl_numeric.h @@ -61,6 +61,8 @@ #ifndef _STL_NUMERIC_H #define _STL_NUMERIC_H 1 +#include <debug/debug.h> + namespace std { @@ -70,6 +72,7 @@ namespace std { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __init = __init + *__first; @@ -83,6 +86,7 @@ namespace std { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __init = __binary_op(__init, *__first); @@ -97,6 +101,7 @@ namespace std // 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); @@ -114,6 +119,7 @@ namespace std // 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)); @@ -130,6 +136,7 @@ namespace std // 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; @@ -151,6 +158,7 @@ namespace std // 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; @@ -172,6 +180,7 @@ namespace std // 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; @@ -194,6 +203,7 @@ namespace std // 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; diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h index 0bb41acaf9f..441fc55ef4b 100644 --- a/libstdc++-v3/include/bits/stl_queue.h +++ b/libstdc++-v3/include/bits/stl_queue.h @@ -62,20 +62,21 @@ #define _QUEUE_H 1 #include <bits/concept_check.h> +#include <debug/debug.h> namespace std { // Forward declarations of operators < and ==, needed for friend declaration. + template<typename _Tp, typename _Sequence = deque<_Tp> > + class queue; - template <typename _Tp, typename _Sequence = deque<_Tp> > - class queue; - - template <typename _Tp, typename _Seq> - inline bool operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); - - template <typename _Tp, typename _Seq> - inline bool operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + template<typename _Tp, typename _Seq> + inline bool + operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + template<typename _Tp, typename _Seq> + inline bool + operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); /** * @brief A standard container giving FIFO behavior. @@ -101,111 +102,133 @@ namespace std * which is a typedef for the second Sequence parameter, and @c push and * @c pop, which are standard %queue/FIFO operations. */ - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> class queue - { - // concept requirements - typedef typename _Sequence::value_type _Sequence_value_type; - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept) - __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) - __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) - - template <typename _Tp1, typename _Seq1> - friend bool operator== (const queue<_Tp1, _Seq1>&, - const queue<_Tp1, _Seq1>&); - template <typename _Tp1, typename _Seq1> - friend bool operator< (const queue<_Tp1, _Seq1>&, - const queue<_Tp1, _Seq1>&); - - public: - typedef typename _Sequence::value_type value_type; - typedef typename _Sequence::reference reference; - typedef typename _Sequence::const_reference const_reference; - typedef typename _Sequence::size_type size_type; - typedef _Sequence container_type; - - protected: - /** - * 'c' is the underlying container. Maintainers wondering why this isn't - * uglified as per style guidelines should note that this name is - * specified in the standard, [23.2.3.1]. (Why? Presumably for the same - * reason that it's protected instead of private: to allow derivation. - * But none of the other containers allow for derivation. Odd.) - */ - _Sequence c; - - public: - /** - * @brief Default constructor creates no elements. - */ - explicit - queue(const _Sequence& __c = _Sequence()) - : c(__c) {} - - /** - * Returns true if the %queue is empty. - */ - bool - empty() const { return c.empty(); } - - /** Returns the number of elements in the %queue. */ - size_type - size() const { return c.size(); } - - /** - * Returns a read/write reference to the data at the first element of the - * %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. - * @param x Data to be added. - * - * This is a typical %queue operation. The function creates an element at - * the end of the %queue and assigns the given data to it. - * The time complexity of the operation depends on the underlying - * sequence. - */ - void - push(const value_type& __x) { c.push_back(__x); } - - /** - * @brief Removes first element. - * - * This is a typical %queue operation. It shrinks the %queue by one. - * The time complexity of the operation depends on the underlying - * sequence. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop() is called. - */ - void - pop() { c.pop_front(); } - }; + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template<typename _Tp1, typename _Seq1> + friend bool + operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + template<typename _Tp1, typename _Seq1> + friend bool + operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + /** + * 'c' is the underlying container. Maintainers wondering why + * this isn't uglified as per style guidelines should note that + * this name is specified in the standard, [23.2.3.1]. (Why? + * Presumably for the same reason that it's protected instead + * of private: to allow derivation. But none of the other + * containers allow for derivation. Odd.) + */ + _Sequence c; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + queue(const _Sequence& __c = _Sequence()) : c(__c) {} + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %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. + * @param x Data to be added. + * + * This is a typical %queue operation. The function creates an + * element at the end of the %queue and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue by one. + * The time complexity of the operation depends on the underlying + * sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_front(); + } + }; /** @@ -219,9 +242,10 @@ namespace std * linear in the size of the sequences, and queues are considered equivalent * if their sequences compare equal. */ - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool - operator==(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + operator==(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return __x.c == __y.c; } /** @@ -230,39 +254,43 @@ namespace std * @param y A %queue of the same type as @a x. * @return True iff @a x is lexicographically less than @a y. * - * This is an total ordering relation. Complexity and semantics depend on - * the underlying sequence type, but the expected rules are: this relation - * is linear in the size of the sequences, the elements must be comparable - * with @c <, and std::lexicographical_compare() is usually used to make the + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the * determination. */ - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool operator<(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) { return __x.c < __y.c; } /// Based on operator== - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool - operator!=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + operator!=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return !(__x == __y); } /// Based on operator< - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool operator>(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) { return __y < __x; } /// Based on operator< - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool - operator<=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + operator<=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return !(__y < __x); } /// Based on operator< - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool - operator>=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + operator>=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return !(__x < __y); } @@ -272,157 +300,169 @@ namespace std * @ingroup Containers * @ingroup Sequences * - * This is not a true container, but an @e adaptor. It holds another - * container, and provides a wrapper interface to that container. The - * wrapper is what enforces sorting and first-in-first-out %queue behavior. - * Very few of the standard container/sequence interface requirements are - * met (e.g., iterators). + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces sorting and + * first-in-first-out %queue behavior. Very few of the standard + * container/sequence interface requirements are met (e.g., + * iterators). * * The second template parameter defines the type of the underlying - * sequence/container. It defaults to std::vector, but it can be any type - * that supports @c front(), @c push_back, @c pop_back, and random-access - * iterators, such as std::deque or an appropriate user-defined type. + * sequence/container. It defaults to std::vector, but it can be + * any type that supports @c front(), @c push_back, @c pop_back, + * and random-access iterators, such as std::deque or an + * appropriate user-defined type. * - * The third template parameter supplies the means of making priority - * comparisons. It defaults to @c less<value_type> but can be anything - * defining a strict weak ordering. + * The third template parameter supplies the means of making + * priority comparisons. It defaults to @c less<value_type> but + * can be anything defining a strict weak ordering. * * Members not found in "normal" containers are @c container_type, - * which is a typedef for the second Sequence parameter, and @c push, - * @c pop, and @c top, which are standard %queue/FIFO operations. + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %queue/FIFO + * operations. * - * @note No equality/comparison operators are provided for %priority_queue. + * @note No equality/comparison operators are provided for + * %priority_queue. * - * @note Sorting of the elements takes place as they are added to, and - * removed from, the %priority_queue using the %priority_queue's - * member functions. If you access the elements by other means, and - * change their data such that the sorting order would be different, - * the %priority_queue will not re-sort the elements for you. (How - * could it know to do so?) + * @note Sorting of the elements takes place as they are added to, + * and removed from, the %priority_queue using the + * %priority_queue's member functions. If you access the elements + * by other means, and change their data such that the sorting + * order would be different, the %priority_queue will not re-sort + * the elements for you. (How could it know to do so?) */ - template <typename _Tp, typename _Sequence = vector<_Tp>, + template<typename _Tp, typename _Sequence = vector<_Tp>, typename _Compare = less<typename _Sequence::value_type> > class priority_queue - { - // concept requirements - typedef typename _Sequence::value_type _Sequence_value_type; - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - __glibcxx_class_requires(_Sequence, _SequenceConcept) - __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept) - __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) - __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp, _BinaryFunctionConcept) - - public: - typedef typename _Sequence::value_type value_type; - typedef typename _Sequence::reference reference; - typedef typename _Sequence::const_reference const_reference; - typedef typename _Sequence::size_type size_type; - typedef _Sequence container_type; - - protected: - // See queue::c for notes on these names. - _Sequence c; - _Compare comp; - - public: - /** - * @brief Default constructor creates no elements. - */ - explicit - priority_queue(const _Compare& __x = _Compare(), - const _Sequence& __s = _Sequence()) - : c(__s), comp(__x) - { std::make_heap(c.begin(), c.end(), comp); } - - /** - * @brief Builds a %queue from a range. - * @param first An input iterator. - * @param last An input iterator. - * @param x A comparison functor describing a strict weak ordering. - * @param s An initial sequence with which to start. - * - * Begins by copying @a s, inserting a copy of the elements from - * @a [first,last) into the copy of @a s, then ordering the copy - * according to @a x. - * - * For more information on function objects, see the documentation on - * @link s20_3_1_base functor base classes@endlink. - */ - template <typename _InputIterator> - priority_queue(_InputIterator __first, _InputIterator __last, - const _Compare& __x = _Compare(), - const _Sequence& __s = _Sequence()) - : c(__s), comp(__x) - { - c.insert(c.end(), __first, __last); - std::make_heap(c.begin(), c.end(), comp); - } - - /** - * Returns true if the %queue is empty. - */ - bool - empty() const { return c.empty(); } - - /** Returns the number of elements in the %queue. */ - size_type - size() const { return c.size(); } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %queue. - */ - const_reference - top() const { return c.front(); } - - /** - * @brief Add data to the %queue. - * @param x Data to be added. - * - * This is a typical %queue operation. - * The time complexity of the operation depends on the underlying - * sequence. - */ - void - push(const value_type& __x) { - try + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _SequenceConcept) + __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + __glibcxx_class_requires4(_Compare, bool, _Tp,_Tp,_BinaryFunctionConcept) + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on these names. + _Sequence c; + _Compare comp; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + priority_queue(const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { std::make_heap(c.begin(), c.end(), comp); } + + /** + * @brief Builds a %queue from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param x A comparison functor describing a strict weak ordering. + * @param s An initial sequence with which to start. + * + * Begins by copying @a s, inserting a copy of the elements + * from @a [first,last) into the copy of @a s, then ordering + * the copy according to @a x. + * + * For more information on function objects, see the + * documentation on @link s20_3_1_base functor base + * classes@endlink. + */ + template<typename _InputIterator> + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x = _Compare(), + 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); + } + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const { return c.size(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * @brief Add data to the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. + * The time complexity of the operation depends on the underlying + * sequence. + */ + void + push(const value_type& __x) + { + try { c.push_back(__x); std::push_heap(c.begin(), c.end(), comp); } - catch(...) + catch(...) { c.clear(); __throw_exception_again; } - } - - /** - * @brief Removes first element. - * - * This is a typical %queue operation. It shrinks the %queue by one. - * The time complexity of the operation depends on the underlying - * sequence. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop() is called. - */ - void - pop() - { - try + } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + try { std::pop_heap(c.begin(), c.end(), comp); c.pop_back(); } - catch(...) + catch(...) { c.clear(); __throw_exception_again; } - } - }; + } + }; // No equality/comparison operators are provided for priority_queue. } // namespace std diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index fa8c6cfb707..d1494b9db03 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -63,37 +63,36 @@ #include <bits/concept_check.h> -namespace std +namespace __gnu_norm { - -// Forward declarations of operators < and ==, needed for friend declaration. - -template <class _Key, class _Compare = less<_Key>, - class _Alloc = allocator<_Key> > -class set; - -template <class _Key, class _Compare, class _Alloc> -inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, - const set<_Key,_Compare,_Alloc>& __y); - -template <class _Key, class _Compare, class _Alloc> -inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, - const set<_Key,_Compare,_Alloc>& __y); - - -template <class _Key, class _Compare, class _Alloc> -class set -{ - // concept requirements - __glibcxx_class_requires(_Key, _SGIAssignableConcept) - __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) - -public: - // typedefs: - typedef _Key key_type; - typedef _Key value_type; - typedef _Compare key_compare; - typedef _Compare value_compare; + // Forward declarations of operators < and ==, needed for friend declaration. + template<class _Key, class _Compare = less<_Key>, + class _Alloc = allocator<_Key> > + class set; + + template<class _Key, class _Compare, class _Alloc> + inline bool + operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + template<class _Key, class _Compare, class _Alloc> + inline bool + operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + template<class _Key, class _Compare, class _Alloc> + class set + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) + + public: + // typedefs: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; private: typedef _Rb_tree<key_type, value_type, _Identity<value_type>, key_compare, _Alloc> _Rep_type; @@ -118,12 +117,12 @@ public: const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) {} - template <class _InputIterator> + template<class _InputIterator> set(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } - template <class _InputIterator> + template<class _InputIterator> set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } @@ -159,7 +158,7 @@ public: typedef typename _Rep_type::iterator _Rep_iterator; return _M_t.insert_unique((_Rep_iterator&)__position, __x); } - template <class _InputIterator> + template<class _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_unique(__first, __last); } @@ -205,54 +204,54 @@ public: return _M_t.equal_range(__x); } - template <class _K1, class _C1, class _A1> + template<class _K1, class _C1, class _A1> friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); - template <class _K1, class _C1, class _A1> + template<class _K1, class _C1, class _A1> friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); }; -template <class _Key, class _Compare, class _Alloc> +template<class _Key, class _Compare, class _Alloc> inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } -template <class _Key, class _Compare, class _Alloc> +template<class _Key, class _Compare, class _Alloc> inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } -template <class _Key, class _Compare, class _Alloc> +template<class _Key, class _Compare, class _Alloc> inline bool operator!=(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return !(__x == __y); } -template <class _Key, class _Compare, class _Alloc> +template<class _Key, class _Compare, class _Alloc> inline bool operator>(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return __y < __x; } -template <class _Key, class _Compare, class _Alloc> +template<class _Key, class _Compare, class _Alloc> inline bool operator<=(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return !(__y < __x); } -template <class _Key, class _Compare, class _Alloc> +template<class _Key, class _Compare, class _Alloc> inline bool operator>=(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return !(__x < __y); } -template <class _Key, class _Compare, class _Alloc> +template<class _Key, class _Compare, class _Alloc> inline void swap(set<_Key,_Compare,_Alloc>& __x, set<_Key,_Compare,_Alloc>& __y) { __x.swap(__y); } -} // namespace std +} // namespace __gnu_norm #endif /* _SET_H */ diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h index b9847ceb6ad..d72755a9fae 100644 --- a/libstdc++-v3/include/bits/stl_stack.h +++ b/libstdc++-v3/include/bits/stl_stack.h @@ -62,20 +62,22 @@ #define _STACK_H 1 #include <bits/concept_check.h> +#include <debug/debug.h> namespace std { - // Forward declarations of operators == and <, needed for friend declaration. + // Forward declarations of operators == and <, needed for friend + // declaration. + template<typename _Tp, typename _Sequence = deque<_Tp> > + class stack; - template <typename _Tp, typename _Sequence = deque<_Tp> > - class stack; + template<typename _Tp, typename _Seq> + inline bool + operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); - template <typename _Tp, typename _Seq> - inline bool operator==(const stack<_Tp,_Seq>& __x, - const stack<_Tp,_Seq>& __y); - - template <typename _Tp, typename _Seq> - inline bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + template<typename _Tp, typename _Seq> + inline bool + operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); /** @@ -89,104 +91,120 @@ namespace std * but does not define anything to do with iterators. Very few of the * other standard container interfaces are defined. * - * This is not a true container, but an @e adaptor. It holds another - * container, and provides a wrapper interface to that container. The - * wrapper is what enforces strict first-in-last-out %stack behavior. + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces strict + * first-in-last-out %stack behavior. * * The second template parameter defines the type of the underlying - * sequence/container. It defaults to std::deque, but it can be any type - * that supports @c back, @c push_back, and @c pop_front, such as - * std::list, std::vector, or an appropriate user-defined type. + * sequence/container. It defaults to std::deque, but it can be + * any type that supports @c back, @c push_back, and @c pop_front, + * such as std::list, std::vector, or an appropriate user-defined + * type. * * Members not found in "normal" containers are @c container_type, - * which is a typedef for the second Sequence parameter, and @c push, - * @c pop, and @c top, which are standard %stack/FILO operations. + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %stack/FILO + * operations. */ - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> class stack - { - // concept requirements - typedef typename _Sequence::value_type _Sequence_value_type; - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) - __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) - - template <typename _Tp1, typename _Seq1> - friend bool operator== (const stack<_Tp1, _Seq1>&, - const stack<_Tp1, _Seq1>&); - template <typename _Tp1, typename _Seq1> - friend bool operator< (const stack<_Tp1, _Seq1>&, - const stack<_Tp1, _Seq1>&); - - public: - typedef typename _Sequence::value_type value_type; - typedef typename _Sequence::reference reference; - typedef typename _Sequence::const_reference const_reference; - typedef typename _Sequence::size_type size_type; - typedef _Sequence container_type; - - protected: - // See queue::c for notes on this name. - _Sequence c; - - public: - // XXX removed old def ctor, added def arg to this one to match 14882 - /** - * @brief Default constructor creates no elements. - */ - explicit - stack(const _Sequence& __c = _Sequence()) - : c(__c) {} + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) - /** - * Returns true if the %stack is empty. - */ - bool - empty() const { return c.empty(); } - - /** Returns the number of elements in the %stack. */ - size_type - size() const { return c.size(); } - - /** - * Returns a read/write reference to the data at the first element of the - * %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(); } + template<typename _Tp1, typename _Seq1> + friend bool + operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + template<typename _Tp1, typename _Seq1> + friend bool + operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); - /** - * @brief Add data to the top of the %stack. - * @param x Data to be added. - * - * This is a typical %stack operation. The function creates an element at - * the top of the %stack and assigns the given data to it. - * The time complexity of the operation depends on the underlying - * sequence. - */ - void - push(const value_type& __x) { c.push_back(__x); } + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on this name. + _Sequence c; + + public: + // XXX removed old def ctor, added def arg to this one to match 14882 + /** + * @brief Default constructor creates no elements. + */ + explicit + stack(const _Sequence& __c = _Sequence()) : c(__c) {} + + /** + * Returns true if the %stack is empty. + */ + bool + empty() const { return c.empty(); } + + /** Returns the number of elements in the %stack. */ + size_type + size() const { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %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. + * @param x Data to be added. + * + * This is a typical %stack operation. The function creates an + * element at the top of the %stack and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) { c.push_back(__x); } - /** - * @brief Removes first element. - * - * This is a typical %stack operation. It shrinks the %stack by one. - * The time complexity of the operation depends on the underlying - * sequence. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop() is called. - */ - void - pop() { c.pop_back(); } - }; + /** + * @brief Removes first element. + * + * This is a typical %stack operation. It shrinks the %stack + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_back(); + } + }; /** @@ -195,12 +213,13 @@ namespace std * @param y A %stack of the same type as @a x. * @return True iff the size and elements of the stacks are equal. * - * This is an equivalence relation. Complexity and semantics depend on the - * underlying sequence type, but the expected rules are: this relation is - * linear in the size of the sequences, and stacks are considered equivalent - * if their sequences compare equal. + * This is an equivalence relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, and + * stacks are considered equivalent if their sequences compare + * equal. */ - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return __x.c == __y.c; } @@ -211,37 +230,38 @@ namespace std * @param y A %stack of the same type as @a x. * @return True iff @a x is lexicographically less than @a y. * - * This is an total ordering relation. Complexity and semantics depend on - * the underlying sequence type, but the expected rules are: this relation - * is linear in the size of the sequences, the elements must be comparable - * with @c <, and std::lexicographical_compare() is usually used to make the + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the * determination. */ - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return __x.c < __y.c; } /// Based on operator== - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return !(__x == __y); } /// Based on operator< - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return __y < __x; } /// Based on operator< - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return !(__y < __x); } /// Based on operator< - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return !(__x < __y); } diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index e911697210d..94d6a4a1317 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -65,7 +65,7 @@ #include <bits/functexcept.h> #include <bits/concept_check.h> -namespace std +namespace __gnu_norm { /// @if maint Primary default version. @endif /** @@ -966,6 +966,6 @@ namespace std inline void swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y) { __x.swap(__y); } -} // namespace std +} // namespace __gnu_norm #endif /* _VECTOR_H */ diff --git a/libstdc++-v3/include/bits/stream_iterator.h b/libstdc++-v3/include/bits/stream_iterator.h index dcbf9f01d91..cc67505dd69 100644 --- a/libstdc++-v3/include/bits/stream_iterator.h +++ b/libstdc++-v3/include/bits/stream_iterator.h @@ -37,6 +37,8 @@ #pragma GCC system_header +#include <debug/debug.h> + namespace std { template<typename _Tp, typename _CharT = char, @@ -65,18 +67,33 @@ namespace std { } const _Tp& - operator*() const { return _M_value; } + operator*() const + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_deref_istream) + ._M_iterator(*this)); + return _M_value; + } const _Tp* operator->() const { return &(operator*()); } istream_iterator& operator++() - { _M_read(); return *this; } + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + _M_read(); + return *this; + } istream_iterator operator++(int) { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); istream_iterator __tmp = *this; _M_read(); return __tmp; @@ -138,6 +155,9 @@ namespace std ostream_iterator& operator=(const _Tp& __value) { + __glibcxx_requires_cond(_M_stream != 0, + _M_message(__gnu_debug::__msg_output_ostream) + ._M_iterator(*this)); *_M_stream << __value; if (_M_string) *_M_stream << _M_string; return *this; diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 51d8384b54d..d193de280c3 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -39,6 +39,7 @@ #pragma GCC system_header #include <streambuf> +#include <debug/debug.h> // NB: Should specialize copy, find algorithms for streambuf iterators. @@ -82,11 +83,23 @@ namespace std // NB: The result of operator*() on an end of stream is undefined. char_type operator*() const - { return traits_type::to_char_type(_M_get()); } + { +#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::__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::__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; @@ -98,6 +111,10 @@ namespace std istreambuf_iterator operator++(int) { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + const int_type __eof = traits_type::eof(); istreambuf_iterator __old = *this; if (_M_sbuf @@ -116,8 +133,8 @@ namespace std 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); + bool __thiseof = _M_at_eof(); + bool __beof = __b._M_at_eof(); return (__thiseof && __beof || (!__thiseof && !__beof)); } @@ -137,6 +154,13 @@ namespace std } return __ret; } + + bool + _M_at_eof() const + { + const int_type __eof = traits_type::eof(); + return traits_type::eq_int_type(_M_get(), __eof); + } }; template<typename _CharT, typename _Traits> diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 181b3596243..6342743266a 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -61,7 +61,7 @@ #ifndef _VECTOR_TCC #define _VECTOR_TCC 1 -namespace std +namespace __gnu_norm { template<typename _Tp, typename _Alloc> void @@ -432,7 +432,8 @@ namespace std { __new_finish = std::uninitialized_copy(iterator(this->_M_start), __position, __new_start); - __new_finish = std::uninitialized_copy(__first, __last, __new_finish); + __new_finish = std::uninitialized_copy(__first, __last, + __new_finish); __new_finish = std::uninitialized_copy(__position, iterator(this->_M_finish), __new_finish); @@ -452,6 +453,6 @@ namespace std } } } -} // namespace std +} // namespace __gnu_norm #endif /* _VECTOR_TCC */ diff --git a/libstdc++-v3/include/debug/bitset b/libstdc++-v3/include/debug/bitset new file mode 100644 index 00000000000..3c474cf9d82 --- /dev/null +++ b/libstdc++-v3/include/debug/bitset @@ -0,0 +1,298 @@ +// 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 +#define _GLIBCXX_DEBUG_BITSET + +#include <bitset> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<size_t _Nb> + class bitset + : public __gnu_norm::bitset<_Nb>, public __gnu_debug::_Safe_sequence_base + { + typedef __gnu_norm::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::__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::__msg_bad_bitset_read) + ._M_iterator(__x)); + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__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::__msg_bad_bitset_read) + ._M_iterator(*this)); + return ~(*static_cast<const _Base_ref*>(this)); + } + + operator bool() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return *static_cast<const _Base_ref*>(this); + } + + reference& + flip() + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__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<typename _CharT, typename _Traits, typename _Allocator> + 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 <typename _CharT, typename _Traits, typename _Allocator> + 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<size_t _Nb> + bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) &= __y; } + + template<size_t _Nb> + bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) |= __y; } + + template<size_t _Nb> + bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) ^= __y; } + + template<typename _CharT, typename _Traits, size_t _Nb> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { return __is >> __x._M_base(); } + + template<typename _CharT, typename _Traits, size_t _Nb> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bitset<_Nb>& __x) + { return __os << __x._M_base(); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h new file mode 100644 index 00000000000..edb19aa85c3 --- /dev/null +++ b/libstdc++-v3/include/debug/debug.h @@ -0,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 1 + +/** + * 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::__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::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__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::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__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::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__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::__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::__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::__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::__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::__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::__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::__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::__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::__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 <cassert> // TBD: temporary + +#include <stddef.h> // for ptrdiff_t +#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories +#include <bits/type_traits.h> // for _Is_integer + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + 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<typename _Iterator> + inline bool + __check_singular(_Iterator& __x) + { return __gnu_debug::__check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template<typename _Tp> + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + 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<typename _Iterator> + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template<typename _Tp> + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + 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<typename _RandomAccessIterator> + 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<typename _InputIterator> + 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<typename _Integral> + 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<typename _InputIterator> + 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<typename _InputIterator> + 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<typename _Iterator, typename _Sequence> + 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<typename _InputIterator> + 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<typename _CharT, typename _Integer> + 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<typename _CharT> + 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<typename _InputIterator> + 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<typename _ForwardIterator> + 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<typename _InputIterator, typename _Predicate> + 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<typename _ForwardIterator, typename _Predicate> + 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<typename _InputIterator> + 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<typename _InputIterator, typename _Predicate> + 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<typename _ForwardIterator, typename _Tp> + 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<typename _ForwardIterator, typename _Tp, typename _Pred> + 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 <debug/formatter.h> +#endif + +#endif diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque new file mode 100644 index 00000000000..b9d68af598a --- /dev/null +++ b/libstdc++-v3/include/debug/deque @@ -0,0 +1,386 @@ +// 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 +#define _GLIBCXX_DEBUG_DEQUE 1 + +#include <deque> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Tp, typename _Allocator = std::allocator<_Tp> > + class deque + : public __gnu_norm::deque<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> > + { + typedef __gnu_norm::deque<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<deque> _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque> + 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<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<class _InputIterator> + 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<class _InputIterator> + 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 __res = _Base::insert(__position.base(), __x); + this->_M_invalidate_all(); + return iterator(__res, 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<class _InputIterator> + 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 __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, 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 __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, 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<typename _Tp, typename _Alloc> + inline bool + operator==(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h new file mode 100644 index 00000000000..317ce21bc25 --- /dev/null +++ b/libstdc++-v3/include/debug/formatter.h @@ -0,0 +1,385 @@ +// 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 1 + +#include <typeinfo> +#include <debug/debug.h> + +namespace __gnu_debug +{ + /** Determine if the two types are the same. */ + template<typename _Type1, typename _Type2> + struct __is_same + { + static const bool value = false; + }; + + template<typename _Type> + struct __is_same<_Type, _Type> + { + static const bool value = true; + }; + + template<bool> struct __truth { }; + + class _Safe_sequence_base; + + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + template<typename _Sequence> + class _Safe_sequence; + + enum _Debug_msg_id + { + // General checks + __msg_valid_range, + __msg_insert_singular, + __msg_insert_different, + __msg_erase_bad, + __msg_erase_different, + __msg_subscript_oob, + __msg_empty, + __msg_unpartitioned, + __msg_unpartitioned_pred, + __msg_unsorted, + __msg_unsorted_pred, + __msg_not_heap, + __msg_not_heap_pred, + // std::bitset checks + __msg_bad_bitset_write, + __msg_bad_bitset_read, + __msg_bad_bitset_flip, + // std::list checks + __msg_self_splice, + __msg_splice_alloc, + __msg_splice_bad, + __msg_splice_other, + __msg_splice_overlap, + // iterator checks + __msg_init_singular, + __msg_init_copy_singular, + __msg_init_const_singular, + __msg_copy_singular, + __msg_bad_deref, + __msg_bad_inc, + __msg_bad_dec, + __msg_iter_subscript_oob, + __msg_advance_oob, + __msg_retreat_oob, + __msg_iter_compare_bad, + __msg_compare_different, + __msg_iter_order_bad, + __msg_order_different, + __msg_distance_bad, + __msg_distance_different, + // istream_iterator + __msg_deref_istream, + __msg_inc_istream, + // ostream_iterator + __msg_output_ostream, + // istreambuf_iterator + __msg_deref_istreambuf, + __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<typename _Iterator, typename _Sequence> + _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 = + __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<typename _Type> + _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<typename _Type> + _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<typename _Iterator> + _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<typename _Sequence> + _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<const _Sequence*>(&__seq); + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + template<typename _Sequence> + _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<typename _Iterator> + 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<typename _Sequence> + 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 diff --git a/libstdc++-v3/include/debug/hash_map b/libstdc++-v3/include/debug/hash_map new file mode 100644 index 00000000000..570a9af6b69 --- /dev/null +++ b/libstdc++-v3/include/debug/hash_map @@ -0,0 +1,38 @@ +// 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_DEBUG_HASH_MAP +#define _GLIBCXX_DEBUG_HASH_MAP 1 + +#include <hash_map> +#include <debug/dbg_hash_map.h> +#include <debug/dbg_hash_multimap.h> + +#endif diff --git a/libstdc++-v3/include/debug/hash_map.h b/libstdc++-v3/include/debug/hash_map.h new file mode 100644 index 00000000000..5ca102ad68a --- /dev/null +++ b/libstdc++-v3/include/debug/hash_map.h @@ -0,0 +1,270 @@ +// 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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, typename _Tp, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_map + : public __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_map<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc> > + { + typedef __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_map> _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<typename _Base::iterator, hash_map> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_map> + 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<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + 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<iterator, bool> + insert(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.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<iterator, iterator> + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.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<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + 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<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + 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<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline void + swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/hash_multimap.h b/libstdc++-v3/include/debug/hash_multimap.h new file mode 100644 index 00000000000..dd453d61c72 --- /dev/null +++ b/libstdc++-v3/include/debug/hash_multimap.h @@ -0,0 +1,261 @@ +// 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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, typename _Tp, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multimap + : public __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc>, + public __gnu_debug::_Safe_sequence<hash_multimap<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc> > + { + typedef __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_multimap> _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<typename _Base::iterator, + hash_multimap> iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_multimap> 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<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + 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 <typename _InputIterator> + 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<iterator, iterator> + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + std::pair<iterator, iterator> __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<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + 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<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + 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<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline void + swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/hash_multiset.h b/libstdc++-v3/include/debug/hash_multiset.h new file mode 100644 index 00000000000..cacad0353be --- /dev/null +++ b/libstdc++-v3/include/debug/hash_multiset.h @@ -0,0 +1,236 @@ +// 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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multiset + : public __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_multiset<_Value, _HashFcn, + _EqualKey, _Alloc> > + { + typedef __gnu_cxx:: hash_multiset<_Value,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_multiset> _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<typename _Base::iterator, + hash_multiset> iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_multiset> 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<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template<typename _InputIterator> + 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 <typename _InputIterator> + 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<iterator, iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + size_type __count = 0; + std::pair<iterator, iterator> __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<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + 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<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + 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<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + inline void + swap(hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/hash_set b/libstdc++-v3/include/debug/hash_set new file mode 100644 index 00000000000..13d879de5bb --- /dev/null +++ b/libstdc++-v3/include/debug/hash_set @@ -0,0 +1,38 @@ +// 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_DEBUG_HASH_SET +#define _GLIBCXX_DEBUG_HASH_SET 1 + +#include <hash_set> +#include <debug/dbg_hash_set.h> +#include <debug/dbg_hash_multiset.h> + +#endif diff --git a/libstdc++-v3/include/debug/hash_set.h b/libstdc++-v3/include/debug/hash_set.h new file mode 100644 index 00000000000..88afb9092d9 --- /dev/null +++ b/libstdc++-v3/include/debug/hash_set.h @@ -0,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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_set + : public __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_set<_Value, _HashFcn, _EqualKey, + _Alloc> > + { + typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Base; + typedef __gnu_debug::_Safe_sequence<hash_set> _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<typename _Base::iterator, hash_set> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_set> + 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<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + 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<iterator, bool> + insert(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.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<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + 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<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + 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<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + inline void + swap(hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list new file mode 100644 index 00000000000..79dcb1d13d8 --- /dev/null +++ b/libstdc++-v3/include/debug/list @@ -0,0 +1,505 @@ +// 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 +#define _GLIBCXX_DEBUG_LIST 1 + +#include <list> +#include <bits/stl_algo.h> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Tp, typename _Allocator = std::allocator<_Tp> > + class list + : public __gnu_norm::list<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> > + { + typedef __gnu_norm::list<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<list> _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, list> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, list> + 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<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<class _InputIterator> + 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<class _InputIterator> + 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<class _InputIterator> + 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::__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::__msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x, "__x")); + _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(), + _M_message(::__gnu_debug::__msg_splice_bad) + ._M_iterator(__i, "__i")); + _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x), + _M_message(::__gnu_debug::__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::__msg_splice_other) + ._M_sequence(__x, "x") + ._M_iterator(__first, "first")); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__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::__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<class _Predicate> + 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<class _BinaryPredicate> + 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<class _Compare> + 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<typename _StrictWeakOrdering> + 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<typename _Tp, typename _Alloc> + inline bool + operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/map b/libstdc++-v3/include/debug/map new file mode 100644 index 00000000000..2c384048718 --- /dev/null +++ b/libstdc++-v3/include/debug/map @@ -0,0 +1,38 @@ +// 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_DEBUG_MAP +#define _GLIBCXX_DEBUG_MAP 1 + +#include <map> +#include <debug/map.h> +#include <debug/multimap.h> + +#endif diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h new file mode 100644 index 00000000000..d8609bdffb8 --- /dev/null +++ b/libstdc++-v3/include/debug/map.h @@ -0,0 +1,323 @@ +// 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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > + class map + : public __gnu_norm::map<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> > + { + typedef __gnu_norm::map<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<map> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> 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<typename _Base::iterator, map> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, map> + 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<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<typename _InputIterator> + 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<iterator, bool> + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair<iterator, bool>(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template<typename _InputIterator> + 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<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline void + swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs, + map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h new file mode 100644 index 00000000000..8c3bd317bbe --- /dev/null +++ b/libstdc++-v3/include/debug/multimap.h @@ -0,0 +1,314 @@ +// 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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > + class multimap + : public __gnu_norm::multimap<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> > + { + typedef __gnu_norm::multimap<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> 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<typename _Base::iterator, multimap> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + multimap> 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<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<typename _InputIterator> + 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<typename _InputIterator> + 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<iterator, iterator> __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<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + 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<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h new file mode 100644 index 00000000000..083c8fb69a2 --- /dev/null +++ b/libstdc++-v3/include/debug/multiset.h @@ -0,0 +1,320 @@ +// 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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<_Key> > + class multiset + : public __gnu_norm::multiset<_Key, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> > + { + typedef __gnu_norm::multiset<_Key, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<multiset> _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<typename _Base::iterator, multiset> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + multiset> 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<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<typename _InputIterator> + 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<typename _InputIterator> + 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<iterator, iterator> __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<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.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<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator==(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + void + swap(multiset<_Key,_Compare,_Allocator>& __x, + multiset<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h new file mode 100644 index 00000000000..93b17618e35 --- /dev/null +++ b/libstdc++-v3/include/debug/safe_base.h @@ -0,0 +1,201 @@ +// 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 1 + +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 diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h new file mode 100644 index 00000000000..5d7ee27fb3c --- /dev/null +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -0,0 +1,607 @@ +// 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 1 + +#include <bits/stl_pair.h> +#include <debug/debug.h> +#include <debug/formatter.h> +#include <debug/safe_base.h> + +namespace __gnu_debug +{ + /** 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<typename _Iterator, typename _Sequence> + 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 __is_same<const_iterator, _Safe_iterator>::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(__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(__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<typename _MutableIterator> + _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(__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(__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(__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(__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(__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(__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(__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(__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(__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(__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(__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<typename _Other> + 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<const _Sequence*>(_M_sequence); } + + /** Determine the distance between two iterators with some known + * precision. + */ + template<typename _Iterator1, typename _Iterator2> + static pair<difference_type, _Distance_precision> + _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<typename _Iterator1, typename _Iterator2> + static pair<difference_type, _Distance_precision> + _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<typename _Iterator1, typename _Iterator2> + static pair<difference_type, _Distance_precision> + _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<const _Sequence*>(_M_sequence)->begin(); } + + /// Is this iterator equal to the sequence's end() iterator? + bool _M_is_end() const + { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); } + }; + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + 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(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + 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(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + 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(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + 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(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + 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(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__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<typename _IteratorL, typename _IteratorR, typename _Sequence> + 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(__msg_distance_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_distance_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() - __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + 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 <debug/safe_iterator.tcc> +#endif + +#endif diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc new file mode 100644 index 00000000000..0af21b9eb2d --- /dev/null +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -0,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 1 + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + 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<const _Sequence*>(_M_sequence)->begin(); + pair<difference_type, _Distance_precision> __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<const _Sequence*>(_M_sequence)->end(); + pair<difference_type, _Distance_precision> __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<typename _Iterator, typename _Sequence> + template<typename _Other> + 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<difference_type, _Distance_precision> __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<typename _Iterator, typename _Sequence> + 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<iterator*>(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<const_iterator*>(iter); + iter = iter->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + _M_version = 0; + } + } +} // namespace __gnu_debug + +#endif + diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h new file mode 100644 index 00000000000..cb2d8ae3872 --- /dev/null +++ b/libstdc++-v3/include/debug/safe_sequence.h @@ -0,0 +1,179 @@ +// 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 1 + +#include <debug/debug.h> +#include <debug/safe_base.h> + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + 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<typename _Type> + 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<typename _Iterator> + 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<typename _Sequence> + 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<typename _Predicate> + 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<typename _Iterator> + void + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x); + }; + + template<typename _Sequence> + template<typename _Predicate> + 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<iterator*>(__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<const_iterator*>(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + } + + template<typename _Sequence> + template<typename _Iterator> + 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<iterator*>(__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<const_iterator*>(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + } +} // namespace __gnu_debug + +#endif diff --git a/libstdc++-v3/include/debug/set b/libstdc++-v3/include/debug/set new file mode 100644 index 00000000000..a1a69efb4f4 --- /dev/null +++ b/libstdc++-v3/include/debug/set @@ -0,0 +1,38 @@ +// 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_DEBUG_SET +#define _GLIBCXX_DEBUG_SET 1 + +#include <set> +#include <debug/set.h> +#include <debug/multiset.h> + +#endif diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h new file mode 100644 index 00000000000..861077d7557 --- /dev/null +++ b/libstdc++-v3/include/debug/set.h @@ -0,0 +1,325 @@ +// 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 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<_Key> > + class set + : public __gnu_norm::set<_Key,_Compare,_Allocator>, + public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> > + { + typedef __gnu_norm::set<_Key,_Compare,_Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<set> _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<typename _Base::iterator, set> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, set> + 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<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<typename _InputIterator> + 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<iterator, bool> + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair<iterator, bool>(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template <typename _InputIterator> + 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<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.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<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator==(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator!=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + void + swap(set<_Key,_Compare,_Allocator>& __x, + set<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string new file mode 100644 index 00000000000..5be5da6c129 --- /dev/null +++ b/libstdc++-v3/include/debug/string @@ -0,0 +1,1001 @@ +// 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 +#define _GLIBCXX_DEBUG_STRING 1 + +#include <string> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug +{ + template<typename _CharT, typename _Traits, typename _Allocator> + class basic_string + : public std::basic_string<_CharT, _Traits, _Allocator>, + public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits, + _Allocator> > + { + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<basic_string> _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<typename _Base::iterator, basic_string> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + basic_string> const_iterator; + + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<typename _InputIterator> + 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::__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<typename _InputIterator> + 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<typename _InputIterator> + 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 __res = _Base::insert(__p.base(), __c); + this->_M_invalidate_all(); + return iterator(__res, 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<typename _InputIterator> + 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 __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, 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 __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, 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<typename _InputIterator> + 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* __res = _Base::c_str(); + this->_M_invalidate_all(); + return __res; + } + + const _CharT* + data() const + { + const _CharT* __res = _Base::data(); + this->_M_invalidate_all(); + return __res; + } + + 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<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs == __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() == __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs != __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() != __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs < __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() < __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs <= __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() <= __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs >= __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() >= __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs > __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + inline void + swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, + basic_string<_CharT,_Traits,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + operator>>(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); + __str._M_invalidate_all(); + return __res; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + 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>& __res = getline(__is, + __str._M_base(), + __delim); + __str._M_invalidate_all(); + return __res; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base()); + __str._M_invalidate_all(); + return __res; + } +} // namespace __gnu_debug + +#endif diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector new file mode 100644 index 00000000000..19249b6bb81 --- /dev/null +++ b/libstdc++-v3/include/debug/vector @@ -0,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 +#define _GLIBCXX_DEBUG_VECTOR 1 + +#include <vector> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Tp, + typename _Allocator = std::allocator<_Tp> > + class vector + : public __gnu_norm::vector<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > + { + typedef __gnu_norm::vector<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<vector> _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<typename _Base::iterator,vector> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector> + 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<iterator> reverse_iterator; + typedef std::reverse_iterator<const_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<class _InputIterator> + 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<typename _InputIterator> + 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 __res = _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(__res, 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<class _InputIterator> + 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 __res = _Base::erase(__position.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, 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 __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, 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<typename _Tp, typename _Alloc> + inline bool + operator==(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/libstdc++-v3/include/ext/algorithm b/libstdc++-v3/include/ext/algorithm index 9cccec871ba..dfb551535cd 100644 --- a/libstdc++-v3/include/ext/algorithm +++ b/libstdc++-v3/include/ext/algorithm @@ -208,6 +208,8 @@ namespace __gnu_cxx 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); } @@ -226,6 +228,8 @@ namespace __gnu_cxx __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; @@ -241,6 +245,8 @@ namespace __gnu_cxx __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; @@ -262,6 +268,7 @@ namespace __gnu_cxx __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); @@ -297,6 +304,7 @@ namespace __gnu_cxx 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); @@ -378,6 +386,8 @@ namespace __gnu_cxx __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); @@ -399,46 +409,14 @@ namespace __gnu_cxx __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); } - // 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<typename _RandomAccessIterator, typename _Distance> - 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<typename _RandomAccessIterator, typename _Distance, - typename _StrictWeakOrdering> - 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 @@ -452,8 +430,9 @@ namespace __gnu_cxx __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - return __is_heap(__first, __last - __first); + return std::__is_heap(__first, __last - __first); } /** @@ -471,8 +450,9 @@ namespace __gnu_cxx __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - return __is_heap(__first, __comp, __last - __first); + return std::__is_heap(__first, __comp, __last - __first); } // is_sorted, a predicated testing whether a range is sorted in @@ -492,6 +472,7 @@ namespace __gnu_cxx __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; @@ -519,6 +500,7 @@ namespace __gnu_cxx __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; @@ -531,7 +513,6 @@ namespace __gnu_cxx return true; } - } // namespace __gnu_cxx #endif /* _EXT_ALGORITHM */ diff --git a/libstdc++-v3/include/std/std_algorithm.h b/libstdc++-v3/include/std/std_algorithm.h index 1d81201bc7d..40e6246ce7f 100644 --- a/libstdc++-v3/include/std/std_algorithm.h +++ b/libstdc++-v3/include/std/std_algorithm.h @@ -69,7 +69,3 @@ #include <bits/stl_algo.h> #endif /* _GLIBCXX_ALGORITHM */ - -// Local Variables: -// mode:C++ -// End: diff --git a/libstdc++-v3/include/std/std_bitset.h b/libstdc++-v3/include/std/std_bitset.h index ab4ca236bd7..345affc7750 100644 --- a/libstdc++-v3/include/std/std_bitset.h +++ b/libstdc++-v3/include/std/std_bitset.h @@ -50,21 +50,21 @@ #pragma GCC system_header -#include <cstddef> // for size_t -#include <cstring> // for memset -#include <limits> // for numeric_limits +#include <cstddef> // For size_t +#include <cstring> // For memset +#include <limits> // For numeric_limits #include <string> -#include <bits/functexcept.h> // for invalid_argument, out_of_range, +#include <bits/functexcept.h> // For invalid_argument, out_of_range, // overflow_error -#include <ostream> // for ostream (operator<<) -#include <istream> // for istream (operator>>) +#include <ostream> // For ostream (operator<<) +#include <istream> // For istream (operator>>) #define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits<unsigned long>::digits #define _GLIBCXX_BITSET_WORDS(__n) \ ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD) -namespace std +namespace __gnu_norm { /** * @if maint @@ -646,7 +646,7 @@ namespace std ~reference() { } - // for b[i] = __x; + // For b[i] = __x; reference& operator=(bool __x) { @@ -657,7 +657,7 @@ namespace std return *this; } - // for b[i] = b[__j]; + // For b[i] = b[__j]; reference& operator=(const reference& __j) { @@ -668,16 +668,16 @@ namespace std return *this; } - // flips the bit + // Flips the bit bool operator~() const { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } - // for __x = b[i]; + // For __x = b[i]; operator bool() const { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } - // for b[i].flip(); + // For b[i].flip(); reference& flip() { @@ -1207,9 +1207,13 @@ namespace std return __os << __tmp; } //@} -} // namespace std +} // namespace __gnu_norm #undef _GLIBCXX_BITSET_WORDS #undef _GLIBCXX_BITSET_BITS_PER_WORD +#ifdef _GLIBCXX_DEBUG +# include <debug/bitset> +#endif + #endif /* _GLIBCXX_BITSET */ diff --git a/libstdc++-v3/include/std/std_deque.h b/libstdc++-v3/include/std/std_deque.h index 7200220975c..80817f632aa 100644 --- a/libstdc++-v3/include/std/std_deque.h +++ b/libstdc++-v3/include/std/std_deque.h @@ -74,4 +74,8 @@ # include <bits/deque.tcc> #endif +#ifdef _GLIBCXX_DEBUG +# include <debug/deque> +#endif + #endif /* _GLIBCXX_DEQUE */ diff --git a/libstdc++-v3/include/std/std_functional.h b/libstdc++-v3/include/std/std_functional.h index 0330eda8e14..6819f20b6f0 100644 --- a/libstdc++-v3/include/std/std_functional.h +++ b/libstdc++-v3/include/std/std_functional.h @@ -50,13 +50,9 @@ #define _GLIBCXX_FUNCTIONAL 1 #pragma GCC system_header + #include <bits/c++config.h> #include <cstddef> #include <bits/stl_function.h> #endif /* _GLIBCXX_FUNCTIONAL */ - -// Local Variables: -// mode:C++ -// End: - diff --git a/libstdc++-v3/include/std/std_iterator.h b/libstdc++-v3/include/std/std_iterator.h index 3da3e90a414..6e3840b1e7e 100644 --- a/libstdc++-v3/include/std/std_iterator.h +++ b/libstdc++-v3/include/std/std_iterator.h @@ -62,6 +62,7 @@ #define _GLIBCXX_ITERATOR 1 #pragma GCC system_header + #include <bits/c++config.h> #include <cstddef> #include <bits/stl_iterator_base_types.h> @@ -73,7 +74,3 @@ #include <bits/streambuf_iterator.h> #endif /* _GLIBCXX_ITERATOR */ - -// Local Variables: -// mode:C++ -// End: diff --git a/libstdc++-v3/include/std/std_list.h b/libstdc++-v3/include/std/std_list.h index f882bf7e5ee..285a29d8131 100644 --- a/libstdc++-v3/include/std/std_list.h +++ b/libstdc++-v3/include/std/std_list.h @@ -74,5 +74,9 @@ # include <bits/list.tcc> #endif +#ifdef _GLIBCXX_DEBUG +# include <debug/list> +#endif + #endif /* _GLIBCXX_LIST */ diff --git a/libstdc++-v3/include/std/std_map.h b/libstdc++-v3/include/std/std_map.h index f4e0ca1aafc..4a88ae22ea3 100644 --- a/libstdc++-v3/include/std/std_map.h +++ b/libstdc++-v3/include/std/std_map.h @@ -67,8 +67,8 @@ #include <bits/stl_map.h> #include <bits/stl_multimap.h> -#endif /* _GLIBCXX_MAP */ +#ifdef _GLIBCXX_DEBUG +# include <debug/map> +#endif -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_MAP */ diff --git a/libstdc++-v3/include/std/std_memory.h b/libstdc++-v3/include/std/std_memory.h index 3b7cefaefb0..eb2923276f7 100644 --- a/libstdc++-v3/include/std/std_memory.h +++ b/libstdc++-v3/include/std/std_memory.h @@ -57,6 +57,7 @@ #include <bits/stl_iterator_base_types.h> //for iterator_traits #include <bits/stl_uninitialized.h> #include <bits/stl_raw_storage_iter.h> +#include <debug/debug.h> namespace std { @@ -259,7 +260,11 @@ namespace std * what happens when you dereference one of those...) */ element_type& - operator*() const throw() { return *_M_ptr; } + operator*() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return *_M_ptr; + } /** * @brief Smart pointer dereferencing. @@ -268,7 +273,11 @@ namespace std * automatically cause to be dereferenced. */ element_type* - operator->() const throw() { return _M_ptr; } + operator->() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return _M_ptr; + } /** * @brief Bypassing the smart pointer. diff --git a/libstdc++-v3/include/std/std_numeric.h b/libstdc++-v3/include/std/std_numeric.h index f46150872e9..88661e9f5a4 100644 --- a/libstdc++-v3/include/std/std_numeric.h +++ b/libstdc++-v3/include/std/std_numeric.h @@ -62,6 +62,7 @@ #define _GLIBCXX_NUMERIC 1 #pragma GCC system_header + #include <bits/c++config.h> #include <cstddef> #include <iterator> @@ -69,7 +70,3 @@ #include <bits/stl_numeric.h> #endif /* _GLIBCXX_NUMERIC */ - -// Local Variables: -// mode:C++ -// End: diff --git a/libstdc++-v3/include/std/std_queue.h b/libstdc++-v3/include/std/std_queue.h index e2e0b845e45..9a6523bef87 100644 --- a/libstdc++-v3/include/std/std_queue.h +++ b/libstdc++-v3/include/std/std_queue.h @@ -62,21 +62,17 @@ #define _GLIBCXX_QUEUE 1 #pragma GCC system_header + #include <bits/c++config.h> #include <bits/functexcept.h> #include <bits/stl_algobase.h> #include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> -#include <bits/stl_vector.h> #include <bits/stl_heap.h> -#include <bits/stl_deque.h> #include <bits/stl_function.h> +#include <deque> +#include <vector> #include <bits/stl_queue.h> -#ifndef _GLIBCXX_EXPORT_TEMPLATE -# include <bits/deque.tcc> -# include <bits/vector.tcc> -#endif - #endif /* _GLIBCXX_QUEUE */ diff --git a/libstdc++-v3/include/std/std_set.h b/libstdc++-v3/include/std/std_set.h index 8dbed180ace..7ef8c9fef3b 100644 --- a/libstdc++-v3/include/std/std_set.h +++ b/libstdc++-v3/include/std/std_set.h @@ -67,8 +67,8 @@ #include <bits/stl_set.h> #include <bits/stl_multiset.h> -#endif /* _GLIBCXX_SET */ +#ifdef _GLIBCXX_DEBUG +# include <debug/set> +#endif -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_SET */ diff --git a/libstdc++-v3/include/std/std_stack.h b/libstdc++-v3/include/std/std_stack.h index 80178528516..70f045684e0 100644 --- a/libstdc++-v3/include/std/std_stack.h +++ b/libstdc++-v3/include/std/std_stack.h @@ -67,11 +67,7 @@ #include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> -#include <bits/stl_deque.h> +#include <deque> #include <bits/stl_stack.h> -#ifndef _GLIBCXX_EXPORT_TEMPLATE -# include <bits/deque.tcc> -#endif - #endif /* _GLIBCXX_STACK */ diff --git a/libstdc++-v3/include/std/std_utility.h b/libstdc++-v3/include/std/std_utility.h index f5793425b22..fe93090f939 100644 --- a/libstdc++-v3/include/std/std_utility.h +++ b/libstdc++-v3/include/std/std_utility.h @@ -62,12 +62,9 @@ #define _GLIBCXX_UTILITY 1 #pragma GCC system_header + #include <bits/c++config.h> #include <bits/stl_relops.h> #include <bits/stl_pair.h> #endif /* _GLIBCXX_UTILITY */ - -// Local Variables: -// mode:C++ -// End: diff --git a/libstdc++-v3/include/std/std_valarray.h b/libstdc++-v3/include/std/std_valarray.h index 09367488c8b..7dac89dadb0 100644 --- a/libstdc++-v3/include/std/std_valarray.h +++ b/libstdc++-v3/include/std/std_valarray.h @@ -46,6 +46,7 @@ #include <cstdlib> #include <numeric> #include <algorithm> +#include <debug/debug.h> namespace std { @@ -221,12 +222,18 @@ namespace std template<typename _Tp> inline const _Tp& valarray<_Tp>::operator[](size_t __i) const - { return _M_data[__i]; } + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } template<typename _Tp> inline _Tp& valarray<_Tp>::operator[](size_t __i) - { return _M_data[__i]; } + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } } // std:: @@ -260,7 +267,10 @@ namespace std 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); } + { + _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0); + std::__valarray_copy_construct(__p, __p + __n, _M_data); + } template<typename _Tp> inline @@ -324,6 +334,7 @@ namespace std 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; } @@ -340,6 +351,7 @@ namespace std 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; @@ -349,6 +361,7 @@ namespace std 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<size_t>(__ga._M_index), _Array<_Tp>(_M_data), _M_size); return *this; @@ -358,6 +371,7 @@ namespace std 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; @@ -367,6 +381,7 @@ namespace std 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; @@ -376,6 +391,7 @@ namespace std 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; } @@ -460,6 +476,7 @@ namespace std inline _Tp valarray<_Tp>::sum() const { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); return std::__valarray_sum(_M_data, _M_data + _M_size); } @@ -540,6 +557,7 @@ namespace std inline _Tp valarray<_Tp>::min() const { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); return *std::min_element (_M_data, _M_data+_M_size); } @@ -547,6 +565,7 @@ namespace std inline _Tp valarray<_Tp>::max() const { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); return *std::max_element (_M_data, _M_data+_M_size); } @@ -596,6 +615,7 @@ namespace std 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; \ @@ -643,6 +663,7 @@ _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) 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)); \ @@ -690,7 +711,3 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal) } // namespace std #endif /* _GLIBCXX_VALARRAY */ - -// Local Variables: -// mode:c++ -// End: diff --git a/libstdc++-v3/include/std/std_vector.h b/libstdc++-v3/include/std/std_vector.h index 02cf1229148..16e50a99ec8 100644 --- a/libstdc++-v3/include/std/std_vector.h +++ b/libstdc++-v3/include/std/std_vector.h @@ -75,5 +75,9 @@ # include <bits/vector.tcc> #endif +#ifdef _GLIBCXX_DEBUG +# include <debug/vector> +#endif + #endif /* _GLIBCXX_VECTOR */ |