aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/bits')
-rw-r--r--libstdc++-v3/include/bits/basic_ios.h21
-rw-r--r--libstdc++-v3/include/bits/basic_ios.tcc72
-rw-r--r--libstdc++-v3/include/bits/basic_string.h55
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc35
-rw-r--r--libstdc++-v3/include/bits/c++config10
-rw-r--r--libstdc++-v3/include/bits/char_traits.h62
-rw-r--r--libstdc++-v3/include/bits/codecvt.h43
-rw-r--r--libstdc++-v3/include/bits/fpos.h2
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc291
-rw-r--r--libstdc++-v3/include/bits/ios_base.h33
-rw-r--r--libstdc++-v3/include/bits/istream.tcc357
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h192
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc689
-rw-r--r--libstdc++-v3/include/bits/localefwd.h108
-rw-r--r--libstdc++-v3/include/bits/ostream.tcc73
-rw-r--r--libstdc++-v3/include/bits/slice_array.h3
-rw-r--r--libstdc++-v3/include/bits/sstream.tcc90
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h677
-rw-r--r--libstdc++-v3/include/bits/stl_alloc.h1411
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h86
-rw-r--r--libstdc++-v3/include/bits/stl_construct.h29
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h213
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h75
-rw-r--r--libstdc++-v3/include/bits/stl_iterator_base_types.h8
-rw-r--r--libstdc++-v3/include/bits/stl_list.h16
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h2
-rw-r--r--libstdc++-v3/include/bits/stl_relops.h4
-rw-r--r--libstdc++-v3/include/bits/stl_tempbuf.h4
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h2480
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h2
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h51
-rw-r--r--libstdc++-v3/include/bits/streambuf.tcc47
-rw-r--r--libstdc++-v3/include/bits/streambuf_iterator.h184
-rw-r--r--libstdc++-v3/include/bits/stringfwd.h18
-rw-r--r--libstdc++-v3/include/bits/type_traits.h4
35 files changed, 4301 insertions, 3146 deletions
diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h
index f91719582f1..13ad0f82e99 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -64,24 +64,18 @@ namespace std
// Data members:
protected:
basic_ostream<_CharT, _Traits>* _M_tie;
- char_type _M_fill;
- iostate _M_exception;
-
+ mutable char_type _M_fill;
+ mutable bool _M_fill_init;
basic_streambuf<_CharT, _Traits>* _M_streambuf;
- iostate _M_streambuf_state;
// Cached use_facet<ctype>, which is based on the current locale info.
- const __ctype_type* _M_ios_fctype;
+ const __ctype_type* _M_fctype;
// From ostream.
const __numput_type* _M_fnumput;
// From istream.
const __numget_type* _M_fnumget;
public:
- const __ctype_type*
- _M_get_fctype_ios(void)
- { return _M_ios_fctype; }
-
operator void*() const
{ return this->fail() ? 0 : const_cast<basic_ios*>(this); }
@@ -160,7 +154,14 @@ namespace std
char_type
fill() const
- { return _M_fill; }
+ {
+ if (!_M_fill_init)
+ {
+ _M_fill = this->widen(' ');
+ _M_fill_init = true;
+ }
+ return _M_fill;
+ }
char_type
fill(char_type __ch)
diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc
index 4db4a82d5ac..7ee8015e29f 100644
--- a/libstdc++-v3/include/bits/basic_ios.tcc
+++ b/libstdc++-v3/include/bits/basic_ios.tcc
@@ -64,31 +64,31 @@ namespace std
// associated with imbue()
// Alloc any new word array first, so if it fails we have "rollback".
- _Words* __words = (__rhs._M_word_limit <= _S_local_words) ?
- _M_word_array : new _Words[__rhs._M_word_limit];
-
- // XXX This is the only reason _Callback_list was defined
- // inline. The suspicion is that this increased compilation
- // times dramatically for functions that use this member
- // function (inserters_extractors, ios_manip_fmtflags). FIX ME,
- // clean this stuff up. Callbacks are broken right now, anyway.
+ _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ?
+ _M_local_word : new _Words[__rhs._M_word_size];
// Bump refs before doing callbacks, for safety.
_Callback_list* __cb = __rhs._M_callbacks;
if (__cb)
__cb->_M_add_reference();
_M_call_callbacks(erase_event);
- if (_M_words != _M_word_array)
- delete [] _M_words;
+ if (_M_word != _M_local_word)
+ {
+ delete [] _M_word;
+ _M_word = 0;
+ }
_M_dispose_callbacks();
_M_callbacks = __cb; // NB: Don't want any added during above.
- for (int __i = 0; __i < __rhs._M_word_limit; ++__i)
- __words[__i] = __rhs._M_words[__i];
- if (_M_words != _M_word_array)
- delete [] _M_words;
- _M_words = __words;
- _M_word_limit = __rhs._M_word_limit;
+ for (int __i = 0; __i < __rhs._M_word_size; ++__i)
+ __words[__i] = __rhs._M_word[__i];
+ if (_M_word != _M_local_word)
+ {
+ delete [] _M_word;
+ _M_word = 0;
+ }
+ _M_word = __words;
+ _M_word_size = __rhs._M_word_size;
this->flags(__rhs.flags());
this->width(__rhs.width());
@@ -107,8 +107,8 @@ namespace std
basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const
{
char __ret = __dfault;
- if (_M_check_facet(_M_ios_fctype))
- __ret = _M_ios_fctype->narrow(__c, __dfault);
+ if (_M_check_facet(_M_fctype))
+ __ret = _M_fctype->narrow(__c, __dfault);
return __ret;
}
@@ -117,8 +117,8 @@ namespace std
basic_ios<_CharT, _Traits>::widen(char __c) const
{
char_type __ret = char_type();
- if (_M_check_facet(_M_ios_fctype))
- __ret = _M_ios_fctype->widen(__c);
+ if (_M_check_facet(_M_fctype))
+ __ret = _M_fctype->widen(__c);
return __ret;
}
@@ -144,17 +144,20 @@ namespace std
_M_cache_facets(_M_ios_locale);
_M_tie = 0;
- // NB: The 27.4.4.1 Postconditions Table only specifies
- // requirements after basic_ios::init() has been called. As part
- // of this, fill() must return widen(' '), which needs an imbued
- // ctype facet of char_type to return without throwing an
- // exception. This is not a required facet, so streams with
- // char_type != [char, wchar_t] will not have it by
- // default. However, because fill()'s signature is const, this
- // data member cannot be lazily initialized. Thus, thoughts of
- // using a non-const helper function in ostream inserters is
- // really besides the point.
- _M_fill = this->widen(' ');
+ // NB: The 27.4.4.1 Postconditions Table specifies requirements
+ // after basic_ios::init() has been called. As part of this,
+ // fill() must return widen(' ') any time after init() has been
+ // called, which needs an imbued ctype facet of char_type to
+ // return without throwing an exception. Unfortunately,
+ // ctype<char_type> is not necessarily a required facet, so
+ // streams with char_type != [char, wchar_t] will not have it by
+ // default. Because of this, the correct value for _M_fill is
+ // constructed on the first call of fill(). That way,
+ // unformatted input and output with non-required basic_ios
+ // instantiations is possible even without imbuing the expected
+ // ctype<char_type> facet.
+ _M_fill = _CharT();
+ _M_fill_init = false;
_M_exception = goodbit;
_M_streambuf = __sb;
@@ -166,9 +169,9 @@ namespace std
basic_ios<_CharT, _Traits>::_M_cache_facets(const locale& __loc)
{
if (has_facet<__ctype_type>(__loc))
- _M_ios_fctype = &use_facet<__ctype_type>(__loc);
+ _M_fctype = &use_facet<__ctype_type>(__loc);
else
- _M_ios_fctype = 0;
+ _M_fctype = 0;
// Should be filled in by ostream and istream, respectively.
if (has_facet<__numput_type>(__loc))
_M_fnumput = &use_facet<__numput_type>(__loc);
@@ -184,7 +187,10 @@ namespace std
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
extern template class basic_ios<char>;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
extern template class basic_ios<wchar_t>;
+#endif
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 913484cbb7f..a9c02ce3708 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -99,8 +99,9 @@ namespace std
typedef typename _Alloc::const_reference const_reference;
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
- typedef __normal_iterator<pointer, basic_string> iterator;
- typedef __normal_iterator<const_pointer, basic_string> const_iterator;
+ typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
+ typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
+ const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
@@ -162,7 +163,7 @@ namespace std
_CharT*
_M_refdata() throw()
- { return reinterpret_cast<_CharT*> (this + 1); }
+ { return reinterpret_cast<_CharT*>(this + 1); }
_CharT&
operator[](size_t __s) throw()
@@ -170,8 +171,10 @@ namespace std
_CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
- { return (!_M_is_leaked() && __alloc1 == __alloc2) ?
- _M_refcopy() : _M_clone(__alloc1); }
+ {
+ return (!_M_is_leaked() && __alloc1 == __alloc2)
+ ? _M_refcopy() : _M_clone(__alloc1);
+ }
// Create & Destroy
static _Rep*
@@ -639,16 +642,19 @@ namespace std
const size_type __size = this->size();
if (__pos > __size)
__throw_out_of_range("basic_string::replace");
- if (__size - __n1 > this->max_size() - __n2)
- __throw_length_error("basic_string::replace");
const bool __testn1 = __n1 < __size - __pos;
const size_type __foldn1 = __testn1 ? __n1 : __size - __pos;
+ if (__size - __foldn1 > this->max_size() - __n2)
+ __throw_length_error("basic_string::replace");
if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
|| less<const _CharT*>()(_M_data() + __size, __s))
return _M_replace_safe(_M_ibegin() + __pos,
_M_ibegin() + __pos + __foldn1, __s, __s + __n2);
- else return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
- __s, __s + __n2);
+ // Todo: optimized in-place replace.
+ else return
+ _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __foldn1,
+ __s, __s + __n2,
+ typename iterator_traits<const _CharT*>::iterator_category());
}
basic_string&
@@ -682,6 +688,30 @@ namespace std
{ return _M_replace(__i1, __i2, __k1, __k2,
typename iterator_traits<_InputIterator>::iterator_category()); }
+ // Specializations for the common case of pointer and iterator:
+ // useful to avoid the overhead of temporary buffering in _M_replace.
+ basic_string&
+ replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
+ { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1, __k2 - __k1); }
+
+ basic_string&
+ replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
+ { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1, __k2 - __k1); }
+
+ basic_string&
+ replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
+ { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1.base(), __k2 - __k1);
+ }
+
+ basic_string&
+ replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
+ { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1.base(), __k2 - __k1);
+ }
+
private:
template<class _InputIterator>
basic_string&
@@ -731,7 +761,7 @@ namespace std
// string::iterator, _CharT*, etc.
template<class _FwdIter>
static _CharT*
- _S_construct(_FwdIter __end, _FwdIter __beg, const _Alloc& __a,
+ _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a,
forward_iterator_tag);
static _CharT*
@@ -879,15 +909,14 @@ namespace std
int
compare(const _CharT* __s) const;
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-// 5. String::compare specification questionable
+ // _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // 5. String::compare specification questionable
int
compare(size_type __pos, size_type __n1, const _CharT* __s) const;
int
compare(size_type __pos, size_type __n1, const _CharT* __s,
size_type __n2) const;
-#endif
};
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index dce9b38fcb4..4a22d896792 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -142,6 +142,10 @@ namespace std
if (__beg == __end && __a == _Alloc())
return _S_empty_rep()._M_refcopy();
+ // NB: Not required, but considered best practice.
+ if (__builtin_expect(__beg == _InIter(), 0))
+ __throw_logic_error("attempt to create string with null pointer");
+
// Check for out_of_range and length_error exceptions.
_Rep* __r = _Rep::_S_create(__dnew, __a);
try
@@ -219,7 +223,8 @@ namespace std
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _CharT* __s, const _Alloc& __a)
- : _M_dataplus(_S_construct(__s, __s + traits_type::length(__s), __a), __a)
+ : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
+ __s + npos, __a), __a)
{ }
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -438,7 +443,7 @@ namespace std
void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
_Rep *__p = new (__place) _Rep;
__p->_M_capacity = __capacity;
- __p->_M_set_sharable(); // one reference
+ __p->_M_set_sharable(); // One reference.
__p->_M_length = 0;
return __p;
}
@@ -492,14 +497,10 @@ namespace std
this->erase(__n);
// else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
}
-
- // This is the general replace helper, which gets instantiated both
- // for input-iterators and forward-iterators. It buffers internally and
- // then calls _M_replace_safe. For input-iterators this is almost the
- // best we can do, but for forward-iterators many optimizations could be
- // conceived: f.i., when source and destination ranges do not overlap
- // buffering is not really needed. In order to easily implement them, it
- // could become useful to add an _M_replace(forward_iterator_tag)
+
+ // This is the general replace helper, which currently gets instantiated both
+ // for input iterators and reverse iterators. It buffers internally and then
+ // calls _M_replace_safe.
template<typename _CharT, typename _Traits, typename _Alloc>
template<typename _InputIter>
basic_string<_CharT, _Traits, _Alloc>&
@@ -513,10 +514,8 @@ namespace std
}
// This is a special replace helper, which does not buffer internally
- // and can be used in the "safe" situations involving forward-iterators,
+ // and can be used in "safe" situations involving forward iterators,
// i.e., when source and destination ranges are known to not overlap.
- // Presently, is called by _M_replace, by the various append and by
- // the assigns.
template<typename _CharT, typename _Traits, typename _Alloc>
template<typename _ForwardIter>
basic_string<_CharT, _Traits, _Alloc>&
@@ -885,9 +884,11 @@ namespace std
compare(const _CharT* __s) const
{
size_type __size = this->size();
- int __r = traits_type::compare(_M_data(), __s, __size);
+ size_type __osize = traits_type::length(__s);
+ size_type __len = min(__size, __osize);
+ int __r = traits_type::compare(_M_data(), __s, __len);
if (!__r)
- __r = __size - traits_type::length(__s);
+ __r = __size - __osize;
return __r;
}
@@ -945,7 +946,7 @@ namespace std
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
extern template class basic_string<char>;
- extern template
+ extern template
basic_istream<char>&
operator>>(basic_istream<char>&, string&);
extern template
@@ -958,6 +959,7 @@ namespace std
basic_istream<char>&
getline(basic_istream<char>&, string&);
+#ifdef _GLIBCPP_USE_WCHAR_T
extern template class basic_string<wchar_t>;
extern template
basic_istream<wchar_t>&
@@ -971,6 +973,7 @@ namespace std
extern template
basic_istream<wchar_t>&
getline(basic_istream<wchar_t>&, wstring&);
+#endif
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 4e88d9f2e3f..cda776c22da 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -34,7 +34,7 @@
#include <bits/os_defines.h>
// The current version of the C++ library in compressed ISO date format.
-#define __GLIBCPP__ 20020225
+#define __GLIBCPP__ 20030205
// This is necessary until GCC supports separate template
// compilation.
@@ -55,6 +55,9 @@
// Use corrected code from the committee library group's issues list.
#define _GLIBCPP_RESOLVE_LIB_DEFECTS 1
+// Hopefully temporary workaround to autoconf/m4 issue with quoting '@'.
+#define _GLIBCPP_AT_AT "@@"
+
// In those parts of the standard C++ library that use a mutex instead
// of a spin-lock, we now unconditionally use GCC's gthr.h mutex
// abstraction layer. All support to directly map to various
@@ -69,7 +72,10 @@
// that threads are properly configured on your platform before
// assigning blame to the STL container-memory allocator. After doing
// so, please report any possible issues to libstdc++@gcc.gnu.org .
-// Do not blindly #define __USE_MALLOC here or on the command line.
+// Do not define __USE_MALLOC on the command line. Enforce it here:
+#ifdef __USE_MALLOC
+#error __USE_MALLOC should never be defined. Read the release notes.
+#endif
// The remainder of the prewritten config is mostly automatic; all the
// user hooks are listed above.
diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h
index 7d14838ab26..41f943d9a59 100644
--- a/libstdc++-v3/include/bits/char_traits.h
+++ b/libstdc++-v3/include/bits/char_traits.h
@@ -1,6 +1,7 @@
// Character Traits for use by standard string and iostream -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// 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
@@ -53,82 +54,53 @@ namespace std
struct char_traits
{
typedef _CharT char_type;
- // Unsigned as wint_t in unsigned.
+ // Unsigned as wint_t is unsigned.
typedef unsigned long int_type;
typedef streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
static void
- assign(char_type& __c1, const char_type& __c2)
- { __c1 = __c2; }
+ assign(char_type& __c1, const char_type& __c2);
static bool
- eq(const char_type& __c1, const char_type& __c2)
- { return __c1 == __c2; }
+ eq(const char_type& __c1, const char_type& __c2);
static bool
- lt(const char_type& __c1, const char_type& __c2)
- { return __c1 < __c2; }
+ lt(const char_type& __c1, const char_type& __c2);
static int
- compare(const char_type* __s1, const char_type* __s2, size_t __n)
- {
- for (size_t __i = 0; __i < __n; ++__i)
- if (!eq(__s1[__i], __s2[__i]))
- return lt(__s1[__i], __s2[__i]) ? -1 : 1;
- return 0;
- }
+ compare(const char_type* __s1, const char_type* __s2, size_t __n);
static size_t
- length(const char_type* __s)
- {
- const char_type* __p = __s;
- while (*__p) ++__p;
- return (__p - __s);
- }
+ length(const char_type* __s);
static const char_type*
- find(const char_type* __s, size_t __n, const char_type& __a)
- {
- for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p)
- if (*__p == __a) return __p;
- return 0;
- }
+ find(const char_type* __s, size_t __n, const char_type& __a);
static char_type*
- move(char_type* __s1, const char_type* __s2, size_t __n)
- { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); }
+ move(char_type* __s1, const char_type* __s2, size_t __n);
static char_type*
- copy(char_type* __s1, const char_type* __s2, size_t __n)
- { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); }
+ copy(char_type* __s1, const char_type* __s2, size_t __n);
static char_type*
- assign(char_type* __s, size_t __n, char_type __a)
- {
- for (char_type* __p = __s; __p < __s + __n; ++__p)
- assign(*__p, __a);
- return __s;
- }
+ assign(char_type* __s, size_t __n, char_type __a);
static char_type
- to_char_type(const int_type& __c)
- { return char_type(__c); }
+ to_char_type(const int_type& __c);
static int_type
- to_int_type(const char_type& __c) { return int_type(__c); }
+ to_int_type(const char_type& __c);
static bool
- eq_int_type(const int_type& __c1, const int_type& __c2)
- { return __c1 == __c2; }
+ eq_int_type(const int_type& __c1, const int_type& __c2);
static int_type
- eof() { return static_cast<int_type>(-1); }
+ eof();
static int_type
- not_eof(const int_type& __c)
- { return eq_int_type(__c, eof()) ? int_type(0) : __c; }
+ not_eof(const int_type& __c);
};
diff --git a/libstdc++-v3/include/bits/codecvt.h b/libstdc++-v3/include/bits/codecvt.h
index 506752f3432..3666e987d6d 100644
--- a/libstdc++-v3/include/bits/codecvt.h
+++ b/libstdc++-v3/include/bits/codecvt.h
@@ -1,6 +1,6 @@
// Locale support (codecvt) -*- C++ -*-
-// Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+// Copyright (C) 2000, 2001, 2002 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
@@ -66,10 +66,10 @@
{
public:
// Types:
- typedef codecvt_base::result result;
- typedef _InternT intern_type;
- typedef _ExternT extern_type;
- typedef _StateT state_type;
+ typedef codecvt_base::result result;
+ typedef _InternT intern_type;
+ typedef _ExternT extern_type;
+ typedef _StateT state_type;
// 22.2.1.5.1 codecvt members
result
@@ -159,17 +159,17 @@
{
public:
// Types:
- typedef codecvt_base::result result;
- typedef _InternT intern_type;
- typedef _ExternT extern_type;
- typedef _StateT state_type;
+ typedef codecvt_base::result result;
+ typedef _InternT intern_type;
+ typedef _ExternT extern_type;
+ typedef _StateT state_type;
- // Data Members:
- static locale::id id;
+ public:
+ static locale::id id;
explicit
codecvt(size_t __refs = 0)
- : __codecvt_abstract_base<_InternT,_ExternT,_StateT> (__refs) { }
+ : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { }
protected:
virtual
@@ -215,11 +215,11 @@
{
public:
// Types:
- typedef char intern_type;
- typedef char extern_type;
- typedef mbstate_t state_type;
+ typedef char intern_type;
+ typedef char extern_type;
+ typedef mbstate_t state_type;
- // Data Members:
+ public:
static locale::id id;
explicit
@@ -267,12 +267,12 @@
{
public:
// Types:
- typedef wchar_t intern_type;
- typedef char extern_type;
- typedef mbstate_t state_type;
+ typedef wchar_t intern_type;
+ typedef char extern_type;
+ typedef mbstate_t state_type;
- // Data Members:
- static locale::id id;
+ public:
+ static locale::id id;
explicit
codecvt(size_t __refs = 0);
@@ -322,6 +322,7 @@
explicit
codecvt_byname(const char*, size_t __refs = 0)
: codecvt<_InternT, _ExternT, _StateT>(__refs) { }
+
protected:
virtual
~codecvt_byname() { }
diff --git a/libstdc++-v3/include/bits/fpos.h b/libstdc++-v3/include/bits/fpos.h
index 3cb3e4b51a2..279e0ab16ba 100644
--- a/libstdc++-v3/include/bits/fpos.h
+++ b/libstdc++-v3/include/bits/fpos.h
@@ -105,7 +105,7 @@ namespace std
bool
operator!=(const fpos& __pos) const
{ return _M_off != __pos._M_off; }
-
+
streamoff
_M_position() const { return _M_off; }
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 0d0882619e8..0b3bec1c263 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -1,6 +1,6 @@
// File based streams -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -42,24 +42,6 @@ namespace std
template<typename _CharT, typename _Traits>
void
basic_filebuf<_CharT, _Traits>::
- _M_allocate_file()
- {
- if (!_M_file)
- {
- _M_buf_unified = true; // Tie input to output for basic_filebuf.
- try
- { _M_file = new __file_type(&_M_lock); }
- catch(...)
- {
- delete _M_file;
- __throw_exception_again;
- }
- }
- }
-
- template<typename _CharT, typename _Traits>
- void
- basic_filebuf<_CharT, _Traits>::
_M_allocate_internal_buffer()
{
if (!_M_buf && _M_buf_size_opt)
@@ -67,12 +49,7 @@ namespace std
_M_buf_size = _M_buf_size_opt;
// Allocate internal buffer.
- try { _M_buf = new char_type[_M_buf_size]; }
- catch(...)
- {
- delete [] _M_buf;
- __throw_exception_again;
- }
+ _M_buf = new char_type[_M_buf_size];
_M_buf_allocated = true;
}
}
@@ -93,59 +70,12 @@ namespace std
}
}
- template<typename _CharT, typename _Traits>
- void
- basic_filebuf<_CharT, _Traits>::
- _M_allocate_pback_buffer()
- {
- if (!_M_pback && _M_pback_size)
- {
- // Allocate pback buffer.
- try
- { _M_pback = new char_type[_M_pback_size]; }
- catch(...)
- {
- delete [] _M_pback;
- __throw_exception_again;
- }
- }
- }
-
template<typename _CharT, typename _Traits>
basic_filebuf<_CharT, _Traits>::
- basic_filebuf()
- : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()),
- _M_state_beg(__state_type()), _M_buf_allocated(false),
- _M_last_overflowed(false)
- { }
-
- template<typename _CharT, typename _Traits>
- basic_filebuf<_CharT, _Traits>::
- basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, int_type __s)
- : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()),
- _M_state_beg(__state_type()), _M_buf_allocated(false),
- _M_last_overflowed(false)
- {
- _M_allocate_file();
- _M_file->sys_open(__f, __mode);
- if (this->is_open())
- {
- _M_mode = __mode;
- if (__s)
- {
- _M_buf_size_opt = __s;
- _M_allocate_internal_buffer();
- _M_set_indeterminate();
- }
- _M_allocate_pback_buffer();
- }
- }
-
- template<typename _CharT, typename _Traits>
- int
- basic_filebuf<_CharT, _Traits>::
- fd()
- { return _M_file->fd(); }
+ basic_filebuf() : __streambuf_type(), _M_file(&_M_lock),
+ _M_state_cur(__state_type()), _M_state_beg(__state_type()),
+ _M_buf_allocated(false), _M_last_overflowed(false)
+ { _M_buf_unified = true; }
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
@@ -155,17 +85,14 @@ namespace std
__filebuf_type *__ret = NULL;
if (!this->is_open())
{
- _M_allocate_file();
- _M_file->open(__s, __mode);
+ _M_file.open(__s, __mode);
if (this->is_open())
{
_M_allocate_internal_buffer();
- _M_allocate_pback_buffer();
_M_mode = __mode;
-
- // For time being, set both (in/out) sets of pointers.
_M_set_indeterminate();
- if (__mode & ios_base::ate
+
+ if ((__mode & ios_base::ate)
&& this->seekoff(0, ios_base::end, __mode) < 0)
this->close();
__ret = this;
@@ -184,19 +111,14 @@ namespace std
{
const int_type __eof = traits_type::eof();
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
- if (__testput && _M_really_overflow(__eof) == __eof)
+ if (__testput
+ && traits_type::eq_int_type(_M_really_overflow(__eof), __eof))
return __ret;
// NB: Do this here so that re-opened filebufs will be cool...
_M_mode = ios_base::openmode(0);
_M_destroy_internal_buffer();
-
_M_pback_destroy();
- if (_M_pback)
- {
- delete [] _M_pback;
- _M_pback = NULL;
- }
#if 0
// XXX not done
@@ -206,16 +128,11 @@ namespace std
_M_really_overflow(__eof);
}
#endif
- __ret = this;
- }
- // Can actually allocate this file as part of an open and never
- // have it be opened.....
- if (_M_file)
- {
- delete _M_file;
- _M_file = NULL;
+ if (_M_file.close())
+ __ret = this;
}
+
_M_last_overflowed = false;
return __ret;
}
@@ -229,106 +146,7 @@ namespace std
bool __testin = _M_mode & ios_base::in;
if (__testin && this->is_open())
- {
- if (_M_in_cur < _M_in_end)
- __ret = _M_in_end - _M_in_cur;
- else
- __ret = 0;
- }
- _M_last_overflowed = false;
- return __ret;
- }
-
- template<typename _CharT, typename _Traits>
- typename basic_filebuf<_CharT, _Traits>::int_type
- basic_filebuf<_CharT, _Traits>::
- underflow()
- {
- int_type __ret = traits_type::eof();
- bool __testin = _M_mode & ios_base::in;
- bool __testout = _M_mode & ios_base::out;
-
- if (__testin)
- {
- // Check for pback madness, and if so swich back to the
- // normal buffers and jet outta here before expensive
- // fileops happen...
- if (_M_pback_init)
- {
- _M_pback_destroy();
- if (_M_in_cur < _M_in_end)
- return traits_type::to_int_type(*_M_in_cur);
- }
-
- // Sync internal and external buffers.
- // NB: __testget -> __testput as _M_buf_unified here.
- bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
- bool __testinit = _M_is_indeterminate();
- if (__testget)
- {
- if (__testout)
- _M_really_overflow();
-#if _GLIBCPP_AVOID_FSEEK
- else if ((_M_in_cur - _M_in_beg) == 1)
- _M_file->sys_getc();
-#endif
- else
- _M_file->seekoff(_M_in_cur - _M_in_beg,
- ios_base::cur, ios_base::in);
- }
-
- if (__testinit || __testget)
- {
- const locale __loc = this->getloc();
- const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
-
- streamsize __elen = 0;
- streamsize __ilen = 0;
- if (__cvt.always_noconv())
- {
- __elen = _M_file->xsgetn(reinterpret_cast<char*>(_M_in_beg),
- _M_buf_size);
- __ilen = __elen;
- }
- else
- {
- char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size));
- __elen = _M_file->xsgetn(__buf, _M_buf_size);
-
- const char* __eend;
- char_type* __iend;
- __res_type __r = __cvt.in(_M_state_cur, __buf,
- __buf + __elen, __eend, _M_in_beg,
- _M_in_beg + _M_buf_size, __iend);
- if (__r == codecvt_base::ok)
- __ilen = __iend - _M_in_beg;
- else
- {
- // Unwind.
- __ilen = 0;
- _M_file->seekoff(-__elen, ios_base::cur, ios_base::in);
- }
- }
-
- if (0 < __ilen)
- {
- _M_set_determinate(__ilen);
- if (__testout)
- _M_out_cur = _M_in_cur;
- __ret = traits_type::to_int_type(*_M_in_cur);
-#if _GLIBCPP_AVOID_FSEEK
- if (__elen == 1)
- _M_file->sys_ungetc(*_M_in_cur);
- else
- {
-#endif
- _M_file->seekoff(-__elen, ios_base::cur, ios_base::in);
-#if _GLIBCPP_AVOID_FSEEK
- }
-#endif
- }
- }
- }
+ __ret = _M_in_end - _M_in_cur;
_M_last_overflowed = false;
return __ret;
}
@@ -437,7 +255,7 @@ namespace std
if (__cvt.always_noconv() && __ilen)
{
- __elen += _M_file->xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
+ __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
__plen += __ilen;
}
else
@@ -461,7 +279,7 @@ namespace std
if (__blen)
{
- __elen += _M_file->xsputn(__buf, __blen);
+ __elen += _M_file.xsputn(__buf, __blen);
__plen += __blen;
}
@@ -478,7 +296,7 @@ namespace std
__rlen = 0;
if (__rlen)
{
- __elen += _M_file->xsputn(__buf, __rlen);
+ __elen += _M_file.xsputn(__buf, __rlen);
__plen += __rlen;
}
}
@@ -492,7 +310,7 @@ namespace std
{
int_type __ret = traits_type::eof();
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
- bool __testunbuffered = _M_file && !_M_buf_size;
+ bool __testunbuffered = _M_file.is_open() && !_M_buf_size_opt;
if (__testput || __testunbuffered)
{
@@ -500,6 +318,15 @@ namespace std
streamsize __elen = 0;
streamsize __plen = 0;
+ // Need to restore current position. The position of the external
+ // byte sequence (_M_file) corresponds to _M_filepos, and we need
+ // to move it to _M_out_beg for the write.
+ if (_M_filepos && _M_filepos != _M_out_beg)
+ {
+ off_type __off = _M_out_beg - _M_filepos;
+ _M_file.seekoff(__off, ios_base::cur);
+ }
+
// Convert internal buffer to external representation, output.
// NB: In the unbuffered case, no internal buffer exists.
if (!__testunbuffered)
@@ -507,16 +334,20 @@ namespace std
__elen, __plen);
// Convert pending sequence to external representation, output.
+ // If eof, then just attempt sync.
if (!traits_type::eq_int_type(__c, traits_type::eof()))
{
char_type __pending = traits_type::to_char_type(__c);
_M_convert_to_external(&__pending, 1, __elen, __plen);
- }
- // Last, sync internal and external buffers.
- // NB: Need this so that external byte sequence reflects
- // internal buffer plus pending sequence.
- if (__elen == __plen && !_M_file->sync())
+ // User code must flush when switching modes (thus don't sync).
+ if (__elen == __plen)
+ {
+ _M_set_indeterminate();
+ __ret = traits_type::not_eof(__c);
+ }
+ }
+ else if (!_M_file.sync())
{
_M_set_indeterminate();
__ret = traits_type::not_eof(__c);
@@ -546,9 +377,6 @@ namespace std
_M_buf = __s;
_M_buf_size_opt = _M_buf_size = __n;
_M_set_indeterminate();
-
- // Step 3: Make sure a pback buffer is allocated.
- _M_allocate_pback_buffer();
}
_M_last_overflowed = false;
return this;
@@ -560,17 +388,16 @@ namespace std
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
- bool __testopen = this->is_open();
- bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
- bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
+ bool __testin = (ios_base::in & _M_mode & __mode) != 0;
+ bool __testout = (ios_base::out & _M_mode & __mode) != 0;
// Should probably do has_facet checks here.
int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
if (__width < 0)
__width = 0;
- bool __testfail = __off != 0 && __width <= 0;
+ bool __testfail = __off != 0 && __width <= 0;
- if (__testopen && !__testfail && (__testin || __testout))
+ if (this->is_open() && !__testfail && (__testin || __testout))
{
// Ditch any pback buffers to avoid confusion.
_M_pback_destroy();
@@ -591,19 +418,18 @@ namespace std
_M_output_unshift();
}
//in
- // NB: underflow() rewinds the external buffer.
else if (__testget && __way == ios_base::cur)
- __computed_off += _M_in_cur - _M_in_beg;
+ __computed_off += _M_in_cur - _M_filepos;
- __ret = _M_file->seekoff(__computed_off, __way, __mode);
+ __ret = _M_file.seekoff(__computed_off, __way, __mode);
_M_set_indeterminate();
}
// NB: Need to do this in case _M_file in indeterminate
- // state, ie _M_file->_offset == -1
+ // state, ie _M_file._offset == -1
else
{
- __ret = _M_file->seekoff(__off, ios_base::cur, __mode);
- __ret += max(_M_out_cur, _M_in_cur) - _M_buf;
+ __ret = _M_file.seekoff(__off, ios_base::cur, __mode);
+ __ret += max(_M_out_cur, _M_in_cur) - _M_filepos;
}
}
_M_last_overflowed = false;
@@ -615,13 +441,10 @@ namespace std
basic_filebuf<_CharT, _Traits>::
seekpos(pos_type __pos, ios_base::openmode __mode)
{
- pos_type __ret;
- off_type __off = __pos;
-
- __ret = this->seekoff(__off, ios_base::beg, __mode);
-
- _M_last_overflowed = false;
- return __ret;
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 171. Strange seekpos() semantics due to joint position
+ return this->seekoff(off_type(__pos), ios_base::beg, __mode);
+#endif
}
template<typename _CharT, typename _Traits>
@@ -638,10 +461,7 @@ namespace std
bool __testbeg = gptr() == eback() && pptr() == pbase();
if (__testbeg && _M_buf_locale != __loc)
- {
- _M_buf_locale = __loc;
- _M_buf_locale_init = true;
- }
+ _M_buf_locale = __loc;
// NB this may require the reconversion of previously
// converted chars. This in turn may cause the reconstruction
@@ -654,13 +474,16 @@ namespace std
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
extern template class basic_filebuf<char>;
- extern template class basic_filebuf<wchar_t>;
extern template class basic_ifstream<char>;
- extern template class basic_ifstream<wchar_t>;
extern template class basic_ofstream<char>;
- extern template class basic_ofstream<wchar_t>;
extern template class basic_fstream<char>;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ extern template class basic_filebuf<wchar_t>;
+ extern template class basic_ifstream<wchar_t>;
+ extern template class basic_ofstream<wchar_t>;
extern template class basic_fstream<wchar_t>;
+#endif
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h
index 7525e7d6f4c..a56475ccef6 100644
--- a/libstdc++-v3/include/bits/ios_base.h
+++ b/libstdc++-v3/include/bits/ios_base.h
@@ -158,6 +158,8 @@ namespace std
explicit
failure(const string& __str) throw();
+ // This declaration is not useless:
+ // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual
~failure() throw();
@@ -218,6 +220,9 @@ namespace std
typedef int io_state;
typedef int open_mode;
typedef int seek_dir;
+
+ typedef std::streampos streampos;
+ typedef std::streamoff streamoff;
#endif
// Callbacks;
@@ -238,6 +243,8 @@ namespace std
streamsize _M_precision;
streamsize _M_width;
fmtflags _M_flags;
+ iostate _M_exception;
+ iostate _M_streambuf_state;
// 27.4.2.6 Members for callbacks
// 27.4.2.6 ios_base callbacks
@@ -256,9 +263,9 @@ namespace std
void
_M_add_reference() { __atomic_add(&_M_refcount, 1); }
+ // 0 => OK to delete.
int
_M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); }
- // 0 => OK to delete
};
_Callback_list* _M_callbacks;
@@ -274,13 +281,19 @@ namespace std
{
void* _M_pword;
long _M_iword;
+ _Words() : _M_pword(0), _M_iword(0) { }
};
- static const int _S_local_words = 8;
- _Words _M_word_array[_S_local_words]; // Guaranteed storage
- _Words _M_dummy; // Only for failed iword/pword calls.
- _Words* _M_words;
- int _M_word_limit;
+ // Only for failed iword/pword calls.
+ _Words _M_word_zero;
+
+ // Guaranteed storage.
+ static const int _S_local_word_size = 8;
+ _Words _M_local_word[_S_local_word_size];
+
+ // Allocated storage.
+ int _M_word_size;
+ _Words* _M_word;
_Words&
_M_grow_words(int __index);
@@ -386,16 +399,16 @@ namespace std
inline long&
iword(int __ix)
{
- _Words& __word = (__ix < _M_word_limit)
- ? _M_words[__ix] : _M_grow_words(__ix);
+ _Words& __word = (__ix < _M_word_size)
+ ? _M_word[__ix] : _M_grow_words(__ix);
return __word._M_iword;
}
inline void*&
pword(int __ix)
{
- _Words& __word = (__ix < _M_word_limit)
- ? _M_words[__ix] : _M_grow_words(__ix);
+ _Words& __word = (__ix < _M_word_size)
+ ? _M_word[__ix] : _M_grow_words(__ix);
return __word._M_pword;
}
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index 4a32c659be4..a6e49a923bd 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -50,16 +50,18 @@ namespace std
if (!__noskipws && (__in.flags() & ios_base::skipws))
{
const __int_type __eof = traits_type::eof();
- const __ctype_type* __ctype = __in._M_get_fctype_ios();
__streambuf_type* __sb = __in.rdbuf();
__int_type __c = __sb->sgetc();
-
- while (__c != __eof && __ctype->is(ctype_base::space, __c))
- __c = __sb->snextc();
+
+ if (__in._M_check_facet(__in._M_fctype))
+ while (!traits_type::eq_int_type(__c, __eof)
+ && __in._M_fctype->is(ctype_base::space,
+ traits_type::to_char_type(__c)))
+ __c = __sb->snextc();
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
//195. Should basic_istream::sentry's constructor ever set eofbit?
- if (__c == __eof)
+ if (traits_type::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
#endif
}
@@ -520,7 +522,7 @@ namespace std
{
__c = this->rdbuf()->sbumpc();
// 27.6.1.1 paragraph 3
- if (__c != __eof)
+ if (!traits_type::eq_int_type(__c, __eof))
_M_gcount = 1;
else
this->setstate(ios_base::eofbit | ios_base::failbit);
@@ -551,7 +553,7 @@ namespace std
const int_type __eof = traits_type::eof();
int_type __bufval = this->rdbuf()->sbumpc();
// 27.6.1.1 paragraph 3
- if (__bufval != __eof)
+ if (!traits_type::eq_int_type(__bufval, __eof))
{
_M_gcount = 1;
__c = traits_type::to_char_type(__bufval);
@@ -578,28 +580,24 @@ namespace std
{
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__cerb && __n > 1)
+ if (__cerb)
{
try
{
const int_type __idelim = traits_type::to_int_type(__delim);
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
- int_type __c = __sb->sbumpc();
- bool __testdelim = __c == __idelim;
- bool __testeof = __c == __eof;
+ int_type __c = __sb->sgetc();
- while (_M_gcount < __n - 1 && !__testeof && !__testdelim)
+ while (_M_gcount + 1 < __n
+ && !traits_type::eq_int_type(__c, __eof)
+ && !traits_type::eq_int_type(__c, __idelim))
{
*__s++ = traits_type::to_char_type(__c);
+ __c = __sb->snextc();
++_M_gcount;
- __c = __sb->sbumpc();
- __testeof = __c == __eof;
- __testdelim = __c == __idelim;
}
- if (__testdelim || _M_gcount == __n - 1)
- __sb->sputbackc(__c);
- if (__testeof)
+ if (traits_type::eq_int_type(__c, __eof))
this->setstate(ios_base::eofbit);
}
catch(exception& __fail)
@@ -626,35 +624,32 @@ namespace std
sentry __cerb(*this, true);
if (__cerb)
{
- int_type __c;
- __streambuf_type* __this_sb = this->rdbuf();
try
{
const int_type __idelim = traits_type::to_int_type(__delim);
const int_type __eof = traits_type::eof();
- __c = __this_sb->sbumpc();
- bool __testdelim = __c == __idelim;
- bool __testeof = __c == __eof;
- bool __testput = true;
+ __streambuf_type* __this_sb = this->rdbuf();
+ int_type __c = __this_sb->sgetc();
+ char_type __c2 = traits_type::to_char_type(__c);
- while (!__testeof && !__testdelim
- && (__testput = __sb.sputc(traits_type::to_char_type(__c))
- != __eof))
+ while (!traits_type::eq_int_type(__c, __eof)
+ && !traits_type::eq_int_type(__c, __idelim)
+ && !traits_type::eq_int_type(__sb.sputc(__c2), __eof))
{
++_M_gcount;
- __c = __this_sb->sbumpc();
- __testeof = __c == __eof;
- __testdelim = __c == __idelim;
+ __c = __this_sb->snextc();
+ __c2 = traits_type::to_char_type(__c);
}
- if (__testdelim || !__testput)
- __this_sb->sputbackc(traits_type::to_char_type(__c));
- if (__testeof)
+ if (traits_type::eq_int_type(__c, __eof))
this->setstate(ios_base::eofbit);
}
catch(exception& __fail)
{
- // Exception may result from sputc->overflow.
- __this_sb->sputbackc(traits_type::to_char_type(__c));
+ // 27.6.1.3 paragraph 1
+ // Turn this on without causing an ios::failure to be thrown.
+ this->setstate(ios_base::badbit);
+ if ((this->exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
}
}
if (!_M_gcount)
@@ -673,33 +668,30 @@ namespace std
{
try
{
- __streambuf_type* __sb = this->rdbuf();
- int_type __c = __sb->sbumpc();
- ++_M_gcount;
const int_type __idelim = traits_type::to_int_type(__delim);
const int_type __eof = traits_type::eof();
- bool __testdelim = __c == __idelim;
- bool __testeof = __c == __eof;
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
- while (_M_gcount < __n && !__testeof && !__testdelim)
+ while (_M_gcount + 1 < __n
+ && !traits_type::eq_int_type(__c, __eof)
+ && !traits_type::eq_int_type(__c, __idelim))
{
*__s++ = traits_type::to_char_type(__c);
- __c = __sb->sbumpc();
+ __c = __sb->snextc();
++_M_gcount;
- __testeof = __c == __eof;
- __testdelim = __c == __idelim;
}
-
- if (__testeof)
- {
- --_M_gcount;
- this->setstate(ios_base::eofbit);
- }
- else if (!__testdelim)
+ if (traits_type::eq_int_type(__c, __eof))
+ this->setstate(ios_base::eofbit);
+ else
{
- --_M_gcount;
- __sb->sputbackc(traits_type::to_char_type(__c));
- this->setstate(ios_base::failbit);
+ if (traits_type::eq_int_type(__c, __idelim))
+ {
+ __sb->sbumpc();
+ ++_M_gcount;
+ }
+ else
+ this->setstate(ios_base::failbit);
}
}
catch(exception& __fail)
@@ -728,24 +720,19 @@ namespace std
{
try
{
- const int_type __idelim = traits_type::to_int_type(__delim);
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
- int_type __c = __sb->sbumpc();
- bool __testdelim = __c == __idelim;
- bool __testeof = __c == __eof;
+ int_type __c;
__n = min(__n, numeric_limits<streamsize>::max());
- while (_M_gcount < __n - 1 && !__testeof && !__testdelim)
+ while (_M_gcount < __n
+ && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
{
++_M_gcount;
- __c = __sb->sbumpc();
- __testeof = __c == __eof;
- __testdelim = __c == __idelim;
+ if (traits_type::eq_int_type(__c, __delim))
+ break;
}
- if ((_M_gcount == __n - 1 && !__testeof) || __testdelim)
- ++_M_gcount;
- if (__testeof)
+ if (traits_type::eq_int_type(__c, __eof))
this->setstate(ios_base::eofbit);
}
catch(exception& __fail)
@@ -793,39 +780,19 @@ namespace std
sentry __cerb(*this, true);
if (__cerb)
{
- if (__n > 0)
+ try
{
- try
- {
- const int_type __eof = traits_type::eof();
- __streambuf_type* __sb = this->rdbuf();
- int_type __c = __sb->sbumpc();
- bool __testeof = __c == __eof;
-
- while (_M_gcount < __n - 1 && !__testeof)
- {
- *__s++ = traits_type::to_char_type(__c);
- ++_M_gcount;
- __c = __sb->sbumpc();
- __testeof = __c == __eof;
- }
- if (__testeof)
- this->setstate(ios_base::eofbit | ios_base::failbit);
- else
- {
- // _M_gcount == __n - 1
- *__s++ = traits_type::to_char_type(__c);
- ++_M_gcount;
- }
- }
- catch(exception& __fail)
- {
- // 27.6.1.3 paragraph 1
- // Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ _M_gcount = this->rdbuf()->sgetn(__s, __n);
+ if (_M_gcount != __n)
+ this->setstate(ios_base::eofbit | ios_base::failbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.3 paragraph 1
+ // Turn this on without causing an ios::failure to be thrown.
+ this->setstate(ios_base::badbit);
+ if ((this->exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
}
}
else
@@ -838,32 +805,30 @@ namespace std
basic_istream<_CharT, _Traits>::
readsome(char_type* __s, streamsize __n)
{
- const int_type __eof = traits_type::eof();
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb)
{
- if (__n > 0)
+ try
{
- try
+ // Cannot compare int_type with streamsize generically.
+ streamsize __num = this->rdbuf()->in_avail();
+ if (__num >= 0)
{
- streamsize __num = this->rdbuf()->in_avail();
- if (__num != static_cast<streamsize>(__eof))
- {
- __num = min(__num, __n);
- _M_gcount = this->rdbuf()->sgetn(__s, __num);
- }
- else
- this->setstate(ios_base::eofbit);
- }
- catch(exception& __fail)
- {
- // 27.6.1.3 paragraph 1
- // Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
+ __num = min(__num, __n);
+ if (__num)
+ _M_gcount = this->rdbuf()->sgetn(__s, __num);
}
+ else
+ this->setstate(ios_base::eofbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.3 paragraph 1
+ // Turn this on without causing an ios::failure to be thrown.
+ this->setstate(ios_base::badbit);
+ if ((this->exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
}
}
else
@@ -883,7 +848,8 @@ namespace std
{
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
- if (!__sb || __sb->sputbackc(__c) == __eof)
+ if (!__sb
+ || traits_type::eq_int_type(__sb->sputbackc(__c), __eof))
this->setstate(ios_base::badbit);
}
catch(exception& __fail)
@@ -913,7 +879,8 @@ namespace std
{
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
- if (!__sb || __eof == __sb->sungetc())
+ if (!__sb
+ || traits_type::eq_int_type(__sb->sungetc(), __eof))
this->setstate(ios_base::badbit);
}
catch(exception& __fail)
@@ -935,7 +902,7 @@ namespace std
basic_istream<_CharT, _Traits>::
sync(void)
{
- int __ret = traits_type::eof();
+ int __ret = -1;
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb)
@@ -943,10 +910,13 @@ namespace std
try
{
__streambuf_type* __sb = this->rdbuf();
- if (!__sb || __ret == __sb->pubsync())
- this->setstate(ios_base::badbit);
- else
- __ret = 0;
+ if (__sb)
+ {
+ if (__sb->pubsync() == -1)
+ this->setstate(ios_base::badbit);
+ else
+ __ret = 0;
+ }
}
catch(exception& __fail)
{
@@ -966,23 +936,8 @@ namespace std
tellg(void)
{
pos_type __ret = pos_type(-1);
- _M_gcount = 0;
- sentry __cerb(*this, true);
- if (__cerb)
- {
- try
- {
- __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
- }
- catch(exception& __fail)
- {
- // 27.6.1.3 paragraph 1
- // Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
- }
+ if (!this->fail())
+ __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
return __ret;
}
@@ -993,28 +948,16 @@ namespace std
seekg(pos_type __pos)
{
_M_gcount = 0;
- sentry __cerb(*this, true);
- if (__cerb)
+ if (!this->fail())
{
- try
- {
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
- pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::in);
+ pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::in);
// 129. Need error indication from seekp() and seekg()
- if (__err == pos_type(off_type(-1)))
- this->setstate(ios_base::failbit);
+ if (__err == pos_type(off_type(-1)))
+ this->setstate(ios_base::failbit);
#endif
- }
- catch(exception& __fail)
- {
- // 27.6.1.3 paragraph 1
- // Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
}
return *this;
}
@@ -1025,29 +968,17 @@ namespace std
seekg(off_type __off, ios_base::seekdir __dir)
{
_M_gcount = 0;
- sentry __cerb(*this, true);
- if (__cerb)
+ if (!this->fail())
{
- try
- {
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
- pos_type __err = this->rdbuf()->pubseekoff(__off, __dir,
- ios_base::in);
+ pos_type __err = this->rdbuf()->pubseekoff(__off, __dir,
+ ios_base::in);
// 129. Need error indication from seekp() and seekg()
- if (__err == pos_type(off_type(-1)))
- this->setstate(ios_base::failbit);
+ if (__err == pos_type(off_type(-1)))
+ this->setstate(ios_base::failbit);
#endif
- }
- catch(exception& __fail)
- {
- // 27.6.1.3 paragraph 1
- // Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
}
return *this;
}
@@ -1098,25 +1029,20 @@ namespace std
if (__num == 0)
__num = numeric_limits<streamsize>::max();
- __streambuf_type* __sb = __in.rdbuf();
- const __ctype_type* __ctype = __in._M_get_fctype_ios();
- int_type __c = __sb->sbumpc();
+ const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc());
const int_type __eof = _Traits::eof();
- bool __testsp = __ctype->is(ctype_base::space, __c);
- bool __testeof = __c == __eof;
+ __streambuf_type* __sb = __in.rdbuf();
+ int_type __c = __sb->sgetc();
- while (__extracted < __num - 1 && !__testeof && !__testsp)
+ while (__extracted < __num - 1
+ && !_Traits::eq_int_type(__c, __eof)
+ && !__ctype.is(ctype_base::space, __c))
{
*__s++ = __c;
++__extracted;
- __c = __sb->sbumpc();
- __testeof = __c == __eof;
- __testsp = __ctype->is(ctype_base::space, __c);
+ __c = __sb->snextc();
}
-
- if (!__testeof)
- __sb->sputbackc(__c);
- else
+ if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
@@ -1148,26 +1074,17 @@ namespace std
typedef typename __istream_type::__streambuf_type __streambuf_type;
typedef typename __istream_type::__ctype_type __ctype_type;
typedef typename __istream_type::int_type __int_type;
- typedef typename __istream_type::char_type __char_type;
- __streambuf_type* __sb = __in.rdbuf();
- const __ctype_type* __ctype = __in._M_get_fctype_ios();
+ const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc());
const __int_type __eof = _Traits::eof();
- __int_type __c;
- bool __testeof;
- bool __testsp;
+ __streambuf_type* __sb = __in.rdbuf();
+ __int_type __c = __sb->sgetc();
- do
- {
- __c = __sb->sbumpc();
- __testeof = __c == __eof;
- __testsp = __ctype->is(ctype_base::space, __c);
- }
- while (!__testeof && __testsp);
+ while (!_Traits::eq_int_type(__c, __eof)
+ && __ctype.is(ctype_base::space, __c))
+ __c = __sb->snextc();
- if (!__testeof && !__testsp)
- __sb->sputbackc(__c);
- else
+ if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
return __in;
@@ -1195,24 +1112,20 @@ namespace std
__size_type __n;
__n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
- __streambuf_type* __sb = __in.rdbuf();
- const __ctype_type* __ctype = __in._M_get_fctype_ios();
- __int_type __c = __sb->sbumpc();
+ const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc());
const __int_type __eof = _Traits::eof();
- bool __testsp = __ctype->is(ctype_base::space, __c);
- bool __testeof = __c == __eof;
-
- while (__extracted < __n && !__testeof && !__testsp)
+ __streambuf_type* __sb = __in.rdbuf();
+ __int_type __c = __sb->sgetc();
+
+ while (__extracted < __n
+ && !_Traits::eq_int_type(__c, __eof)
+ && !__ctype.is(ctype_base::space, __c))
{
__str += _Traits::to_char_type(__c);
++__extracted;
- __c = __sb->sbumpc();
- __testeof = __c == __eof;
- __testsp = __ctype->is(ctype_base::space, __c);
+ __c = __sb->snextc();
}
- if (!__testeof)
- __sb->sputbackc(__c);
- else
+ if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
__in.width(0);
}
@@ -1248,18 +1161,18 @@ namespace std
__streambuf_type* __sb = __in.rdbuf();
__int_type __c = __sb->sbumpc();
const __int_type __eof = _Traits::eof();
- __testdelim = __c == __idelim;
- bool __testeof = __c == __eof;
+ __testdelim = _Traits::eq_int_type(__c, __idelim);
- while (__extracted <= __n && !__testeof && !__testdelim)
+ while (__extracted <= __n
+ && !_Traits::eq_int_type(__c, __eof)
+ && !__testdelim)
{
__str += _Traits::to_char_type(__c);
++__extracted;
__c = __sb->sbumpc();
- __testeof = __c == __eof;
- __testdelim = __c == __idelim;
+ __testdelim = _Traits::eq_int_type(__c, __idelim);
}
- if (__testeof)
+ if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
}
if (!__extracted && !__testdelim)
@@ -1285,8 +1198,10 @@ namespace std
extern template istream& operator>>(istream&, unsigned char*);
extern template istream& operator>>(istream&, signed char*);
+#ifdef _GLIBCPP_USE_WCHAR_T
extern template class basic_istream<wchar_t>;
extern template wistream& ws(wistream&);
extern template wistream& operator>>(wistream&, wchar_t&);
extern template wistream& operator>>(wistream&, wchar_t*);
+#endif
} // namespace std
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index c00e17cd5aa..6e42b3bb5ea 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -43,13 +43,21 @@
#pragma GCC system_header
#include <ctime> // For struct tm
-#ifdef _GLIBCPP_USE_WCHAR_T
-# include <cwctype> // For wctype_t
-#endif
+#include <cwctype> // For wctype_t
#include <ios> // For ios_base
namespace std
{
+ // NB: Don't instantiate required wchar_t facets if no wchar_t support.
+#ifdef _GLIBCPP_USE_WCHAR_T
+# define _GLIBCPP_NUM_FACETS 28
+#else
+# define _GLIBCPP_NUM_FACETS 14
+#endif
+
+ template<typename _CharT, typename _Traits>
+ struct __pad;
+
// 22.2.1.1 Template class ctype
// Include host and configuration specific ctype enums for ctype_base.
#include <bits/ctype_base.h>
@@ -169,11 +177,11 @@ namespace std
typedef _CharT char_type;
typedef typename ctype::mask mask;
+ static locale::id id;
+
explicit
ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
- static locale::id id;
-
protected:
virtual
~ctype();
@@ -421,12 +429,6 @@ namespace std
class __num_base
{
protected:
- // Used to establish gating factor for base 16 input.
- static const double _S_scale_hex;
-
- // Used to establish gating factor for base 8 input.
- static const double _S_scale_oct;
-
// String literal of acceptable (narrow) input, for num_get.
// "0123456789eEabcdfABCDF"
static const char _S_atoms[];
@@ -464,9 +466,9 @@ namespace std
private:
char_type _M_decimal_point;
char_type _M_thousands_sep;
- string _M_grouping;
- string_type _M_truename;
- string_type _M_falsename;
+ const char* _M_grouping;
+ const char_type* _M_truename;
+ const char_type* _M_falsename;
public:
explicit
@@ -499,7 +501,7 @@ namespace std
protected:
virtual
- ~numpunct() { }
+ ~numpunct();
virtual char_type
do_decimal_point() const
@@ -530,11 +532,17 @@ namespace std
locale::id numpunct<_CharT>::id;
template<>
+ numpunct<char>::~numpunct();
+
+ template<>
void
numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
+ numpunct<wchar_t>::~numpunct();
+
+ template<>
void
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
#endif
@@ -647,6 +655,7 @@ namespace std
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
+
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
@@ -692,6 +701,23 @@ namespace std
template<typename _CharT, typename _InIter>
locale::id num_get<_CharT, _InIter>::id;
+#if 0
+ // Partial specialization for istreambuf_iterator, so can use traits_type.
+ template<typename _CharT>
+ class num_get<_CharT, istreambuf_iterator<_CharT> >;
+
+ iter_type
+ _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ string& __xtrc) const;
+
+ iter_type
+ _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ string& __xtrc, int& __base) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
+#endif
+
template<typename _CharT, typename _OutIter>
class num_put : public locale::facet, public __num_base
{
@@ -819,9 +845,8 @@ namespace std
explicit
collate(size_t __refs = 0)
: locale::facet(__refs)
- { _M_c_locale_collate = _S_clone_c_locale(_S_c_locale); }
+ { _M_c_locale_collate = _S_c_locale; }
- // Non-standard.
explicit
collate(__c_locale __cloc, size_t __refs = 0)
: locale::facet(__refs)
@@ -842,10 +867,10 @@ namespace std
// Used to abstract out _CharT bits in virtual member functions, below.
int
- _M_compare_helper(const _CharT*, const _CharT*) const;
+ _M_compare(const _CharT*, const _CharT*) const;
size_t
- _M_transform_helper(_CharT*, const _CharT*, size_t) const;
+ _M_transform(_CharT*, const _CharT*, size_t) const;
protected:
virtual
@@ -869,21 +894,20 @@ namespace std
// Specializations.
template<>
int
- collate<char>::_M_compare_helper(const char*, const char*) const;
+ collate<char>::_M_compare(const char*, const char*) const;
template<>
size_t
- collate<char>::_M_transform_helper(char*, const char*, size_t) const;
+ collate<char>::_M_transform(char*, const char*, size_t) const;
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
int
- collate<wchar_t>::_M_compare_helper(const wchar_t*, const wchar_t*) const;
+ collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
template<>
size_t
- collate<wchar_t>::_M_transform_helper(wchar_t*, const wchar_t*,
- size_t) const;
+ collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
#endif
template<typename _CharT>
@@ -928,7 +952,7 @@ namespace std
protected:
__c_locale _M_c_locale_timepunct;
- const char* _M_name_timepunct;
+ char* _M_name_timepunct;
const _CharT* _M_date_format;
const _CharT* _M_date_era_format;
const _CharT* _M_time_format;
@@ -987,18 +1011,14 @@ namespace std
public:
explicit
- __timepunct(size_t __refs = 0)
- : locale::facet(__refs), _M_name_timepunct("C")
- { _M_initialize_timepunct(); }
+ __timepunct(size_t __refs = 0);
explicit
- __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
- : locale::facet(__refs), _M_name_timepunct(__s)
- { _M_initialize_timepunct(__cloc); }
+ __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
void
- _M_put_helper(_CharT* __s, size_t __maxlen, const _CharT* __format,
- const tm* __tm) const;
+ _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
+ const tm* __tm) const;
void
_M_date_formats(const _CharT** __date) const
@@ -1091,11 +1111,7 @@ namespace std
protected:
virtual
- ~__timepunct()
- {
- if (_M_c_locale_timepunct)
- _S_destroy_c_locale(_M_c_locale_timepunct);
- }
+ ~__timepunct();
// For use at construction time only.
void
@@ -1116,8 +1132,7 @@ namespace std
template<>
void
- __timepunct<char>::_M_put_helper(char*, size_t, const char*,
- const tm*) const;
+ __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
@@ -1130,14 +1145,16 @@ namespace std
template<>
void
- __timepunct<wchar_t>::_M_put_helper(wchar_t*, size_t, const wchar_t*,
- const tm*) const;
+ __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
+ const tm*) const;
#endif
// Generic.
template<typename _CharT>
const _CharT* __timepunct<_CharT>::_S_timezones[14];
+ // Include host and configuration specific timepunct functions.
+ #include <bits/time_members.h>
template<typename _CharT, typename _InIter>
class time_get : public locale::facet, public time_base
@@ -1328,19 +1345,19 @@ namespace std
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
- static const bool intl = _Intl;
- static locale::id id;
+ static const bool intl = _Intl;
+ static locale::id id;
private:
- char_type _M_decimal_point;
- char_type _M_thousands_sep;
- string _M_grouping;
- string_type _M_curr_symbol;
- string_type _M_positive_sign;
- string_type _M_negative_sign;
- int _M_frac_digits;
- pattern _M_pos_format;
- pattern _M_neg_format;
+ const char* _M_grouping;
+ char_type _M_decimal_point;
+ char_type _M_thousands_sep;
+ const char_type* _M_curr_symbol;
+ const char_type* _M_positive_sign;
+ const char_type* _M_negative_sign;
+ int _M_frac_digits;
+ pattern _M_pos_format;
+ pattern _M_neg_format;
public:
explicit
@@ -1348,8 +1365,9 @@ namespace std
{ _M_initialize_moneypunct(); }
explicit
- moneypunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
- { _M_initialize_moneypunct(__cloc); }
+ moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
+ : locale::facet(__refs)
+ { _M_initialize_moneypunct(__cloc, __s); }
char_type
decimal_point() const
@@ -1389,7 +1407,7 @@ namespace std
protected:
virtual
- ~moneypunct() { }
+ ~moneypunct();
virtual char_type
do_decimal_point() const
@@ -1429,7 +1447,8 @@ namespace std
// For use at construction time only.
void
- _M_initialize_moneypunct(__c_locale __cloc = NULL);
+ _M_initialize_moneypunct(__c_locale __cloc = NULL,
+ const char* __name = NULL);
};
template<typename _CharT, bool _Intl>
@@ -1438,22 +1457,36 @@ namespace std
template<typename _CharT, bool _Intl>
const bool moneypunct<_CharT, _Intl>::intl;
+ template<>
+ moneypunct<char, true>::~moneypunct();
+
+ template<>
+ moneypunct<char, false>::~moneypunct();
+
template<>
void
- moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc);
+ moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
template<>
void
- moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc);
+ moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ moneypunct<wchar_t, true>::~moneypunct();
+
+ template<>
+ moneypunct<wchar_t, false>::~moneypunct();
+
template<>
void
- moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc);
+ moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
+ const char*);
template<>
void
- moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc);
+ moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
+ const char*);
#endif
template<typename _CharT, bool _Intl>
@@ -1581,27 +1614,17 @@ namespace std
// Underlying "C" library locale information saved from
// initialization, needed by messages_byname as well.
__c_locale _M_c_locale_messages;
-#if 1
- // Only needed if glibc < 2.3
- const char* _M_name_messages;
-#endif
+ char* _M_name_messages;
public:
static locale::id id;
explicit
- messages(size_t __refs = 0)
- : locale::facet(__refs), _M_name_messages("C")
- { _M_c_locale_messages = _S_clone_c_locale(_S_c_locale); }
+ messages(size_t __refs = 0);
// Non-standard.
explicit
- messages(__c_locale __cloc, const char* __name, size_t __refs = 0)
- : locale::facet(__refs)
- {
- _M_name_messages = __name;
- _M_c_locale_messages = _S_clone_c_locale(__cloc);
- }
+ messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
catalog
open(const basic_string<char>& __s, const locale& __loc) const
@@ -1621,8 +1644,7 @@ namespace std
protected:
virtual
- ~messages()
- { _S_destroy_c_locale(_M_c_locale_messages); }
+ ~messages();
virtual catalog
do_open(const basic_string<char>&, const locale&) const;
@@ -1690,8 +1712,11 @@ namespace std
string
messages<char>::do_get(catalog, int, int, const string&) const;
- // Include host and configuration specific messages virtual functions.
- #include <bits/messages_members.h>
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ wstring
+ messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
+#endif
template<typename _CharT>
class messages_byname : public messages<_CharT>
@@ -1701,13 +1726,7 @@ namespace std
typedef basic_string<_CharT> string_type;
explicit
- messages_byname(const char* __s, size_t __refs = 0)
- : messages<_CharT>(__refs)
- {
- _M_name_messages = __s;
- _S_destroy_c_locale(_M_c_locale_messages);
- _S_create_c_locale(_M_c_locale_messages, __s);
- }
+ messages_byname(const char* __s, size_t __refs = 0);
protected:
virtual
@@ -1715,6 +1734,9 @@ namespace std
{ }
};
+ // Include host and configuration specific messages functions.
+ #include <bits/messages_members.h>
+
// Subclause convenience interfaces, inlines.
// NB: These are inline because, when used in a loop, some compilers
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 02ae96eeb51..1bf3d7ce796 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -41,9 +41,7 @@
#include <cmath> // For ceil
#include <cctype> // For isspace
#include <limits> // For numeric_limits
-#include <memory> // For auto_ptr
#include <bits/streambuf_iterator.h>
-#include <vector>
#include <typeinfo> // For bad_cast.
namespace std
@@ -72,21 +70,20 @@ namespace std
const _Facet&
use_facet(const locale& __loc)
{
- size_t __i = _Facet::id._M_index;
- locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
- const locale::facet* __fp = (*__facet)[__i];
- if (__fp == 0 || __i >= __facet->size())
+ size_t __i = _Facet::id._M_id();
+ locale::facet** __facets = __loc._M_impl->_M_facets;
+ if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
__throw_bad_cast();
- return static_cast<const _Facet&>(*__fp);
+ return static_cast<const _Facet&>(*__facets[__i]);
}
template<typename _Facet>
bool
has_facet(const locale& __loc) throw()
{
- size_t __i = _Facet::id._M_index;
- locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
- return (__i < __facet->size() && (*__facet)[__i] != 0);
+ size_t __i = _Facet::id._M_id();
+ locale::facet** __facets = __loc._M_impl->_M_facets;
+ return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
}
@@ -97,6 +94,7 @@ namespace std
_M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
ios_base::iostate& __err, string& __xtrc) const
{
+ typedef char_traits<_CharT> __traits_type;
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
@@ -106,7 +104,8 @@ namespace std
const char_type __minus = __ctype.widen('-');
int __pos = 0;
char_type __c = *__beg;
- if ((__c == __plus || __c == __minus) && __beg != __end)
+ if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
+ && __beg != __end)
{
__xtrc += __ctype.narrow(__c, char());
++__pos;
@@ -116,7 +115,7 @@ namespace std
// Next, strip leading zeros.
const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
bool __found_zero = false;
- while (__c == __zero && __beg != __end)
+ while (__traits_type::eq(__c, __zero) && __beg != __end)
{
__c = *(++__beg);
__found_zero = true;
@@ -144,11 +143,10 @@ namespace std
while (__beg != __end)
{
// Only look in digits.
- typedef char_traits<_CharT> __traits_type;
const char_type* __p = __traits_type::find(__watoms, 10, __c);
// NB: strchr returns true for __c == 0x0
- if (__p && __c)
+ if (__p && !__traits_type::eq(__c, char_type()))
{
// Try first for acceptable digit; record it if found.
++__pos;
@@ -156,7 +154,8 @@ namespace std
++__sep_pos;
__c = *(++__beg);
}
- else if (__c == __sep && __check_grouping && !__found_dec)
+ else if (__traits_type::eq(__c, __sep)
+ && __check_grouping && !__found_dec)
{
// NB: Thousands separator at the beginning of a string
// is a no-no, as is two consecutive thousands separators.
@@ -172,15 +171,20 @@ namespace std
break;
}
}
- else if (__c == __dec && !__found_dec)
+ else if (__traits_type::eq(__c, __dec) && !__found_dec)
{
- __found_grouping += static_cast<char>(__sep_pos);
+ // According to the standard, if no grouping chars are seen,
+ // no grouping check is applied. Therefore __found_grouping
+ // must be adjusted only if __dec comes after some __sep.
+ if (__found_grouping.size())
+ __found_grouping += static_cast<char>(__sep_pos);
++__pos;
__xtrc += '.';
__c = *(++__beg);
__found_dec = true;
}
- else if ((__c == __watoms[_M_e] || __c == __watoms[_M_E])
+ else if ((__traits_type::eq(__c, __watoms[_M_e])
+ || __traits_type::eq(__c, __watoms[_M_E]))
&& !__found_sci && __pos)
{
// Scientific notation.
@@ -189,7 +193,8 @@ namespace std
__c = *(++__beg);
// Remove optional plus or minus sign, if they exist.
- if (__c == __plus || __c == __minus)
+ if (__traits_type::eq(__c, __plus)
+ || __traits_type::eq(__c, __minus))
{
++__pos;
__xtrc += __ctype.narrow(__c, char());
@@ -227,6 +232,7 @@ namespace std
_M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
ios_base::iostate& __err, string& __xtrc, int& __base) const
{
+ typedef char_traits<_CharT> __traits_type;
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
@@ -240,10 +246,13 @@ namespace std
else
__base = 10;
- // First check for sign.
+ // First check for sign.
int __pos = 0;
char_type __c = *__beg;
- if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
+ const char_type __plus = __ctype.widen('+');
+ const char_type __minus = __ctype.widen('-');
+
+ if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
&& __beg != __end)
{
__xtrc += __ctype.narrow(__c, char());
@@ -258,7 +267,7 @@ namespace std
if (__base == 10)
{
bool __found_zero = false;
- while (__c == __zero && __beg != __end)
+ while (__traits_type::eq(__c, __zero) && __beg != __end)
{
__c = *(++__beg);
__found_zero = true;
@@ -269,7 +278,9 @@ namespace std
++__pos;
if (__basefield == 0)
{
- if ((__c == __x || __c == __X) && __beg != __end)
+ if ((__traits_type::eq(__c, __x)
+ || __traits_type::eq(__c, __X))
+ && __beg != __end)
{
__xtrc += __ctype.narrow(__c, char());
++__pos;
@@ -283,12 +294,13 @@ namespace std
}
else if (__base == 16)
{
- if (__c == __zero && __beg != __end)
+ if (__traits_type::eq(__c, __zero) && __beg != __end)
{
__xtrc += _S_atoms[_M_zero];
++__pos;
__c = *(++__beg);
- if ((__c == __x || __c == __X) && __beg != __end)
+ if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X))
+ && __beg != __end)
{
__xtrc += __ctype.narrow(__c, char());
++__pos;
@@ -310,16 +322,15 @@ namespace std
__ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
string __found_grouping;
const string __grouping = __np.grouping();
- bool __check_grouping = __grouping.size() && __base == 10;
+ bool __check_grouping = __grouping.size();
int __sep_pos = 0;
const char_type __sep = __np.thousands_sep();
while (__beg != __end)
{
- typedef char_traits<_CharT> __traits_type;
const char_type* __p = __traits_type::find(__watoms, __len, __c);
// NB: strchr returns true for __c == 0x0
- if (__p && __c)
+ if (__p && !__traits_type::eq(__c, char_type()))
{
// Try first for acceptable digit; record it if found.
__xtrc += _S_atoms[__p - __watoms];
@@ -327,7 +338,7 @@ namespace std
++__sep_pos;
__c = *(++__beg);
}
- else if (__c == __sep && __check_grouping)
+ else if (__traits_type::eq(__c, __sep) && __check_grouping)
{
// NB: Thousands separator at the beginning of a string
// is a no-no, as is two consecutive thousands separators.
@@ -393,19 +404,25 @@ namespace std
// Parse bool values as alphanumeric
else
{
+ typedef char_traits<_CharT> __traits_type;
+ typedef basic_string<_CharT> __string_type;
+
locale __loc = __io.getloc();
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- const char_type* __true = __np.truename().c_str();
- const char_type* __false = __np.falsename().c_str();
-
- const size_t __truen = __np.truename().size() - 1;
- const size_t __falsen = __np.falsename().size() - 1;
+ const __string_type __true = __np.truename();
+ const __string_type __false = __np.falsename();
+ const char_type* __trues = __true.c_str();
+ const char_type* __falses = __false.c_str();
+ const size_t __truen = __true.size() - 1;
+ const size_t __falsen = __false.size() - 1;
for (size_t __n = 0; __beg != __end; ++__n)
{
char_type __c = *__beg++;
- bool __testf = __n <= __falsen ? __c == __false[__n] : false;
- bool __testt = __n <= __truen ? __c == __true[__n] : false;
+ bool __testf = __n <= __falsen
+ ? __traits_type::eq(__c, __falses[__n]) : false;
+ bool __testt = __n <= __truen
+ ? __traits_type::eq(__c, __trues[__n]) : false;
if (!(__testf || __testt))
{
__err |= ios_base::failbit;
@@ -589,16 +606,15 @@ namespace std
return __beg;
}
-
- // The following code uses sprintf() to convert floating point
- // values for insertion into a stream. An optimization would be to
- // replace sprintf() with code that works directly on a wide buffer
- // and then use __pad to do the padding. It would be good
- // to replace sprintf() anyway to avoid accidental buffer overruns
- // and to gain back the efficiency that C++ provides by knowing up
- // front the type of the values to insert. This implementation
- // follows the C++ standard fairly directly as outlined in 22.2.2.2
- // [lib.locale.num.put]
+ // The following code uses snprintf (or sprintf(), when _GLIBCPP_USE_C99
+ // is not defined) to convert floating point values for insertion into a
+ // stream. An optimization would be to replace them with code that works
+ // directly on a wide buffer and then use __pad to do the padding.
+ // It would be good to replace them anyway to gain back the efficiency
+ // that C++ provides by knowing up front the type of the values to insert.
+ // Also, sprintf is dangerous since may lead to accidental buffer overruns.
+ // This implementation follows the C++ standard fairly directly as
+ // outlined in 22.2.2.2 [lib.locale.num.put]
template<typename _CharT, typename _OutIter>
template<typename _ValueT>
_OutIter
@@ -606,15 +622,50 @@ namespace std
_M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
_ValueT __v) const
{
- const int __max_digits = numeric_limits<_ValueT>::digits10;
+ // Note: digits10 is rounded down: we need to add 1 to ensure
+ // we get the full available precision.
+ // Then, in general, one more 1 needs to be added since, when the
+ // %{g,G} conversion specifiers are chosen inside _S_format_float, the
+ // precision field is "the maximum number of significant digits", *not*
+ // the "number of digits to appear after the decimal point", as happens
+ // for %{e,E,f,F} (C99, 7.19.6.1,4).
+ const int __max_digits = numeric_limits<_ValueT>::digits10 + 2;
streamsize __prec = __io.precision();
- // Protect against sprintf() buffer overflows.
+
if (__prec > static_cast<streamsize>(__max_digits))
__prec = static_cast<streamsize>(__max_digits);
// Long enough for the max format spec.
char __fbuf[16];
+ // [22.2.2.2.2] Stage 1, numeric conversion to character.
+ int __len;
+#ifdef _GLIBCPP_USE_C99
+ // First try a buffer perhaps big enough (for sure sufficient for
+ // non-ios_base::fixed outputs)
+ int __cs_size = __max_digits * 3;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+
+ const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec);
+ if (__fp)
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale, __prec);
+ else
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
+
+ // If the buffer was not large enough, try again with the correct size.
+ if (__len >= __cs_size)
+ {
+ __cs_size = __len + 1;
+ __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ if (__fp)
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale, __prec);
+ else
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale);
+ }
+#else
// Consider the possibility of long ios_base::fixed outputs
const bool __fixed = __io.flags() & ios_base::fixed;
const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
@@ -627,12 +678,11 @@ namespace std
: __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- int __len;
- // [22.2.2.2.2] Stage 1, numeric conversion to character.
if (_S_format_float(__io, __fbuf, __mod, __prec))
- __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale, __prec);
+ __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
else
- __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
+ __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
+#endif
return _M_widen_float(__s, __io, __fill, __cs, __len);
}
@@ -644,13 +694,30 @@ namespace std
char __modl, _ValueT __v) const
{
// [22.2.2.2.2] Stage 1, numeric conversion to character.
- // Leave room for "+/-," "0x," and commas. This size is
- // arbitrary, but should work.
- char __cs[64];
+
// Long enough for the max format spec.
char __fbuf[16];
_S_format_int(__io, __fbuf, __mod, __modl);
- int __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
+#ifdef _GLIBCPP_USE_C99
+ // First try a buffer perhaps big enough.
+ int __cs_size = 64;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale);
+ // If the buffer was not large enough, try again with the correct size.
+ if (__len >= __cs_size)
+ {
+ __cs_size = __len + 1;
+ __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale);
+ }
+#else
+ // Leave room for "+/-," "0x," and commas. This size is
+ // arbitrary, but should be largely sufficient.
+ char __cs[128];
+ int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
+#endif
return _M_widen_int(__s, __io, __fill, __cs, __len);
}
@@ -660,6 +727,7 @@ namespace std
_M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
int __len) const
{
+ typedef char_traits<_CharT> __traits_type;
// [22.2.2.2.2] Stage 2, convert to char_type, using correct
// numpunct.decimal_point() values for '.' and adding grouping.
const locale __loc = __io.getloc();
@@ -675,7 +743,7 @@ namespace std
// Replace decimal point.
const _CharT* __p;
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
+ if (__p = __traits_type::find(__ws, __len, __ctype.widen('.')))
__ws[__p - __ws] = __np.decimal_point();
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
@@ -696,7 +764,7 @@ namespace std
// Tack on decimal part.
if (__p)
{
- char_traits<_CharT>::copy(__p2, __p, __len - __declen);
+ __traits_type::copy(__p2, __p, __len - __declen);
__newlen += __len - __declen;
}
@@ -726,18 +794,35 @@ namespace std
* __len * 2));
__ctype.widen(__cs, __cs + __len, __ws);
- // Add grouping, if necessary.
+ // Add grouping, if necessary.
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
const string __grouping = __np.grouping();
- ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
- bool __dec = __basefield != ios_base::oct
- && __basefield != ios_base::hex;
- if (__grouping.size() && __dec)
+ const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+ if (__grouping.size())
{
+ // By itself __add_grouping cannot deal correctly with __ws when
+ // ios::showbase is set and ios_base::oct || ios_base::hex.
+ // Therefore we take care "by hand" of the initial 0, 0x or 0X.
+ // However, remember that the latter do not occur if the number
+ // printed is '0' (__len == 1).
+ streamsize __off = 0;
+ if ((__io.flags() & ios_base::showbase) && __len > 1)
+ if (__basefield == ios_base::oct)
+ {
+ __off = 1;
+ *__ws2 = *__ws;
+ }
+ else if (__basefield == ios_base::hex)
+ {
+ __off = 2;
+ *__ws2 = *__ws;
+ *(__ws2 + 1) = *(__ws + 1);
+ }
_CharT* __p;
- __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
+ __p = __add_grouping(__ws2 + __off, __np.thousands_sep(),
+ __grouping.c_str(),
__grouping.c_str() + __grouping.size(),
- __ws, __ws + __len);
+ __ws + __off, __ws + __len);
__len = __p - __ws2;
// Switch strings.
__ws = __ws2;
@@ -753,13 +838,15 @@ namespace std
_M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws,
int __len) const
{
+ typedef char_traits<_CharT> __traits_type;
// [22.2.2.2.2] Stage 3.
streamsize __w = __io.width();
_CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __w));
if (__w > static_cast<streamsize>(__len))
{
- __pad(__io, __fill, __ws2, __ws, __w, __len, true);
+ __pad<_CharT, __traits_type>::_S_pad(__io, __fill, __ws2, __ws,
+ __w, __len, true);
__len = static_cast<int>(__w);
// Switch strings.
__ws = __ws2;
@@ -782,25 +869,19 @@ namespace std
if ((__flags & ios_base::boolalpha) == 0)
{
unsigned long __uv = __v;
- __s = _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
+ __s = _M_convert_int(__s, __io, __fill, 'u', char(), __uv);
}
else
{
+ typedef basic_string<_CharT> __string_type;
locale __loc = __io.getloc();
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- const char_type* __ws;
- int __len;
+ __string_type __name;
if (__v)
- {
- __ws = __np.truename().c_str();
- __len = __np.truename().size();
- }
+ __name = __np.truename();
else
- {
- __ws = __np.falsename().c_str();
- __len = __np.falsename().size();
- }
- __s = _M_insert(__s, __io, __fill, __ws, __len);
+ __name = __np.falsename();
+ __s = _M_insert(__s, __io, __fill, __name.c_str(), __name.size());
}
return __s;
}
@@ -809,14 +890,14 @@ namespace std
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
- { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); }
+ { return _M_convert_int(__s, __io, __fill, 'd', char(), __v); }
template<typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill,
unsigned long __v) const
- { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); }
+ { return _M_convert_int(__s, __io, __fill, 'u', char(), __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
template<typename _CharT, typename _OutIter>
@@ -837,7 +918,7 @@ namespace std
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
- { return _M_convert_float(__s, __io, __fill, char_type(), __v); }
+ { return _M_convert_float(__s, __io, __fill, char(), __v); }
template<typename _CharT, typename _OutIter>
_OutIter
@@ -858,7 +939,7 @@ namespace std
__io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
try
{
- __s = _M_convert_int(__s, __io, __fill, 'u', char_type(),
+ __s = _M_convert_int(__s, __io, __fill, 'u', char(),
reinterpret_cast<unsigned long>(__v));
__io.flags(__flags);
}
@@ -881,7 +962,7 @@ namespace std
__beg = this->do_get(__beg, __end, __intl, __io, __err, __str);
const int __n = numeric_limits<long double>::digits10;
- char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
+ char* __cs = static_cast<char*>(__builtin_alloca(__n));
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
const _CharT* __wcs = __str.c_str();
@@ -943,15 +1024,16 @@ namespace std
switch (__which)
{
case money_base::symbol:
- if (__io.flags() & ios_base::showbase
- || __i < 2
- || (__i == 2 && static_cast<part>(__p.field[3]) != money_base::none)
- || __sign.size() > 1)
+ if (__io.flags() & ios_base::showbase
+ || __i < 2 || __sign.size() > 1
+ || ((static_cast<part>(__p.field[3]) != money_base::none)
+ && __i == 2))
{
- // According to 22.2.6.1.2.2, symbol is required if
- // (__io.flags() & ios_base::showbase), otherwise is optional
- // and consumed only if other characters are needed to complete
- // the format.
+ // According to 22.2.6.1.2.2, symbol is required
+ // if (__io.flags() & ios_base::showbase),
+ // otherwise is optional and consumed only if
+ // other characters are needed to complete the
+ // format.
const string_type __symbol = __intl ? __mpt.curr_symbol()
: __mpf.curr_symbol();
size_type __len = __symbol.size();
@@ -962,7 +1044,8 @@ namespace std
__c = *(++__beg);
++__j;
}
- // When (__io.flags() & ios_base::showbase) symbol is required.
+ // When (__io.flags() & ios_base::showbase)
+ // symbol is required.
if (__j != __len && (__io.flags() & ios_base::showbase))
__testvalid = false;
}
@@ -1091,11 +1174,29 @@ namespace std
long double __units) const
{
const locale __loc = __io.getloc();
- const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
- const int __n = numeric_limits<long double>::digits10;
- char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
- _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
- int __len = __convert_from_v(__cs, "%.01Lf", __units, _S_c_locale);
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+#ifdef _GLIBCPP_USE_C99
+ // First try a buffer perhaps big enough.
+ int __cs_size = 64;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units,
+ _S_c_locale);
+ // If the buffer was not large enough, try again with the correct size.
+ if (__len >= __cs_size)
+ {
+ __cs_size = __len + 1;
+ __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units,
+ _S_c_locale);
+ }
+#else
+ // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
+ // decimal digit, '\0'.
+ const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
+#endif
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size));
__ctype.widen(__cs, __cs + __len, __ws);
string_type __digits(__ws);
return this->do_put(__s, __intl, __io, __fill, __digits);
@@ -1187,8 +1288,9 @@ namespace std
: __mpf.thousands_sep();
const char* __gbeg = __grouping.c_str();
const char* __gend = __gbeg + __grouping.size();
- const int __n = numeric_limits<long double>::digits10 * 2;
- _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
+ const int __n = (__end - __beg) * 2;
+ _CharT* __ws2 =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
_CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg,
__gend, __beg, __end);
__value.insert(0, __ws2, __ws_end - __ws2);
@@ -1513,7 +1615,7 @@ namespace std
const _CharT** __names, size_t __indexlen,
ios_base::iostate& __err) const
{
- typedef char_traits<char_type> __traits_type;
+ typedef char_traits<_CharT> __traits_type;
int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
size_t __nmatches = 0;
size_t __pos = 0;
@@ -1531,7 +1633,7 @@ namespace std
// Find smallest matching string.
size_t __minlen = 10;
for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
- __minlen = min(__minlen,
+ __minlen = min(__minlen,
__traits_type::length(__names[__matches[__i2]]));
if (__pos < __minlen && __beg != __end)
@@ -1608,7 +1710,7 @@ namespace std
do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
ios_base::iostate& __err, tm* __tm) const
{
- typedef char_traits<char_type> __traits_type;
+ typedef char_traits<_CharT> __traits_type;
locale __loc = __io.getloc();
__timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
const char_type* __days[7];
@@ -1651,7 +1753,7 @@ namespace std
do_get_monthname(iter_type __beg, iter_type __end,
ios_base& __io, ios_base::iostate& __err, tm* __tm) const
{
- typedef char_traits<char_type> __traits_type;
+ typedef char_traits<_CharT> __traits_type;
locale __loc = __io.getloc();
__timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
const char_type* __months[12];
@@ -1776,7 +1878,8 @@ namespace std
// NB: This size is arbitrary. Should this be a data member,
// initialized at construction?
const size_t __maxlen = 64;
- char_type* __res = static_cast<char_type*>(__builtin_alloca(__maxlen));
+ char_type* __res =
+ static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
// NB: In IEE 1003.1-200x, and perhaps other locale models, it
// is possible that the format character will be longer than one
@@ -1797,7 +1900,7 @@ namespace std
__fmt[3] = char_type();
}
- __tp._M_put_helper(__res, __maxlen, __fmt, __tm);
+ __tp._M_put(__res, __maxlen, __fmt, __tm);
// Write resulting, fully-formatted string to output iterator.
size_t __len = char_traits<char_type>::length(__res);
@@ -1810,13 +1913,13 @@ namespace std
// Generic version does nothing.
template<typename _CharT>
int
- collate<_CharT>::_M_compare_helper(const _CharT*, const _CharT*) const
+ collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
{ return 0; }
// Generic version does nothing.
template<typename _CharT>
size_t
- collate<_CharT>::_M_transform_helper(_CharT*, const _CharT*, size_t) const
+ collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
{ return 0; }
template<typename _CharT>
@@ -1827,7 +1930,7 @@ namespace std
{
const string_type __one(__lo1, __hi1);
const string_type __two(__lo2, __hi2);
- return _M_compare_helper(__one.c_str(), __two.c_str());
+ return _M_compare(__one.c_str(), __two.c_str());
}
template<typename _CharT>
@@ -1835,16 +1938,17 @@ namespace std
collate<_CharT>::
do_transform(const _CharT* __lo, const _CharT* __hi) const
{
- size_t __len = __hi - __lo;
- _CharT* __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
- size_t __res = _M_transform_helper(__c, __lo, __len);
+ size_t __len = (__hi - __lo) * 2;
+ // First try a buffer perhaps big enough.
+ _CharT* __c =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
+ size_t __res = _M_transform(__c, __lo, __len);
+ // If the buffer was not large enough, try again with the correct size.
if (__res >= __len)
{
- // Try to increment size of translated string.
- size_t __len2 = __len * 2;
- _CharT* __c2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len2));
- __res = _M_transform_helper(__c2, __lo, __len);
- // XXX Throw exception if still indeterminate?
+ __c =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1)));
+ _M_transform(__c, __lo, __res + 1);
}
return string_type(__c);
}
@@ -1870,20 +1974,12 @@ namespace std
const __c_locale& __cloc, int __base = 10);
// Convert numeric value of type _Tv to string and return length of string.
+ // If snprintf is available use it, otherwise fall back to the unsafe sprintf
+ // which, in general, can be dangerous and should be avoided.
template<typename _Tv>
int
- __convert_from_v(char* __out, const char* __fmt, _Tv __v,
- const __c_locale&, int __prec = -1)
- {
- int __ret;
- const char* __old = setlocale(LC_ALL, "C");
- if (__prec >= 0)
- __ret = sprintf(__out, __fmt, __prec, __v);
- else
- __ret = sprintf(__out, __fmt, __v);
- setlocale(LC_ALL, __old);
- return __ret;
- }
+ __convert_from_v(char* __out, const int __size, const char* __fmt,
+ _Tv __v, const __c_locale&, int __prec = -1);
// Construct correctly padded string, as per 22.2.2.2.2
// Assumes
@@ -1893,22 +1989,31 @@ namespace std
// internal-adjusted objects are padded according to the rules below
// concerning 0[xX] and +-, otherwise, exactly as right-adjusted
// ones are.
+
+ // NB: Of the two parameters, _CharT can be deduced from the
+ // function arguments. The other (_Traits) has to be explicitly specified.
template<typename _CharT, typename _Traits>
- void
- __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
- const streamsize __newlen, const streamsize __oldlen,
- const bool __num)
+ struct __pad
{
- typedef _CharT char_type;
- typedef _Traits traits_type;
- typedef typename traits_type::int_type int_type;
-
- int_type __plen = static_cast<size_t>(__newlen - __oldlen);
- char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
- traits_type::assign(__pads, __plen, __fill);
+ static void
+ _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
+ const _CharT* __olds, const streamsize __newlen,
+ const streamsize __oldlen, const bool __num);
+ };
- char_type* __beg;
- char_type* __end;
+ template<typename _CharT, typename _Traits>
+ void
+ __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
+ _CharT* __news, const _CharT* __olds,
+ const streamsize __newlen,
+ const streamsize __oldlen, const bool __num)
+ {
+ size_t __plen = static_cast<size_t>(__newlen - __oldlen);
+ _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __plen));
+ _Traits::assign(__pads, __plen, __fill);
+
+ _CharT* __beg;
+ _CharT* __end;
size_t __mod = 0;
size_t __beglen; //either __plen or __oldlen
ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
@@ -1916,7 +2021,7 @@ namespace std
if (__adjust == ios_base::left)
{
// Padding last.
- __beg = const_cast<char_type*>(__olds);
+ __beg = const_cast<_CharT*>(__olds);
__beglen = __oldlen;
__end = __pads;
}
@@ -1927,12 +2032,14 @@ namespace std
// Who came up with these rules, anyway? Jeeze.
locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
- const char_type __minus = __ctype.widen('-');
- const char_type __plus = __ctype.widen('+');
- bool __testsign = __olds[0] == __minus || __olds[0] == __plus;
- bool __testhex = __ctype.widen('0') == __olds[0]
- && (__ctype.widen('x') == __olds[1]
- || __ctype.widen('X') == __olds[1]);
+ const _CharT __minus = __ctype.widen('-');
+ const _CharT __plus = __ctype.widen('+');
+ bool __testsign = _Traits::eq(__olds[0], __minus)
+ || _Traits::eq(__olds[0], __plus);
+
+ bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0])
+ && (_Traits::eq(__ctype.widen('x'), __olds[1])
+ || _Traits::eq(__ctype.widen('X'), __olds[1]));
if (__testhex)
{
__news[0] = __olds[0];
@@ -1941,23 +2048,23 @@ namespace std
__news += 2;
__beg = __pads;
__beglen = __plen;
- __end = const_cast<char_type*>(__olds + __mod);
+ __end = const_cast<_CharT*>(__olds + __mod);
}
else if (__testsign)
{
- __news[0] = __olds[0] == __plus ? __plus : __minus;
+ _Traits::eq((__news[0] = __olds[0]), __plus) ? __plus : __minus;
++__mod;
++__news;
__beg = __pads;
__beglen = __plen;
- __end = const_cast<char_type*>(__olds + __mod);
+ __end = const_cast<_CharT*>(__olds + __mod);
}
else
{
// Padding first.
__beg = __pads;
__beglen = __plen;
- __end = const_cast<char_type*>(__olds);
+ __end = const_cast<_CharT*>(__olds);
}
}
else
@@ -1965,23 +2072,11 @@ namespace std
// Padding first.
__beg = __pads;
__beglen = __plen;
- __end = const_cast<char_type*>(__olds);
+ __end = const_cast<_CharT*>(__olds);
}
- traits_type::copy(__news, __beg, __beglen);
- traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
- }
-
- // NB: Can't have default argument on non-member template, and
- // num_put doesn't have a _Traits template parameter, so this
- // forwarding template adds in the default template argument.
- template<typename _CharT>
- void
- __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
- const streamsize __newlen, const streamsize __oldlen,
- const bool __num)
- {
- return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news, __olds,
- __newlen, __oldlen, __num);
+ _Traits::copy(__news, __beg, __beglen);
+ _Traits::copy(__news + __beglen, __end,
+ __newlen - __beglen - __mod);
}
// Used by both numeric and monetary facets.
@@ -2048,51 +2143,255 @@ namespace std
extern template class moneypunct<char, true>;
extern template class moneypunct_byname<char, false>;
extern template class moneypunct_byname<char, true>;
- extern template class money_get<char, istreambuf_iterator<char> >;
- extern template class money_put<char, ostreambuf_iterator<char> >;
+ extern template class money_get<char>;
+ extern template class money_put<char>;
+ extern template class numpunct<char>;
+ extern template class numpunct_byname<char>;
+ extern template class num_get<char>;
+ extern template class num_put<char>;
+ extern template class __timepunct<char>;
+ extern template class time_put<char>;
+ extern template class time_put_byname<char>;
+ extern template class time_get<char>;
+ extern template class time_get_byname<char>;
+ extern template class messages<char>;
+ extern template class messages_byname<char>;
+ extern template class ctype_byname<char>;
+ extern template class codecvt_byname<char, char, mbstate_t>;
+ extern template class collate<char>;
+ extern template class collate_byname<char>;
+
+ extern template
+ const codecvt<char, char, mbstate_t>&
+ use_facet<codecvt<char, char, mbstate_t> >(const locale&);
+
+ extern template
+ const collate<char>&
+ use_facet<collate<char> >(const locale&);
+
+ extern template
+ const numpunct<char>&
+ use_facet<numpunct<char> >(const locale&);
+
+ extern template
+ const num_put<char>&
+ use_facet<num_put<char> >(const locale&);
+
+ extern template
+ const num_get<char>&
+ use_facet<num_get<char> >(const locale&);
+
+ extern template
+ const moneypunct<char, true>&
+ use_facet<moneypunct<char, true> >(const locale&);
+
+ extern template
+ const moneypunct<char, false>&
+ use_facet<moneypunct<char, false> >(const locale&);
+
+ extern template
+ const money_put<char>&
+ use_facet<money_put<char> >(const locale&);
+
+ extern template
+ const money_get<char>&
+ use_facet<money_get<char> >(const locale&);
+
+ extern template
+ const __timepunct<char>&
+ use_facet<__timepunct<char> >(const locale&);
+
+ extern template
+ const time_put<char>&
+ use_facet<time_put<char> >(const locale&);
+
+ extern template
+ const time_get<char>&
+ use_facet<time_get<char> >(const locale&);
+
+ extern template
+ const messages<char>&
+ use_facet<messages<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<ctype<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<codecvt<char, char, mbstate_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<collate<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<numpunct<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_put<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_get<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<moneypunct<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<money_put<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<money_get<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<__timepunct<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<time_put<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<time_get<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<messages<char> >(const locale&);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
extern template class moneypunct<wchar_t, false>;
extern template class moneypunct<wchar_t, true>;
extern template class moneypunct_byname<wchar_t, false>;
extern template class moneypunct_byname<wchar_t, true>;
- extern template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
- extern template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
- extern template class numpunct<char>;
- extern template class numpunct_byname<char>;
- extern template class num_get<char, istreambuf_iterator<char> >;
- extern template class num_put<char, ostreambuf_iterator<char> >;
+ extern template class money_get<wchar_t>;
+ extern template class money_put<wchar_t>;
extern template class numpunct<wchar_t>;
extern template class numpunct_byname<wchar_t>;
- extern template class num_get<wchar_t, istreambuf_iterator<wchar_t> >;
- extern template class num_put<wchar_t, ostreambuf_iterator<wchar_t> >;
- extern template class __timepunct<char>;
- extern template class time_put<char, ostreambuf_iterator<char> >;
- extern template class time_put_byname<char, ostreambuf_iterator<char> >;
- extern template class time_get<char, istreambuf_iterator<char> >;
- extern template class time_get_byname<char, istreambuf_iterator<char> >;
+ extern template class num_get<wchar_t>;
+ extern template class num_put<wchar_t>;
extern template class __timepunct<wchar_t>;
- extern template class time_put<wchar_t, ostreambuf_iterator<wchar_t> >;
- extern template class time_put_byname<wchar_t, ostreambuf_iterator<wchar_t> >;
- extern template class time_get<wchar_t, istreambuf_iterator<wchar_t> >;
- extern template class time_get_byname<wchar_t, istreambuf_iterator<wchar_t> >;
- extern template class messages<char>;
- extern template class messages_byname<char>;
+ extern template class time_put<wchar_t>;
+ extern template class time_put_byname<wchar_t>;
+ extern template class time_get<wchar_t>;
+ extern template class time_get_byname<wchar_t>;
extern template class messages<wchar_t>;
extern template class messages_byname<wchar_t>;
- extern template class ctype_byname<char>;
extern template class ctype_byname<wchar_t>;
- extern template class codecvt_byname<char, char, mbstate_t>;
extern template class codecvt_byname<wchar_t, char, mbstate_t>;
- extern template class collate<char>;
- extern template class collate_byname<char>;
extern template class collate<wchar_t>;
extern template class collate_byname<wchar_t>;
-} // namespace std
-#endif
+ extern template
+ const codecvt<wchar_t, char, mbstate_t>&
+ use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
+
+ extern template
+ const collate<wchar_t>&
+ use_facet<collate<wchar_t> >(const locale&);
+
+ extern template
+ const numpunct<wchar_t>&
+ use_facet<numpunct<wchar_t> >(const locale&);
+
+ extern template
+ const num_put<wchar_t>&
+ use_facet<num_put<wchar_t> >(const locale&);
+
+ extern template
+ const num_get<wchar_t>&
+ use_facet<num_get<wchar_t> >(const locale&);
+
+ extern template
+ const moneypunct<wchar_t, true>&
+ use_facet<moneypunct<wchar_t, true> >(const locale&);
+
+ extern template
+ const moneypunct<wchar_t, false>&
+ use_facet<moneypunct<wchar_t, false> >(const locale&);
+
+ extern template
+ const money_put<wchar_t>&
+ use_facet<money_put<wchar_t> >(const locale&);
+
+ extern template
+ const money_get<wchar_t>&
+ use_facet<money_get<wchar_t> >(const locale&);
+
+ extern template
+ const __timepunct<wchar_t>&
+ use_facet<__timepunct<wchar_t> >(const locale&);
+
+ extern template
+ const time_put<wchar_t>&
+ use_facet<time_put<wchar_t> >(const locale&);
+
+ extern template
+ const time_get<wchar_t>&
+ use_facet<time_get<wchar_t> >(const locale&);
+
+ extern template
+ const messages<wchar_t>&
+ use_facet<messages<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<ctype<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<collate<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<numpunct<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_put<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_get<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<moneypunct<wchar_t> >(const locale&);
+ extern template
+ bool
+ has_facet<money_put<wchar_t> >(const locale&);
+ extern template
+ bool
+ has_facet<money_get<wchar_t> >(const locale&);
+ extern template
+ bool
+ has_facet<__timepunct<wchar_t> >(const locale&);
+ extern template
+ bool
+ has_facet<time_put<wchar_t> >(const locale&);
+ extern template
+ bool
+ has_facet<time_get<wchar_t> >(const locale&);
+ extern template
+ bool
+ has_facet<messages<wchar_t> >(const locale&);
+#endif
+} // namespace std
+#endif
diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h
index 172adae2e04..dedc7645236 100644
--- a/libstdc++-v3/include/bits/localefwd.h
+++ b/libstdc++-v3/include/bits/localefwd.h
@@ -46,23 +46,13 @@
#include <bits/c++locale.h> // Defines __c_locale, config-specific includes
#include <climits> // For CHAR_BIT
#include <cctype> // For isspace, etc.
-#include <string> // For string
+#include <string> // For string.
#include <bits/functexcept.h>
-
#include <bits/atomicity.h>
namespace std
{
- // NB: Don't instantiate required wchar_t facets if no wchar_t support.
-#ifdef _GLIBCPP_USE_WCHAR_T
-# define _GLIBCPP_NUM_FACETS 28
-#else
-# define _GLIBCPP_NUM_FACETS 14
-#endif
-
// 22.1.1 Locale
- template<typename _Tp, typename _Alloc>
- class vector;
class locale;
// 22.1.3 Convenience interfaces
@@ -217,8 +207,8 @@ namespace std
static const category time = 1L << 3;
static const category monetary = 1L << 4;
static const category messages = 1L << 5;
- static const category all = (collate | ctype | monetary |
- numeric | time | messages);
+ static const category all = (ctype | numeric | collate |
+ time | monetary | messages);
// Construct/copy/destroy:
locale() throw();
@@ -226,7 +216,7 @@ namespace std
locale(const locale& __other) throw();
explicit
- locale(const char* __std_name);
+ locale(const char* __s);
locale(const locale& __base, const char* __s, category __cat);
@@ -274,11 +264,29 @@ namespace std
// The "C" reference locale
static _Impl* _S_classic;
- // Current global reference locale
+ // Current global locale
static _Impl* _S_global;
- static const size_t _S_num_categories = 6;
- static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS;
+ // Number of standard categories. For C++, these categories are
+ // collate, ctype, monetary, numeric, time, and messages. These
+ // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
+ // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE
+ // 1003.1-2001) specifies LC_MESSAGES.
+ static const size_t _S_categories_size = 6;
+
+ // In addition to the standard categories, the underlying
+ // operating system is allowed to define extra LC_*
+ // macros. For GNU systems, the following are also valid:
+ // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT,
+ // and LC_IDENTIFICATION.
+ static const size_t _S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES;
+
+ // Names of underlying locale categories.
+ // NB: locale::global() has to know how to modify all the
+ // underlying categories, not just the ones required by the C++
+ // standard.
+ static const char* _S_categories[_S_categories_size
+ + _S_extra_categories_size];
explicit
locale(_Impl*) throw();
@@ -302,9 +310,6 @@ namespace std
class locale::_Impl
{
public:
- // Types.
- typedef vector<facet*, allocator<facet*> > __vec_facet;
-
// Friends.
friend class locale;
friend class locale::facet;
@@ -320,8 +325,11 @@ namespace std
private:
// Data Members.
_Atomic_word _M_references;
- __vec_facet* _M_facets;
- string _M_names[_S_num_categories];
+ facet** _M_facets;
+ size_t _M_facets_size;
+
+ char* _M_names[_S_categories_size
+ + _S_extra_categories_size];
static const locale::id* const _S_id_ctype[];
static const locale::id* const _S_id_numeric[];
static const locale::id* const _S_id_collate[];
@@ -347,15 +355,24 @@ namespace std
}
_Impl(const _Impl&, size_t);
- _Impl(string __name, size_t);
+ _Impl(const char*, size_t);
+ _Impl(facet**, size_t, bool);
+
~_Impl() throw();
+ _Impl(const _Impl&); // Not defined.
+
+ void
+ operator=(const _Impl&); // Not defined.
+
inline bool
_M_check_same_name()
{
bool __ret = true;
- for (size_t i = 0; i < _S_num_categories - 1; ++i)
- __ret &= _M_names[i] == _M_names[i + 1];
+ for (size_t __i = 0;
+ __ret && __i < _S_categories_size + _S_extra_categories_size - 1;
+ ++__i)
+ __ret &= (strcmp(_M_names[__i], _M_names[__i + 1]) == 0);
return __ret;
}
@@ -382,25 +399,33 @@ namespace std
{
_M_impl = new _Impl(*__other._M_impl, 1);
_M_impl->_M_install_facet(&_Facet::id, __f);
- for (size_t __i = 0; __i < _S_num_categories; ++__i)
- _M_impl->_M_names[__i] = "*";
+ for (size_t __i = 0;
+ __i < _S_categories_size + _S_extra_categories_size; ++__i)
+ {
+ delete [] _M_impl->_M_names[__i];
+ char* __new = new char[2];
+ strcpy(__new, "*");
+ _M_impl->_M_names[__i] = __new;
+ }
}
// 22.1.1.1.2 Class locale::facet
class locale::facet
{
+ private:
friend class locale;
friend class locale::_Impl;
- friend class __enc_traits;
- private:
_Atomic_word _M_references;
protected:
- // Contains data from the underlying "C" library for default "C"
- // or "POSIX" locale.
- static __c_locale _S_c_locale;
-
+ // Contains data from the underlying "C" library for for the
+ // classic locale.
+ static __c_locale _S_c_locale;
+
+ // String literal for the name of the classic locale.
+ static char _S_c_name[2];
+
explicit
facet(size_t __refs = 0) throw();
@@ -408,7 +433,8 @@ namespace std
~facet();
static void
- _S_create_c_locale(__c_locale& __cloc, const char* __s);
+ _S_create_c_locale(__c_locale& __cloc, const char* __s,
+ __c_locale __old = 0);
static __c_locale
_S_clone_c_locale(__c_locale& __cloc);
@@ -448,18 +474,26 @@ namespace std
// function (even an inline) would be undefined.
mutable size_t _M_index;
- // Last id number assigned
+ // Last id number assigned.
static _Atomic_word _S_highwater;
void
- operator=(const id&); // not defined
+ operator=(const id&); // Not defined.
- id(const id&); // not defined
+ id(const id&); // Not defined.
public:
// NB: This class is always a static data member, and thus can be
// counted on to be zero-initialized.
id();
+
+ inline size_t
+ _M_id() const
+ {
+ if (!_M_index)
+ _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
+ return _M_index - 1;
+ }
};
template<typename _Facet>
diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc
index 91c1b124805..e42eca29192 100644
--- a/libstdc++-v3/include/bits/ostream.tcc
+++ b/libstdc++-v3/include/bits/ostream.tcc
@@ -119,19 +119,11 @@ namespace std
basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin)
{
sentry __cerb(*this);
- if (__cerb)
+ if (__cerb && __sbin)
{
try
{
- streamsize __xtrct = 0;
- if (__sbin)
- {
- __streambuf_type* __sbout = this->rdbuf();
- __xtrct = __copy_streambufs(*this, __sbin, __sbout);
- }
- else
- this->setstate(ios_base::badbit);
- if (!__xtrct)
+ if (!__copy_streambufs(*this, __sbin, this->rdbuf()))
this->setstate(ios_base::failbit);
}
catch(exception& __fail)
@@ -143,6 +135,8 @@ namespace std
__throw_exception_again;
}
}
+ else if (!__sbin)
+ this->setstate(ios_base::badbit);
return *this;
}
@@ -185,7 +179,7 @@ namespace std
if (_M_check_facet(_M_fnumput))
{
bool __b = false;
- if (__fmt & ios_base::oct || __fmt & ios_base::hex)
+ if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
{
unsigned long __l = static_cast<unsigned long>(__n);
__b = _M_fnumput->put(*this, *this, __c, __l).failed();
@@ -248,7 +242,7 @@ namespace std
if (_M_check_facet(_M_fnumput))
{
bool __b = false;
- if (__fmt & ios_base::oct || __fmt & ios_base::hex)
+ if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
{
unsigned long long __l;
__l = static_cast<unsigned long long>(__n);
@@ -419,9 +413,7 @@ namespace std
basic_ostream<_CharT, _Traits>::tellp()
{
pos_type __ret = pos_type(-1);
- bool __testok = this->fail() != true;
-
- if (__testok)
+ if (!this->fail())
__ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
return __ret;
}
@@ -431,9 +423,7 @@ namespace std
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
{
- bool __testok = this->fail() != true;
-
- if (__testok)
+ if (!this->fail())
{
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
@@ -452,9 +442,7 @@ namespace std
basic_ostream<_CharT, _Traits>::
seekp(off_type __off, ios_base::seekdir __d)
{
- bool __testok = this->fail() != true;
-
- if (__testok)
+ if (!this->fail())
{
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
@@ -464,8 +452,8 @@ namespace std
// 129. Need error indication from seekp() and seekg()
if (__err == pos_type(off_type(-1)))
this->setstate(ios_base::failbit);
- }
#endif
+ }
return *this;
}
@@ -481,12 +469,13 @@ namespace std
try
{
streamsize __w = __out.width();
- _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
+ _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__w + 1)));
__pads[0] = __c;
streamsize __len = 1;
if (__w > __len)
{
- __pad(__out, __out.fill(), __pads, &__c, __w, __len, false);
+ __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads,
+ &__c, __w, __len, false);
__len = __w;
}
__out.write(__pads, __len);
@@ -521,7 +510,8 @@ namespace std
streamsize __len = 1;
if (__w > __len)
{
- __pad(__out, __out.fill(), __pads, &__c, __w, __len, false);
+ __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads,
+ &__c, __w, __len, false);
__len = __w;
}
__out.write(__pads, __len);
@@ -545,7 +535,7 @@ namespace std
{
typedef basic_ostream<_CharT, _Traits> __ostream_type;
typename __ostream_type::sentry __cerb(__out);
- if (__cerb)
+ if (__cerb && __s)
{
try
{
@@ -554,7 +544,8 @@ namespace std
streamsize __len = static_cast<streamsize>(_Traits::length(__s));
if (__w > __len)
{
- __pad(__out, __out.fill(), __pads, __s, __w, __len, false);
+ __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads,
+ __s, __w, __len, false);
__s = __pads;
__len = __w;
}
@@ -570,6 +561,8 @@ namespace std
__throw_exception_again;
}
}
+ else if (!__s)
+ __out.setstate(ios_base::badbit);
return __out;
}
@@ -581,14 +574,14 @@ namespace std
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 167. Improper use of traits_type::length()
// Note that this is only in 'Review' status.
- typedef char_traits<char> __ctraits_type;
+ typedef char_traits<char> __traits_type;
#endif
typename __ostream_type::sentry __cerb(__out);
- if (__cerb)
+ if (__cerb && __s)
{
- size_t __clen = __ctraits_type::length(__s);
+ size_t __clen = __traits_type::length(__s);
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__clen + 1)));
- for (size_t __i = 0; __i <= __clen; ++__i)
+ for (size_t __i = 0; __i < __clen; ++__i)
__ws[__i] = __out.widen(__s[__i]);
_CharT* __str = __ws;
@@ -600,7 +593,8 @@ namespace std
if (__w > __len)
{
- __pad(__out, __out.fill(), __pads, __ws, __w, __len, false);
+ __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads,
+ __ws, __w, __len, false);
__str = __pads;
__len = __w;
}
@@ -616,6 +610,8 @@ namespace std
__throw_exception_again;
}
}
+ else if (!__s)
+ __out.setstate(ios_base::badbit);
return __out;
}
@@ -626,16 +622,18 @@ namespace std
{
typedef basic_ostream<char, _Traits> __ostream_type;
typename __ostream_type::sentry __cerb(__out);
- if (__cerb)
+ if (__cerb && __s)
{
try
{
streamsize __w = __out.width();
char* __pads = static_cast<char*>(__builtin_alloca(__w));
streamsize __len = static_cast<streamsize>(_Traits::length(__s));
+
if (__w > __len)
{
- __pad(__out, __out.fill(), __pads, __s, __w, __len, false);
+ __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads,
+ __s, __w, __len, false);
__s = __pads;
__len = __w;
}
@@ -651,6 +649,8 @@ namespace std
__throw_exception_again;
}
}
+ else if (!__s)
+ __out.setstate(ios_base::badbit);
return __out;
}
@@ -673,7 +673,8 @@ namespace std
#endif
if (__w > __len)
{
- __pad(__out, __out.fill(), __pads, __s, __w, __len, false);
+ __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, __s,
+ __w, __len, false);
__s = __pads;
__len = __w;
}
@@ -699,6 +700,7 @@ namespace std
extern template ostream& operator<<(ostream&, const unsigned char*);
extern template ostream& operator<<(ostream&, const signed char*);
+#ifdef _GLIBCPP_USE_WCHAR_T
extern template class basic_ostream<wchar_t>;
extern template wostream& endl(wostream&);
extern template wostream& ends(wostream&);
@@ -707,4 +709,5 @@ namespace std
extern template wostream& operator<<(wostream&, char);
extern template wostream& operator<<(wostream&, const wchar_t*);
extern template wostream& operator<<(wostream&, const char*);
+#endif
} // namespace std
diff --git a/libstdc++-v3/include/bits/slice_array.h b/libstdc++-v3/include/bits/slice_array.h
index c8908f8bb53..cca3e63f0ae 100644
--- a/libstdc++-v3/include/bits/slice_array.h
+++ b/libstdc++-v3/include/bits/slice_array.h
@@ -120,7 +120,8 @@ namespace std
inline slice_array<_Tp>&
slice_array<_Tp>::operator=(const slice_array<_Tp>& __a)
{
- __valarray_copy(_M_array, _M_sz, _M_stride, __a._M_array, __a._M_stride);
+ __valarray_copy(__a._M_array, __a._M_sz, __a._M_stride,
+ _M_array, _M_stride);
return *this;
}
diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc
index f83bb697dcc..606705c02e9 100644
--- a/libstdc++-v3/include/bits/sstream.tcc
+++ b/libstdc++-v3/include/bits/sstream.tcc
@@ -95,13 +95,13 @@ namespace std
__len *= 2;
if (__testwrite)
- __ret = this->sputc(__c);
+ __ret = this->sputc(traits_type::to_char_type(__c));
else if (__len <= _M_string.max_size())
{
// Force-allocate, re-sync.
_M_string = this->str();
_M_string.reserve(__len);
- _M_buf_size = static_cast<int_type>(__len);
+ _M_buf_size = __len;
_M_really_sync(_M_in_cur - _M_in_beg,
_M_out_cur - _M_out_beg);
*_M_out_cur = traits_type::to_char_type(__c);
@@ -121,11 +121,13 @@ namespace std
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
- bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
- bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
+ bool __testin = (ios_base::in & _M_mode & __mode) != 0;
+ bool __testout = (ios_base::out & _M_mode & __mode) != 0;
bool __testboth = __testin && __testout && __way != ios_base::cur;
-
- if (_M_buf_size && ((__testin != __testout) || __testboth))
+ __testin &= !(__mode & ios_base::out);
+ __testout &= !(__mode & ios_base::in);
+
+ if (_M_buf_size && (__testin || __testout || __testboth))
{
char_type* __beg = _M_buf;
char_type* __curi = NULL;
@@ -133,12 +135,12 @@ namespace std
char_type* __endi = NULL;
char_type* __endo = NULL;
- if (__testin)
+ if (__testin || __testboth)
{
__curi = this->gptr();
__endi = this->egptr();
}
- if (__testout)
+ if (__testout || __testboth)
{
__curo = this->pptr();
__endo = this->epptr();
@@ -157,13 +159,13 @@ namespace std
__newoffo = __endo - __beg;
}
- if (__testin
+ if ((__testin || __testboth)
&& __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off)
{
_M_in_cur = __beg + __newoffi + __off;
__ret = pos_type(__newoffi);
}
- if (__testout
+ if ((__testout || __testboth)
&& __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off)
{
_M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg));
@@ -179,33 +181,44 @@ namespace std
seekpos(pos_type __sp, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
- off_type __pos = __sp._M_position();
- char_type* __beg = NULL;
- char_type* __end = NULL;
- bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
- bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
- if (__testin)
- {
- __beg = this->eback();
- __end = this->egptr();
- }
- if (__testout)
+ if (_M_buf_size)
{
- __beg = this->pbase();
- __end = _M_buf + _M_buf_size;
- }
-
- if (0 <= __pos && __pos <= __end - __beg)
- {
- // Need to set both of these if applicable
- if (__testin)
- _M_in_cur = _M_in_beg + __pos;
- if (__testout)
- _M_out_cur_move((__pos) - (_M_out_cur - __beg));
- __ret = pos_type(off_type(__pos));
+ off_type __pos = __sp; // Use streamoff operator to do conversion.
+ char_type* __beg = NULL;
+ char_type* __end = NULL;
+ bool __testin = (ios_base::in & _M_mode & __mode) != 0;
+ bool __testout = (ios_base::out & _M_mode & __mode) != 0;
+ bool __testboth = __testin && __testout;
+ __testin &= !(__mode & ios_base::out);
+ __testout &= !(__mode & ios_base::in);
+
+ // NB: Ordered.
+ bool __testposi = false;
+ bool __testposo = false;
+ if (__testin || __testboth)
+ {
+ __beg = this->eback();
+ __end = this->egptr();
+ if (0 <= __pos && __pos <= __end - __beg)
+ __testposi = true;
+ }
+ if (__testout || __testboth)
+ {
+ __beg = this->pbase();
+ __end = _M_buf + _M_buf_size;
+ if (0 <= __pos && __pos <= __end - __beg)
+ __testposo = true;
+ }
+ if (__testposi || __testposo)
+ {
+ if (__testposi)
+ _M_in_cur = _M_in_beg + __pos;
+ if (__testposo)
+ _M_out_cur_move((__pos) - (_M_out_cur - __beg));
+ __ret = pos_type(off_type(__pos));
+ }
}
-
return __ret;
}
@@ -213,13 +226,16 @@ namespace std
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
extern template class basic_stringbuf<char>;
- extern template class basic_stringbuf<wchar_t>;
extern template class basic_istringstream<char>;
- extern template class basic_istringstream<wchar_t>;
extern template class basic_ostringstream<char>;
- extern template class basic_ostringstream<wchar_t>;
extern template class basic_stringstream<char>;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ extern template class basic_stringbuf<wchar_t>;
+ extern template class basic_istringstream<wchar_t>;
+ extern template class basic_ostringstream<wchar_t>;
extern template class basic_stringstream<wchar_t>;
+#endif
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 1eee7b37b11..009c409b6fb 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -120,7 +120,7 @@ namespace std
__median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp)
{
// concept requirements
- __glibcpp_function_requires(_BinaryFunctionConcept<_Compare, bool, _Tp, _Tp>)
+ __glibcpp_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>)
if (__comp(__a, __b))
if (__comp(__b, __c))
return __b;
@@ -144,8 +144,7 @@ namespace std
* @return @p f.
*
* Applies the function object @p f to each element in the range
- * @p [first,last).
- * @p f must not modify its argument.
+ * @p [first,last). @p f must not modify the order of the sequence.
* If @p f has a return value it is ignored.
*/
template<typename _InputIter, typename _Function>
@@ -160,9 +159,9 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an overload used by find() for the Input Iterator case.
- * @endmaint
+ * @endif
*/
template<typename _InputIter, typename _Tp>
inline _InputIter
@@ -176,9 +175,9 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an overload used by find_if() for the Input Iterator case.
- * @endmaint
+ * @endif
*/
template<typename _InputIter, typename _Predicate>
inline _InputIter
@@ -192,9 +191,9 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an overload used by find() for the RAI case.
- * @endmaint
+ * @endif
*/
template<typename _RandomAccessIter, typename _Tp>
_RandomAccessIter
@@ -236,9 +235,9 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an overload used by find_if() for the RAI case.
- * @endmaint
+ * @endif
*/
template<typename _RandomAccessIter, typename _Predicate>
_RandomAccessIter
@@ -1088,10 +1087,10 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an uglified unique_copy(_InputIter, _InputIter, _OutputIter)
* overloaded for output iterators.
- * @endmaint
+ * @endif
*/
template<typename _InputIter, typename _OutputIter>
_OutputIter
@@ -1111,10 +1110,10 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an uglified unique_copy(_InputIter, _InputIter, _OutputIter)
* overloaded for forward iterators.
- * @endmaint
+ * @endif
*/
template<typename _InputIter, typename _ForwardIter>
_ForwardIter
@@ -1140,6 +1139,8 @@ namespace std
* Copies each element in the range @p [first,last) to the range
* beginning at @p result, except that only the first element is copied
* from groups of consecutive elements that compare equal.
+ * unique_copy() is stable, so the relative order of elements that are
+ * copied is unchanged.
*/
template<typename _InputIter, typename _OutputIter>
inline _OutputIter
@@ -1160,11 +1161,11 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an uglified
* unique_copy(_InputIter, _InputIter, _OutputIter, _BinaryPredicate)
* overloaded for output iterators.
- * @endmaint
+ * @endif
*/
template<typename _InputIter, typename _OutputIter, typename _BinaryPredicate>
_OutputIter
@@ -1189,11 +1190,11 @@ namespace std
}
/**
- * @maint
+ * @if maint
* This is an uglified
* unique_copy(_InputIter, _InputIter, _OutputIter, _BinaryPredicate)
* overloaded for forward iterators.
- * @endmaint
+ * @endif
*/
template<typename _InputIter, typename _ForwardIter, typename _BinaryPredicate>
_ForwardIter
@@ -1302,10 +1303,10 @@ __result, __binary_pred, _IterType());
}
/**
- * @maint
+ * @if maint
* This is an uglified reverse(_BidirectionalIter, _BidirectionalIter)
* overloaded for bidirectional iterators.
- * @endmaint
+ * @endif
*/
template<typename _BidirectionalIter>
void
@@ -1320,10 +1321,10 @@ __result, __binary_pred, _IterType());
}
/**
- * @maint
+ * @if maint
* This is an uglified reverse(_BidirectionalIter, _BidirectionalIter)
* overloaded for bidirectional iterators.
- * @endmaint
+ * @endif
*/
template<typename _RandomAccessIter>
void
@@ -1388,8 +1389,13 @@ __result, __binary_pred, _IterType());
return __result;
}
- /// This is a helper function for the rotate algorithm specialized on RAIs.
+ /**
+ * @if maint
+ * This is a helper function for the rotate algorithm specialized on RAIs.
+ * It returns the greatest common divisor of two integer values.
+ * @endif
+ */
template<typename _EuclideanRingElement>
_EuclideanRingElement
__gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
@@ -1402,6 +1408,11 @@ __result, __binary_pred, _IterType());
return __m;
}
+ /**
+ * @if maint
+ * This is a helper function for the rotate algorithm.
+ * @endif
+ */
template<typename _ForwardIter>
void
__rotate(_ForwardIter __first,
@@ -1430,6 +1441,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the rotate algorithm.
+ * @endif
+ */
template<typename _BidirectionalIter>
void
__rotate(_BidirectionalIter __first,
@@ -1458,6 +1474,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the rotate algorithm.
+ * @endif
+ */
template<typename _RandomAccessIter>
void
__rotate(_RandomAccessIter __first,
@@ -1519,6 +1540,24 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @brief Rotate the elements of a sequence.
+ * @param first A forward iterator.
+ * @param middle A forward iterator.
+ * @param last A forward iterator.
+ * @return Nothing.
+ *
+ * Rotates the elements of the range @p [first,last) by @p (middle-first)
+ * positions so that the element at @p middle is moved to @p first, the
+ * element at @p middle+1 is moved to @first+1 and so on for each element
+ * in the range @p [first,last).
+ *
+ * This effectively swaps the ranges @p [first,middle) and
+ * @p [middle,last).
+ *
+ * Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for
+ * each @p n in the range @p [0,last-first).
+ */
template<typename _ForwardIter>
inline void
rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last)
@@ -1530,6 +1569,23 @@ __result, __binary_pred, _IterType());
__rotate(__first, __middle, __last, _IterType());
}
+ /**
+ * @brief Copy a sequence, rotating its elements.
+ * @param first A forward iterator.
+ * @param middle A forward iterator.
+ * @param last A forward iterator.
+ * @param result An output iterator.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * Copies the elements of the range @p [first,last) to the range
+ * beginning at @result, rotating the copied elements by @p (middle-first)
+ * positions so that the element at @p middle is moved to @p result, the
+ * element at @p middle+1 is moved to @result+1 and so on for each element
+ * in the range @p [first,last).
+ *
+ * Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for
+ * each @p n in the range @p [0,last-first).
+ */
template<typename _ForwardIter, typename _OutputIter>
_OutputIter
rotate_copy(_ForwardIter __first, _ForwardIter __middle,
@@ -1543,9 +1599,16 @@ __result, __binary_pred, _IterType());
return copy(__first, __middle, copy(__middle, __last, __result));
}
- // Return a random number in the range [0, __n). This function encapsulates
- // whether we're using rand (part of the standard C library) or lrand48
- // (not standard, but a much better choice whenever it's available).
+
+ /**
+ * @if maint
+ * Return a random number in the range [0, __n). This function encapsulates
+ * whether we're using rand (part of the standard C library) or lrand48
+ * (not standard, but a much better choice whenever it's available).
+ *
+ * XXX There is no corresponding encapsulation fn to seed the generator.
+ * @endif
+ */
template<typename _Distance>
inline _Distance
__random_number(_Distance __n)
@@ -1557,8 +1620,17 @@ __result, __binary_pred, _IterType());
#endif
}
- /// 25.2.11 random_shuffle().
+ /**
+ * @brief Randomly shuffle the elements of a sequence.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @return Nothing.
+ *
+ * Reorder the elements in the range @p [first,last) using a random
+ * distribution, so that every possible ordering of the sequence is
+ * equally likely.
+ */
template<typename _RandomAccessIter>
inline void
random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last)
@@ -1572,6 +1644,19 @@ __result, __binary_pred, _IterType());
iter_swap(__i, __first + __random_number((__i - __first) + 1));
}
+ /**
+ * @brief Shuffle the elements of a sequence using a random number
+ * generator.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param rand The RNG functor or function.
+ * @return Nothing.
+ *
+ * Reorders the elements in the range @p [first,last) using @p rand to
+ * provide a random distribution. Calling @p rand(N) for a positive
+ * integer @p N should return a randomly chosen integer from the
+ * range [0,N).
+ */
template<typename _RandomAccessIter, typename _RandomNumberGenerator>
void
random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -1586,8 +1671,12 @@ __result, __binary_pred, _IterType());
iter_swap(__i, __first + __rand((__i - __first) + 1));
}
- // partition, stable_partition, and their auxiliary functions
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
template<typename _ForwardIter, typename _Predicate>
_ForwardIter
__partition(_ForwardIter __first, _ForwardIter __last,
@@ -1610,6 +1699,11 @@ __result, __binary_pred, _IterType());
return __first;
}
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
template<typename _BidirectionalIter, typename _Predicate>
_BidirectionalIter
__partition(_BidirectionalIter __first, _BidirectionalIter __last,
@@ -1637,6 +1731,20 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @brief Move elements for which a predicate is true to the beginning
+ * of a sequence.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param pred A predicate functor.
+ * @return An iterator @p middle such that @p pred(i) is true for each
+ * iterator @p i in the range @p [first,middle) and false for each @p i
+ * in the range @p [middle,last).
+ *
+ * @p pred must not modify its operand. @p partition() does not preserve
+ * the relative ordering of elements in each group, use
+ * @p stable_partition() if this is needed.
+ */
template<typename _ForwardIter, typename _Predicate>
inline _ForwardIter
partition(_ForwardIter __first, _ForwardIter __last,
@@ -1651,6 +1759,11 @@ __result, __binary_pred, _IterType());
}
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
template<typename _ForwardIter, typename _Predicate, typename _Distance>
_ForwardIter
__inplace_stable_partition(_ForwardIter __first, _ForwardIter __last,
@@ -1671,6 +1784,11 @@ __result, __binary_pred, _IterType());
return __begin;
}
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
template<typename _ForwardIter, typename _Pointer, typename _Predicate,
typename _Distance>
_ForwardIter
@@ -1711,6 +1829,22 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @brief Move elements for which a predicate is true to the beginning
+ * of a sequence, preserving relative ordering.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param pred A predicate functor.
+ * @return An iterator @p middle such that @p pred(i) is true for each
+ * iterator @p i in the range @p [first,middle) and false for each @p i
+ * in the range @p [middle,last).
+ *
+ * Performs the same function as @p partition() with the additional
+ * guarantee that the relative ordering of elements in each group is
+ * preserved, so any two elements @p x and @p y in the range
+ * @p [first,last) such that @p pred(x)==pred(y) will have the same
+ * relative ordering after calling @p stable_partition().
+ */
template<typename _ForwardIter, typename _Predicate>
_ForwardIter
stable_partition(_ForwardIter __first, _ForwardIter __last,
@@ -1739,6 +1873,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Tp>
_RandomAccessIter
__unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -1757,6 +1896,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Tp, typename _Compare>
_RandomAccessIter
__unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -1775,10 +1919,20 @@ __result, __binary_pred, _IterType());
}
}
- extern const int __stl_threshold;
- // sort() and its auxiliary functions.
+ /**
+ * @if maint
+ * @doctodo
+ * This controls some aspect of the sort routines.
+ * @endif
+ */
+ enum { _M_threshold = 16 };
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Tp>
void
__unguarded_linear_insert(_RandomAccessIter __last, _Tp __val)
@@ -1793,6 +1947,11 @@ __result, __binary_pred, _IterType());
*__last = __val;
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Tp, typename _Compare>
void
__unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, _Compare __comp)
@@ -1807,6 +1966,11 @@ __result, __binary_pred, _IterType());
*__last = __val;
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter>
void
__insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
@@ -1825,6 +1989,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Compare>
void
__insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -1844,6 +2013,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter>
inline void
__unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
@@ -1854,6 +2028,11 @@ __result, __binary_pred, _IterType());
__unguarded_linear_insert(__i, _ValueType(*__i));
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Compare>
inline void
__unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -1865,31 +2044,46 @@ __result, __binary_pred, _IterType());
__unguarded_linear_insert(__i, _ValueType(*__i), __comp);
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter>
void
__final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
{
- if (__last - __first > __stl_threshold) {
- __insertion_sort(__first, __first + __stl_threshold);
- __unguarded_insertion_sort(__first + __stl_threshold, __last);
+ if (__last - __first > _M_threshold) {
+ __insertion_sort(__first, __first + _M_threshold);
+ __unguarded_insertion_sort(__first + _M_threshold, __last);
}
else
__insertion_sort(__first, __last);
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Compare>
void
__final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
_Compare __comp)
{
- if (__last - __first > __stl_threshold) {
- __insertion_sort(__first, __first + __stl_threshold, __comp);
- __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
+ if (__last - __first > _M_threshold) {
+ __insertion_sort(__first, __first + _M_threshold, __comp);
+ __unguarded_insertion_sort(__first + _M_threshold, __last, __comp);
}
else
__insertion_sort(__first, __last, __comp);
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _Size>
inline _Size
__lg(_Size __n)
@@ -1899,6 +2093,11 @@ __result, __binary_pred, _IterType());
return __k;
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Size>
void
__introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -1906,7 +2105,7 @@ __result, __binary_pred, _IterType());
{
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
- while (__last - __first > __stl_threshold) {
+ while (__last - __first > _M_threshold) {
if (__depth_limit == 0) {
partial_sort(__first, __last, __last);
return;
@@ -1922,6 +2121,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Size, typename _Compare>
void
__introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -1929,7 +2133,7 @@ __result, __binary_pred, _IterType());
{
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
- while (__last - __first > __stl_threshold) {
+ while (__last - __first > _M_threshold) {
if (__depth_limit == 0) {
partial_sort(__first, __last, __last, __comp);
return;
@@ -1946,6 +2150,19 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @brief Sort the elements of a sequence.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @return Nothing.
+ *
+ * Sorts the elements in the range @p [first,last) in ascending order,
+ * such that @p *(i+1)<*i is false for each iterator @p i in the range
+ * @p [first,last-1).
+ *
+ * The relative ordering of equivalent elements is not preserved, use
+ * @p stable_sort() if this is needed.
+ */
template<typename _RandomAccessIter>
inline void
sort(_RandomAccessIter __first, _RandomAccessIter __last)
@@ -1963,6 +2180,20 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @brief Sort the elements of a sequence using a predicate for comparison.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param comp A comparison functor.
+ * @return Nothing.
+ *
+ * Sorts the elements in the range @p [first,last) in ascending order,
+ * such that @p comp(*(i+1),*i) is false for every iterator @p i in the
+ * range @p [first,last-1).
+ *
+ * The relative ordering of equivalent elements is not preserved, use
+ * @p stable_sort() if this is needed.
+ */
template<typename _RandomAccessIter, typename _Compare>
inline void
sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp)
@@ -1980,8 +2211,12 @@ __result, __binary_pred, _IterType());
}
}
- // stable_sort() and its auxiliary functions.
+ /**
+ * @if maint
+ * This is a helper function for the stable sorting routines.
+ * @endif
+ */
template<typename _RandomAccessIter>
void
__inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last)
@@ -1998,6 +2233,11 @@ __result, __binary_pred, _IterType());
__last - __middle);
}
+ /**
+ * @if maint
+ * This is a helper function for the stable sorting routines.
+ * @endif
+ */
template<typename _RandomAccessIter, typename _Compare>
void
__inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last,
@@ -2060,7 +2300,7 @@ __result, __binary_pred, _IterType());
__comp);
}
- extern const int __stl_chunk_size;
+ enum { _M_chunk_size = 7 };
template<typename _RandomAccessIter, typename _Distance>
void
@@ -2096,7 +2336,7 @@ __result, __binary_pred, _IterType());
_Distance __len = __last - __first;
_Pointer __buffer_last = __buffer + __len;
- _Distance __step_size = __stl_chunk_size;
+ _Distance __step_size = _M_chunk_size;
__chunk_insertion_sort(__first, __last, __step_size);
while (__step_size < __len) {
@@ -2117,7 +2357,7 @@ __result, __binary_pred, _IterType());
_Distance __len = __last - __first;
_Pointer __buffer_last = __buffer + __len;
- _Distance __step_size = __stl_chunk_size;
+ _Distance __step_size = _M_chunk_size;
__chunk_insertion_sort(__first, __last, __step_size, __comp);
while (__step_size < __len) {
@@ -2171,6 +2411,22 @@ __result, __binary_pred, _IterType());
__comp);
}
+ /**
+ * @brief Sort the elements of a sequence, preserving the relative order
+ * of equivalent elements.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @return Nothing.
+ *
+ * Sorts the elements in the range @p [first,last) in ascending order,
+ * such that @p *(i+1)<*i is false for each iterator @p i in the range
+ * @p [first,last-1).
+ *
+ * The relative ordering of equivalent elements is preserved, so any two
+ * elements @p x and @p y in the range @p [first,last) such that
+ * @p x<y is false and @p y<x is false will have the same relative
+ * ordering after calling @p stable_sort().
+ */
template<typename _RandomAccessIter>
inline void
stable_sort(_RandomAccessIter __first, _RandomAccessIter __last)
@@ -2190,6 +2446,23 @@ __result, __binary_pred, _IterType());
__stable_sort_adaptive(__first, __last, buf.begin(), _DistanceType(buf.size()));
}
+ /**
+ * @brief Sort the elements of a sequence using a predicate for comparison,
+ * preserving the relative order of equivalent elements.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param comp A comparison functor.
+ * @return Nothing.
+ *
+ * Sorts the elements in the range @p [first,last) in ascending order,
+ * such that @p comp(*(i+1),*i) is false for each iterator @p i in the
+ * range @p [first,last-1).
+ *
+ * The relative ordering of equivalent elements is preserved, so any two
+ * elements @p x and @p y in the range @p [first,last) such that
+ * @p comp(x,y) is false and @p comp(y,x) is false will have the same
+ * relative ordering after calling @p stable_sort().
+ */
template<typename _RandomAccessIter, typename _Compare>
inline void
stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp)
@@ -2211,6 +2484,21 @@ __result, __binary_pred, _IterType());
__comp);
}
+ /**
+ * @brief Sort the smallest elements of a sequence.
+ * @param first An iterator.
+ * @param middle Another iterator.
+ * @param last Another iterator.
+ * @return Nothing.
+ *
+ * Sorts the smallest @p (middle-first) elements in the range
+ * @p [first,last) and moves them to the range @p [first,middle). The
+ * order of the remaining elements in the range @p [middle,last) is
+ * undefined.
+ * After the sort if @p i and @j are iterators in the range
+ * @p [first,middle) such that @i precedes @j and @k is an iterator in
+ * the range @p [middle,last) then @p *j<*i and @p *k<*i are both false.
+ */
template<typename _RandomAccessIter>
void
partial_sort(_RandomAccessIter __first,
@@ -2231,6 +2519,24 @@ __result, __binary_pred, _IterType());
sort_heap(__first, __middle);
}
+ /**
+ * @brief Sort the smallest elements of a sequence using a predicate
+ * for comparison.
+ * @param first An iterator.
+ * @param middle Another iterator.
+ * @param last Another iterator.
+ * @param comp A comparison functor.
+ * @return Nothing.
+ *
+ * Sorts the smallest @p (middle-first) elements in the range
+ * @p [first,last) and moves them to the range @p [first,middle). The
+ * order of the remaining elements in the range @p [middle,last) is
+ * undefined.
+ * After the sort if @p i and @j are iterators in the range
+ * @p [first,middle) such that @i precedes @j and @k is an iterator in
+ * the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i)
+ * are both false.
+ */
template<typename _RandomAccessIter, typename _Compare>
void
partial_sort(_RandomAccessIter __first,
@@ -2253,6 +2559,23 @@ __result, __binary_pred, _IterType());
sort_heap(__first, __middle, __comp);
}
+ /**
+ * @brief Copy the smallest elements of a sequence.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param result_first A random-access iterator.
+ * @param result_last Another random-access iterator.
+ * @return An iterator indicating the end of the resulting sequence.
+ *
+ * Copies and sorts the smallest N values from the range @p [first,last)
+ * to the range beginning at @p result_first, where the number of
+ * elements to be copied, @p N, is the smaller of @p (last-first) and
+ * @p (result_last-result_first).
+ * After the sort if @p i and @j are iterators in the range
+ * @p [result_first,result_first+N) such that @i precedes @j then
+ * @p *j<*i is false.
+ * The value returned is @p result_first+N.
+ */
template<typename _InputIter, typename _RandomAccessIter>
_RandomAccessIter
partial_sort_copy(_InputIter __first, _InputIter __last,
@@ -2288,6 +2611,25 @@ __result, __binary_pred, _IterType());
return __result_real_last;
}
+ /**
+ * @brief Copy the smallest elements of a sequence using a predicate for
+ * comparison.
+ * @param first An input iterator.
+ * @param last Another input iterator.
+ * @param result_first A random-access iterator.
+ * @param result_last Another random-access iterator.
+ * @param comp A comparison functor.
+ * @return An iterator indicating the end of the resulting sequence.
+ *
+ * Copies and sorts the smallest N values from the range @p [first,last)
+ * to the range beginning at @p result_first, where the number of
+ * elements to be copied, @p N, is the smaller of @p (last-first) and
+ * @p (result_last-result_first).
+ * After the sort if @p i and @j are iterators in the range
+ * @p [result_first,result_first+N) such that @i precedes @j then
+ * @p comp(*j,*i) is false.
+ * The value returned is @p result_first+N.
+ */
template<typename _InputIter, typename _RandomAccessIter, typename _Compare>
_RandomAccessIter
partial_sort_copy(_InputIter __first, _InputIter __last,
@@ -2326,6 +2668,21 @@ __result, __binary_pred, _IterType());
return __result_real_last;
}
+ /**
+ * @brief Sort a sequence just enough to find a particular position.
+ * @param first An iterator.
+ * @param nth Another iterator.
+ * @param last Another iterator.
+ * @return Nothing.
+ *
+ * Rearranges the elements in the range @p [first,last) so that @p *nth
+ * is the same element that would have been in that position had the
+ * whole sequence been sorted.
+ * whole sequence been sorted. The elements either side of @p *nth are
+ * not completely sorted, but for any iterator @i in the range
+ * @p [first,nth) and any iterator @j in the range @p [nth,last) it
+ * holds that @p *j<*i is false.
+ */
template<typename _RandomAccessIter>
void
nth_element(_RandomAccessIter __first,
@@ -2352,6 +2709,22 @@ __result, __binary_pred, _IterType());
__insertion_sort(__first, __last);
}
+ /**
+ * @brief Sort a sequence just enough to find a particular position
+ * using a predicate for comparison.
+ * @param first An iterator.
+ * @param nth Another iterator.
+ * @param last Another iterator.
+ * @param comp A comparison functor.
+ * @return Nothing.
+ *
+ * Rearranges the elements in the range @p [first,last) so that @p *nth
+ * is the same element that would have been in that position had the
+ * whole sequence been sorted. The elements either side of @p *nth are
+ * not completely sorted, but for any iterator @i in the range
+ * @p [first,nth) and any iterator @j in the range @p [nth,last) it
+ * holds that @p comp(*j,*i) is false.
+ */
template<typename _RandomAccessIter, typename _Compare>
void
nth_element(_RandomAccessIter __first,
@@ -2383,8 +2756,15 @@ __result, __binary_pred, _IterType());
}
- // Binary search (lower_bound, upper_bound, equal_range, binary_search).
-
+ /**
+ * @brief Finds the first position in which @a val could be inserted
+ * without changing the ordering.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @return An iterator pointing to the first element "not less than" @a val.
+ * @ingroup binarysearch
+ */
template<typename _ForwardIter, typename _Tp>
_ForwardIter
lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val)
@@ -2420,6 +2800,19 @@ __result, __binary_pred, _IterType());
return __first;
}
+ /**
+ * @brief Finds the first position in which @a val could be inserted
+ * without changing the ordering.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @param comp A functor to use for comparisons.
+ * @return An iterator pointing to the first element "not less than" @a val.
+ * @ingroup binarysearch
+ *
+ * The comparison function should have the same effects on ordering as
+ * the function used for the initial sort.
+ */
template<typename _ForwardIter, typename _Tp, typename _Compare>
_ForwardIter
lower_bound(_ForwardIter __first, _ForwardIter __last,
@@ -2451,6 +2844,15 @@ __result, __binary_pred, _IterType());
return __first;
}
+ /**
+ * @brief Finds the last position in which @a val could be inserted
+ * without changing the ordering.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @return An iterator pointing to the first element greater than @a val.
+ * @ingroup binarysearch
+ */
template<typename _ForwardIter, typename _Tp>
_ForwardIter
upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val)
@@ -2483,6 +2885,19 @@ __result, __binary_pred, _IterType());
return __first;
}
+ /**
+ * @brief Finds the last position in which @a val could be inserted
+ * without changing the ordering.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @param comp A functor to use for comparisons.
+ * @return An iterator pointing to the first element greater than @a val.
+ * @ingroup binarysearch
+ *
+ * The comparison function should have the same effects on ordering as
+ * the function used for the initial sort.
+ */
template<typename _ForwardIter, typename _Tp, typename _Compare>
_ForwardIter
upper_bound(_ForwardIter __first, _ForwardIter __last,
@@ -2514,6 +2929,22 @@ __result, __binary_pred, _IterType());
return __first;
}
+ /**
+ * @brief Finds the largest subrange in which @a val could be inserted
+ * at any place in it without changing the ordering.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @return An pair of iterators defining the subrange.
+ * @ingroup binarysearch
+ *
+ * This is equivalent to
+ * @code
+ * std::make_pair(lower_bound(first, last, val),
+ * upper_bound(first, last, val))
+ * @endcode
+ * but does not actually call those functions.
+ */
template<typename _ForwardIter, typename _Tp>
pair<_ForwardIter, _ForwardIter>
equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val)
@@ -2552,6 +2983,23 @@ __result, __binary_pred, _IterType());
return pair<_ForwardIter, _ForwardIter>(__first, __first);
}
+ /**
+ * @brief Finds the largest subrange in which @a val could be inserted
+ * at any place in it without changing the ordering.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @param comp A functor to use for comparisons.
+ * @return An pair of iterators defining the subrange.
+ * @ingroup binarysearch
+ *
+ * This is equivalent to
+ * @code
+ * std::make_pair(lower_bound(first, last, val, comp),
+ * upper_bound(first, last, val, comp))
+ * @endcode
+ * but does not actually call those functions.
+ */
template<typename _ForwardIter, typename _Tp, typename _Compare>
pair<_ForwardIter, _ForwardIter>
equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
@@ -2590,6 +3038,17 @@ __result, __binary_pred, _IterType());
return pair<_ForwardIter, _ForwardIter>(__first, __first);
}
+ /**
+ * @brief Determines whether an element exists in a range.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @return True if @a val (or its equivelent) is in [@a first,@a last ].
+ * @ingroup binarysearch
+ *
+ * Note that this does not actually return an iterator to @a val. For
+ * that, use std::find or a container's specialized find member functions.
+ */
template<typename _ForwardIter, typename _Tp>
bool
binary_search(_ForwardIter __first, _ForwardIter __last,
@@ -2606,6 +3065,21 @@ __result, __binary_pred, _IterType());
return __i != __last && !(__val < *__i);
}
+ /**
+ * @brief Determines whether an element exists in a range.
+ * @param first An iterator.
+ * @param last Another iterator.
+ * @param val The search term.
+ * @param comp A functor to use for comparisons.
+ * @return True if @a val (or its equivelent) is in [@a first,@a last ].
+ * @ingroup binarysearch
+ *
+ * Note that this does not actually return an iterator to @a val. For
+ * that, use std::find or a container's specialized find member functions.
+ *
+ * The comparison function should have the same effects on ordering as
+ * the function used for the initial sort.
+ */
template<typename _ForwardIter, typename _Tp, typename _Compare>
bool
binary_search(_ForwardIter __first, _ForwardIter __last,
@@ -2622,8 +3096,22 @@ __result, __binary_pred, _IterType());
return __i != __last && !__comp(__val, *__i);
}
- // merge, with and without an explicitly supplied comparison function.
-
+ /**
+ * @brief Merges two sorted ranges.
+ * @param first1 An iterator.
+ * @param first2 Another iterator.
+ * @param last1 Another iterator.
+ * @param last2 Another iterator.
+ * @param result An iterator pointing to the end of the merged range.
+ * @return An iterator pointing to the first element "not less than" @a val.
+ *
+ * Merges the ranges [first1,last1) and [first2,last2) into the sorted range
+ * [result, result + (last1-first1) + (last2-first2)). Both input ranges
+ * must be sorted, and the output range must not overlap with either of
+ * the input ranges. The sort is @e stable, that is, for equivalent
+ * elements in the two ranges, elements from the first range will always
+ * come before elements from the second.
+ */
template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
_OutputIter
merge(_InputIter1 __first1, _InputIter1 __last1,
@@ -2655,6 +3143,26 @@ __result, __binary_pred, _IterType());
return copy(__first2, __last2, copy(__first1, __last1, __result));
}
+ /**
+ * @brief Merges two sorted ranges.
+ * @param first1 An iterator.
+ * @param first2 Another iterator.
+ * @param last1 Another iterator.
+ * @param last2 Another iterator.
+ * @param result An iterator pointing to the end of the merged range.
+ * @param comp A functor to use for comparisons.
+ * @return An iterator pointing to the first element "not less than" @a val.
+ *
+ * Merges the ranges [first1,last1) and [first2,last2) into the sorted range
+ * [result, result + (last1-first1) + (last2-first2)). Both input ranges
+ * must be sorted, and the output range must not overlap with either of
+ * the input ranges. The sort is @e stable, that is, for equivalent
+ * elements in the two ranges, elements from the first range will always
+ * come before elements from the second.
+ *
+ * The comparison function should have the same effects on ordering as
+ * the function used for the initial sort.
+ */
template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
typename _Compare>
_OutputIter
@@ -2688,8 +3196,11 @@ __result, __binary_pred, _IterType());
return copy(__first2, __last2, copy(__first1, __last1, __result));
}
- // inplace_merge and its auxiliary functions.
-
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
template<typename _BidirectionalIter, typename _Distance>
void
__merge_without_buffer(_BidirectionalIter __first,
@@ -2729,6 +3240,11 @@ __result, __binary_pred, _IterType());
__len1 - __len11, __len2 - __len22);
}
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
template<typename _BidirectionalIter, typename _Distance, typename _Compare>
void
__merge_without_buffer(_BidirectionalIter __first,
@@ -2769,6 +3285,11 @@ __result, __binary_pred, _IterType());
__len1 - __len11, __len2 - __len22, __comp);
}
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
template<typename _BidirectionalIter1, typename _BidirectionalIter2,
typename _Distance>
_BidirectionalIter1
@@ -2797,6 +3318,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
template<typename _BidirectionalIter1, typename _BidirectionalIter2,
typename _BidirectionalIter3>
_BidirectionalIter3
@@ -2826,6 +3352,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
template<typename _BidirectionalIter1, typename _BidirectionalIter2,
typename _BidirectionalIter3, typename _Compare>
_BidirectionalIter3
@@ -2856,6 +3387,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
template<typename _BidirectionalIter, typename _Distance, typename _Pointer>
void
__merge_adaptive(_BidirectionalIter __first,
@@ -2900,6 +3436,11 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
template<typename _BidirectionalIter, typename _Distance, typename _Pointer,
typename _Compare>
void
@@ -2947,6 +3488,23 @@ __result, __binary_pred, _IterType());
}
}
+ /**
+ * @brief Merges two sorted ranges in place.
+ * @param first An iterator.
+ * @param middle Another iterator.
+ * @param last Another iterator.
+ * @return Nothing.
+ *
+ * Merges two sorted and consecutive ranges, [first,middle) and
+ * [middle,last), and puts the result in [first,last). The output will
+ * be sorted. The sort is @e stable, that is, for equivalent
+ * elements in the two ranges, elements from the first range will always
+ * come before elements from the second.
+ *
+ * If enough additional memory is available, this takes (last-first)-1
+ * comparisons. Otherwise an NlogN algorithm is used, where N is
+ * distance(first,last).
+ */
template<typename _BidirectionalIter>
void
inplace_merge(_BidirectionalIter __first,
@@ -2977,6 +3535,27 @@ __result, __binary_pred, _IterType());
__buf.begin(), _DistanceType(__buf.size()));
}
+ /**
+ * @brief Merges two sorted ranges in place.
+ * @param first An iterator.
+ * @param middle Another iterator.
+ * @param last Another iterator.
+ * @param comp A functor to use for comparisons.
+ * @return Nothing.
+ *
+ * Merges two sorted and consecutive ranges, [first,middle) and
+ * [middle,last), and puts the result in [first,last). The output will
+ * be sorted. The sort is @e stable, that is, for equivalent
+ * elements in the two ranges, elements from the first range will always
+ * come before elements from the second.
+ *
+ * If enough additional memory is available, this takes (last-first)-1
+ * comparisons. Otherwise an NlogN algorithm is used, where N is
+ * distance(first,last).
+ *
+ * The comparison function should have the same effects on ordering as
+ * the function used for the initial sort.
+ */
template<typename _BidirectionalIter, typename _Compare>
void
inplace_merge(_BidirectionalIter __first,
diff --git a/libstdc++-v3/include/bits/stl_alloc.h b/libstdc++-v3/include/bits/stl_alloc.h
index 7a4d9e9e4a6..238986d7eeb 100644
--- a/libstdc++-v3/include/bits/stl_alloc.h
+++ b/libstdc++-v3/include/bits/stl_alloc.h
@@ -50,7 +50,7 @@
/**
* @defgroup Allocators Memory Allocators
- * @maint
+ * @if maint
* stl_alloc.h implements some node allocators. These are NOT the same as
* allocators in the C++ standard, nor in the original H-P STL. They do not
* encapsulate different pointer types; we assume that there is only one
@@ -72,7 +72,11 @@
*
* "SGI" allocators may be wrapped in __allocator to convert the interface
* into a "standard" one.
- * @endmaint
+ * @endif
+ *
+ * @note The @c reallocate member functions have been deprecated for 3.2
+ * and will be removed in 3.4. You must define @c _GLIBCPP_DEPRECATED
+ * to make this visible in 3.2; see c++config.h.
*
* The canonical description of these classes is in docs/html/ext/howto.html
* or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3
@@ -85,157 +89,172 @@
#include <bits/functexcept.h> // For __throw_bad_alloc
#include <bits/stl_threads.h>
+#include <bits/atomicity.h>
+
namespace std
{
/**
- * @maint
+ * @if maint
* A new-based allocator, as required by the standard. Allocation and
* deallocation forward to global new and delete. "SGI" style, minus
* reallocate().
- * @endmaint
+ * @endif
* (See @link Allocators allocators info @endlink for more.)
- */
- class __new_alloc
+ */
+ class __new_alloc
{
public:
- static void*
+ static void*
allocate(size_t __n)
{ return ::operator new(__n); }
-
- static void
+
+ static void
deallocate(void* __p, size_t)
{ ::operator delete(__p); }
};
-
+
/**
- * @maint
+ * @if maint
* A malloc-based allocator. Typically slower than the
* __default_alloc_template (below). Typically thread-safe and more
* storage efficient. The template argument is unused and is only present
* to permit multiple instantiations (but see __default_alloc_template
* for caveats). "SGI" style, plus __set_malloc_handler for OOM conditions.
- * @endmaint
+ * @endif
* (See @link Allocators allocators info @endlink for more.)
- */
- template <int __inst>
- class __malloc_alloc_template
+ */
+ template<int __inst>
+ class __malloc_alloc_template
{
private:
static void* _S_oom_malloc(size_t);
+
+ // _GLIBCPP_DEPRECATED
static void* _S_oom_realloc(void*, size_t);
+
static void (* __malloc_alloc_oom_handler)();
-
+
public:
- static void*
+ static void*
allocate(size_t __n)
{
- void* __result = malloc(__n);
- if (0 == __result) __result = _S_oom_malloc(__n);
- return __result;
+ void* __result = malloc(__n);
+ if (__builtin_expect(__result == 0, 0))
+ __result = _S_oom_malloc(__n);
+ return __result;
}
- static void
+ static void
deallocate(void* __p, size_t /* __n */)
{ free(__p); }
- static void*
+ // _GLIBCPP_DEPRECATED
+ static void*
reallocate(void* __p, size_t /* old_sz */, size_t __new_sz)
{
- void* __result = realloc(__p, __new_sz);
- if (0 == __result) __result = _S_oom_realloc(__p, __new_sz);
- return __result;
+ void* __result = realloc(__p, __new_sz);
+ if (__builtin_expect(__result == 0, 0))
+ __result = _S_oom_realloc(__p, __new_sz);
+ return __result;
}
-
+
static void (* __set_malloc_handler(void (*__f)()))()
{
- void (* __old)() = __malloc_alloc_oom_handler;
- __malloc_alloc_oom_handler = __f;
- return(__old);
+ void (* __old)() = __malloc_alloc_oom_handler;
+ __malloc_alloc_oom_handler = __f;
+ return __old;
}
};
// malloc_alloc out-of-memory handling
- template <int __inst>
+ template<int __inst>
void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0;
- template <int __inst>
+ template<int __inst>
void*
- __malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n)
+ __malloc_alloc_template<__inst>::
+ _S_oom_malloc(size_t __n)
{
void (* __my_malloc_handler)();
void* __result;
-
- for (;;)
- {
- __my_malloc_handler = __malloc_alloc_oom_handler;
- if (0 == __my_malloc_handler)
- std::__throw_bad_alloc();
- (*__my_malloc_handler)();
- __result = malloc(__n);
- if (__result)
- return(__result);
- }
+
+ for (;;)
+ {
+ __my_malloc_handler = __malloc_alloc_oom_handler;
+ if (__builtin_expect(__my_malloc_handler == 0, 0))
+ __throw_bad_alloc();
+ (*__my_malloc_handler)();
+ __result = malloc(__n);
+ if (__result)
+ return __result;
+ }
}
-
- template <int __inst>
- void*
- __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n)
- {
+
+ // _GLIBCPP_DEPRECATED
+ template<int __inst>
+ void*
+ __malloc_alloc_template<__inst>::
+ _S_oom_realloc(void* __p, size_t __n)
+ {
void (* __my_malloc_handler)();
void* __result;
-
- for (;;)
- {
- __my_malloc_handler = __malloc_alloc_oom_handler;
- if (0 == __my_malloc_handler)
- std::__throw_bad_alloc();
- (*__my_malloc_handler)();
- __result = realloc(__p, __n);
- if (__result)
- return(__result);
- }
- }
+ for (;;)
+ {
+ __my_malloc_handler = __malloc_alloc_oom_handler;
+ if (__builtin_expect(__my_malloc_handler == 0, 0))
+ __throw_bad_alloc();
+ (*__my_malloc_handler)();
+ __result = realloc(__p, __n);
+ if (__result)
+ return __result;
+ }
+ }
-// Determines the underlying allocator choice for the node allocator.
-#ifdef __USE_MALLOC
- typedef __malloc_alloc_template<0> __mem_interface;
-#else
+ // Should not be referenced within the library anymore.
typedef __new_alloc __mem_interface;
-#endif
-
/**
- * @maint
+ * @if maint
* This is used primarily (only?) in _Alloc_traits and other places to
- * help provide the _Alloc_type typedef.
+ * help provide the _Alloc_type typedef. All it does is forward the
+ * requests after some minimal checking.
*
* This is neither "standard"-conforming nor "SGI". The _Alloc parameter
* must be "SGI" style.
- * @endmaint
+ * @endif
* (See @link Allocators allocators info @endlink for more.)
- */
- template<class _Tp, class _Alloc>
- class __simple_alloc
- {
- public:
- static _Tp* allocate(size_t __n)
- { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); }
-
- static _Tp* allocate()
- { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
-
- static void deallocate(_Tp* __p, size_t __n)
- { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
-
- static void deallocate(_Tp* __p)
- { _Alloc::deallocate(__p, sizeof (_Tp)); }
- };
+ */
+ template<typename _Tp, typename _Alloc>
+ class __simple_alloc
+ {
+ public:
+ static _Tp*
+ allocate(size_t __n)
+ {
+ _Tp* __ret = 0;
+ if (__n)
+ __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+ return __ret;
+ }
+
+ static _Tp*
+ allocate()
+ { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
+
+ static void
+ deallocate(_Tp* __p, size_t __n)
+ { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
+
+ static void
+ deallocate(_Tp* __p)
+ { _Alloc::deallocate(__p, sizeof (_Tp)); }
+ };
/**
- * @maint
+ * @if maint
* An adaptor for an underlying allocator (_Alloc) to check the size
* arguments for debugging. Errors are reported using assert; these
* checks can be disabled via NDEBUG, but the space penalty is still
@@ -245,275 +264,292 @@ namespace std
* "There is some evidence that this can confuse Purify." - SGI comment
*
* This adaptor is "SGI" style. The _Alloc parameter must also be "SGI".
- * @endmaint
+ * @endif
* (See @link Allocators allocators info @endlink for more.)
- */
- template <class _Alloc>
- class __debug_alloc
- {
- private:
- enum {_S_extra = 8}; // Size of space used to store size. Note that this
- // must be large enough to preserve alignment.
-
- public:
-
- static void* allocate(size_t __n)
+ */
+ template<typename _Alloc>
+ class __debug_alloc
{
- char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
- *(size_t*)__result = __n;
- return __result + (int) _S_extra;
- }
-
- static void deallocate(void* __p, size_t __n)
- {
- char* __real_p = (char*)__p - (int) _S_extra;
- assert(*(size_t*)__real_p == __n);
- _Alloc::deallocate(__real_p, __n + (int) _S_extra);
- }
-
- static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz)
+ private:
+ // Size of space used to store size. Note that this must be
+ // large enough to preserve alignment.
+ enum {_S_extra = 8};
+
+ public:
+ static void*
+ allocate(size_t __n)
+ {
+ char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
+ *(size_t*)__result = __n;
+ return __result + (int) _S_extra;
+ }
+
+ static void
+ deallocate(void* __p, size_t __n)
+ {
+ char* __real_p = (char*)__p - (int) _S_extra;
+ assert(*(size_t*)__real_p == __n);
+ _Alloc::deallocate(__real_p, __n + (int) _S_extra);
+ }
+
+ // _GLIBCPP_DEPRECATED
+ static void*
+ reallocate(void* __p, size_t __old_sz, size_t __new_sz)
+ {
+ char* __real_p = (char*)__p - (int) _S_extra;
+ assert(*(size_t*)__real_p == __old_sz);
+ char* __result = (char*) _Alloc::reallocate(__real_p,
+ __old_sz + (int) _S_extra,
+ __new_sz + (int) _S_extra);
+ *(size_t*)__result = __new_sz;
+ return __result + (int) _S_extra;
+ }
+ };
+
+
+ /**
+ * @if maint
+ * Default node allocator. "SGI" style. Uses various allocators to
+ * fulfill underlying requests (and makes as few requests as possible
+ * when in default high-speed pool mode).
+ *
+ * Important implementation properties:
+ * 0. If globally mandated, then allocate objects from __new_alloc
+ * 1. If the clients request an object of size > _MAX_BYTES, the resulting
+ * object will be obtained directly from __new_alloc
+ * 2. In all other cases, we allocate an object of size exactly
+ * _S_round_up(requested_size). Thus the client has enough size
+ * information that we can return the object to the proper free list
+ * without permanently losing part of the object.
+ *
+ * The first template parameter specifies whether more than one thread may
+ * use this allocator. It is safe to allocate an object from one instance
+ * of a default_alloc and deallocate it with another one. This effectively
+ * transfers its ownership to the second one. This may have undesirable
+ * effects on reference locality.
+ *
+ * The second parameter is unused and serves only to allow the creation of
+ * multiple default_alloc instances. Note that containers built on different
+ * allocator instances have different types, limiting the utility of this
+ * approach. If you do not wish to share the free lists with the main
+ * default_alloc instance, instantiate this with a non-zero __inst.
+ *
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<bool __threads, int __inst>
+ class __default_alloc_template
{
- char* __real_p = (char*)__p - (int) _S_extra;
- assert(*(size_t*)__real_p == __old_sz);
- char* __result = (char*)
- _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra,
- __new_sz + (int) _S_extra);
- *(size_t*)__result = __new_sz;
- return __result + (int) _S_extra;
- }
- };
+ private:
+ enum {_ALIGN = 8};
+ enum {_MAX_BYTES = 128};
+ enum {_NFREELISTS = _MAX_BYTES / _ALIGN};
+ union _Obj
+ {
+ union _Obj* _M_free_list_link;
+ char _M_client_data[1]; // The client sees this.
+ };
-#ifdef __USE_MALLOC
+ static _Obj* volatile _S_free_list[_NFREELISTS];
-typedef __mem_interface __alloc;
-typedef __mem_interface __single_client_alloc;
+ // Chunk allocation state.
+ static char* _S_start_free;
+ static char* _S_end_free;
+ static size_t _S_heap_size;
-#else
+ static _STL_mutex_lock _S_node_allocator_lock;
+ static size_t
+ _S_round_up(size_t __bytes)
+ { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); }
-/**
- * @maint
- * Default node allocator. "SGI" style. Uses __mem_interface for its
- * underlying requests (and makes as few requests as possible).
- * **** Currently __mem_interface is always __new_alloc, never __malloc*.
- *
- * Important implementation properties:
- * 1. If the clients request an object of size > _MAX_BYTES, the resulting
- * object will be obtained directly from the underlying __mem_interface.
- * 2. In all other cases, we allocate an object of size exactly
- * _S_round_up(requested_size). Thus the client has enough size
- * information that we can return the object to the proper free list
- * without permanently losing part of the object.
- *
- * The first template parameter specifies whether more than one thread may
- * use this allocator. It is safe to allocate an object from one instance
- * of a default_alloc and deallocate it with another one. This effectively
- * transfers its ownership to the second one. This may have undesirable
- * effects on reference locality.
- *
- * The second parameter is unused and serves only to allow the creation of
- * multiple default_alloc instances. Note that containers built on different
- * allocator instances have different types, limiting the utility of this
- * approach. If you do not wish to share the free lists with the main
- * default_alloc instance, instantiate this with a non-zero __inst.
- *
- * @endmaint
- * (See @link Allocators allocators info @endlink for more.)
-*/
-template<bool __threads, int __inst>
- class __default_alloc_template
- {
- private:
- enum {_ALIGN = 8};
- enum {_MAX_BYTES = 128};
- enum {_NFREELISTS = _MAX_BYTES / _ALIGN};
-
- union _Obj
- {
- union _Obj* _M_free_list_link;
- char _M_client_data[1]; // The client sees this.
- };
+ static size_t
+ _S_freelist_index(size_t __bytes)
+ { return (((__bytes) + (size_t)_ALIGN - 1)/(size_t)_ALIGN - 1); }
+
+ // Returns an object of size __n, and optionally adds to size __n
+ // free list.
+ static void*
+ _S_refill(size_t __n);
+
+ // Allocates a chunk for nobjs of size size. nobjs may be reduced
+ // if it is inconvenient to allocate the requested number.
+ static char*
+ _S_chunk_alloc(size_t __size, int& __nobjs);
+
+ // It would be nice to use _STL_auto_lock here. But we need a
+ // test whether threads are in use.
+ struct _Lock
+ {
+ _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); }
+ ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); }
+ } __attribute__ ((__unused__));
+ friend struct _Lock;
+
+ static _Atomic_word _S_force_new;
- static _Obj* volatile _S_free_list[_NFREELISTS];
-
- // Chunk allocation state.
- static char* _S_start_free;
- static char* _S_end_free;
- static size_t _S_heap_size;
-
- static _STL_mutex_lock _S_node_allocator_lock;
-
- static size_t
- _S_round_up(size_t __bytes)
- { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); }
-
- static size_t
- _S_freelist_index(size_t __bytes)
- { return (((__bytes) + (size_t)_ALIGN-1)/(size_t)_ALIGN - 1); }
-
- // Returns an object of size __n, and optionally adds to size __n
- // free list.
- static void*
- _S_refill(size_t __n);
-
- // Allocates a chunk for nobjs of size size. nobjs may be reduced
- // if it is inconvenient to allocate the requested number.
- static char*
- _S_chunk_alloc(size_t __size, int& __nobjs);
-
- // It would be nice to use _STL_auto_lock here. But we need a
- // test whether threads are in use.
- class _Lock
- {
public:
- _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); }
- ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); }
- } __attribute__ ((__unused__));
- friend class _Lock;
-
- public:
- // __n must be > 0
- static void*
- allocate(size_t __n)
- {
- void* __ret = 0;
-
- if (__n > (size_t) _MAX_BYTES)
- __ret = __mem_interface::allocate(__n);
- else
- {
- _Obj* volatile* __my_free_list = _S_free_list
- + _S_freelist_index(__n);
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
- _Obj* __restrict__ __result = *__my_free_list;
- if (__result == 0)
- __ret = _S_refill(_S_round_up(__n));
- else
- {
- *__my_free_list = __result -> _M_free_list_link;
- __ret = __result;
- }
- }
- return __ret;
- };
+ // __n must be > 0
+ static void*
+ allocate(size_t __n)
+ {
+ void* __ret = 0;
+
+ // If there is a race through here, assume answer from getenv
+ // will resolve in same direction. Inspired by techniques
+ // to efficiently support threading found in basic_string.h.
+ if (_S_force_new == 0)
+ {
+ if (getenv("GLIBCPP_FORCE_NEW"))
+ __atomic_add(&_S_force_new, 1);
+ else
+ __atomic_add(&_S_force_new, -1);
+ // Trust but verify...
+ assert(_S_force_new != 0);
+ }
+
+ if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
+ __ret = __new_alloc::allocate(__n);
+ else
+ {
+ _Obj* volatile* __my_free_list = _S_free_list
+ + _S_freelist_index(__n);
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ _Obj* __restrict__ __result = *__my_free_list;
+ if (__builtin_expect(__result == 0, 0))
+ __ret = _S_refill(_S_round_up(__n));
+ else
+ {
+ *__my_free_list = __result -> _M_free_list_link;
+ __ret = __result;
+ }
+ if (__builtin_expect(__ret == 0, 0))
+ __throw_bad_alloc();
+ }
+ return __ret;
+ }
- // __p may not be 0
- static void
- deallocate(void* __p, size_t __n)
- {
- if (__n > (size_t) _MAX_BYTES)
- __mem_interface::deallocate(__p, __n);
- else
- {
- _Obj* volatile* __my_free_list
- = _S_free_list + _S_freelist_index(__n);
- _Obj* __q = (_Obj*)__p;
-
- // Acquire the lock here with a constructor call. This ensures that
- // it is released in exit or during stack unwinding.
- _Lock __lock_instance;
- __q -> _M_free_list_link = *__my_free_list;
- *__my_free_list = __q;
- }
- }
-
- static void*
- reallocate(void* __p, size_t __old_sz, size_t __new_sz);
- };
+ // __p may not be 0
+ static void
+ deallocate(void* __p, size_t __n)
+ {
+ if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
+ __new_alloc::deallocate(__p, __n);
+ else
+ {
+ _Obj* volatile* __my_free_list = _S_free_list
+ + _S_freelist_index(__n);
+ _Obj* __q = (_Obj*)__p;
+
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ __q -> _M_free_list_link = *__my_free_list;
+ *__my_free_list = __q;
+ }
+ }
+
+ // _GLIBCPP_DEPRECATED
+ static void*
+ reallocate(void* __p, size_t __old_sz, size_t __new_sz);
+ };
+ template<bool __threads, int __inst> _Atomic_word
+ __default_alloc_template<__threads, __inst>::_S_force_new = 0;
template<bool __threads, int __inst>
- inline bool
- operator==(const __default_alloc_template<__threads, __inst>&,
- const __default_alloc_template<__threads, __inst>&)
+ inline bool
+ operator==(const __default_alloc_template<__threads,__inst>&,
+ const __default_alloc_template<__threads,__inst>&)
{ return true; }
template<bool __threads, int __inst>
- inline bool
- operator!=(const __default_alloc_template<__threads, __inst>&,
- const __default_alloc_template<__threads, __inst>&)
+ inline bool
+ operator!=(const __default_alloc_template<__threads,__inst>&,
+ const __default_alloc_template<__threads,__inst>&)
{ return false; }
// We allocate memory in large chunks in order to avoid fragmenting the
- // malloc heap (or whatever __mem_interface is using) too much. We assume
- // that __size is properly aligned. We hold the allocation lock.
+ // heap too much. We assume that __size is properly aligned. We hold
+ // the allocation lock.
template<bool __threads, int __inst>
char*
- __default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size,
- int& __nobjs)
+ __default_alloc_template<__threads, __inst>::
+ _S_chunk_alloc(size_t __size, int& __nobjs)
{
char* __result;
size_t __total_bytes = __size * __nobjs;
size_t __bytes_left = _S_end_free - _S_start_free;
-
- if (__bytes_left >= __total_bytes)
- {
- __result = _S_start_free;
- _S_start_free += __total_bytes;
- return(__result);
- }
- else if (__bytes_left >= __size)
- {
- __nobjs = (int)(__bytes_left/__size);
- __total_bytes = __size * __nobjs;
- __result = _S_start_free;
- _S_start_free += __total_bytes;
- return(__result);
- }
- else
- {
- size_t __bytes_to_get =
- 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
- // Try to make use of the left-over piece.
- if (__bytes_left > 0)
- {
- _Obj* volatile* __my_free_list =
- _S_free_list + _S_freelist_index(__bytes_left);
-
- ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
- *__my_free_list = (_Obj*)_S_start_free;
- }
- _S_start_free = (char*) __mem_interface::allocate(__bytes_to_get);
- if (0 == _S_start_free)
- {
- size_t __i;
- _Obj* volatile* __my_free_list;
- _Obj* __p;
- // Try to make do with what we have. That can't hurt. We
- // do not try smaller requests, since that tends to result
- // in disaster on multi-process machines.
- __i = __size;
- for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN)
- {
- __my_free_list = _S_free_list + _S_freelist_index(__i);
- __p = *__my_free_list;
- if (0 != __p)
- {
- *__my_free_list = __p -> _M_free_list_link;
- _S_start_free = (char*)__p;
- _S_end_free = _S_start_free + __i;
- return(_S_chunk_alloc(__size, __nobjs));
- // Any leftover piece will eventually make it to the
- // right free list.
- }
- }
- _S_end_free = 0; // In case of exception.
- _S_start_free = (char*)__mem_interface::allocate(__bytes_to_get);
- // This should either throw an exception or remedy the situation.
- // Thus we assume it succeeded.
- }
- _S_heap_size += __bytes_to_get;
- _S_end_free = _S_start_free + __bytes_to_get;
- return(_S_chunk_alloc(__size, __nobjs));
- }
+
+ if (__bytes_left >= __total_bytes)
+ {
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return __result ;
+ }
+ else if (__bytes_left >= __size)
+ {
+ __nobjs = (int)(__bytes_left/__size);
+ __total_bytes = __size * __nobjs;
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return __result;
+ }
+ else
+ {
+ size_t __bytes_to_get =
+ 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
+ // Try to make use of the left-over piece.
+ if (__bytes_left > 0)
+ {
+ _Obj* volatile* __my_free_list =
+ _S_free_list + _S_freelist_index(__bytes_left);
+
+ ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
+ *__my_free_list = (_Obj*)_S_start_free;
+ }
+ _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
+ if (_S_start_free == 0)
+ {
+ size_t __i;
+ _Obj* volatile* __my_free_list;
+ _Obj* __p;
+ // Try to make do with what we have. That can't hurt. We
+ // do not try smaller requests, since that tends to result
+ // in disaster on multi-process machines.
+ __i = __size;
+ for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN)
+ {
+ __my_free_list = _S_free_list + _S_freelist_index(__i);
+ __p = *__my_free_list;
+ if (__p != 0)
+ {
+ *__my_free_list = __p -> _M_free_list_link;
+ _S_start_free = (char*)__p;
+ _S_end_free = _S_start_free + __i;
+ return _S_chunk_alloc(__size, __nobjs);
+ // Any leftover piece will eventually make it to the
+ // right free list.
+ }
+ }
+ _S_end_free = 0; // In case of exception.
+ _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
+ // This should either throw an exception or remedy the situation.
+ // Thus we assume it succeeded.
+ }
+ _S_heap_size += __bytes_to_get;
+ _S_end_free = _S_start_free + __bytes_to_get;
+ return _S_chunk_alloc(__size, __nobjs);
+ }
}
-
-
+
+
// Returns an object of size __n, and optionally adds to "size
// __n"'s free list. We assume that __n is properly aligned. We
// hold the allocation lock.
@@ -528,404 +564,421 @@ template<bool __threads, int __inst>
_Obj* __current_obj;
_Obj* __next_obj;
int __i;
-
- if (1 == __nobjs) return(__chunk);
+
+ if (1 == __nobjs)
+ return __chunk;
__my_free_list = _S_free_list + _S_freelist_index(__n);
-
- /* Build free list in chunk */
+
+ // Build free list in chunk.
__result = (_Obj*)__chunk;
*__my_free_list = __next_obj = (_Obj*)(__chunk + __n);
- for (__i = 1; ; __i++) {
- __current_obj = __next_obj;
- __next_obj = (_Obj*)((char*)__next_obj + __n);
- if (__nobjs - 1 == __i) {
- __current_obj -> _M_free_list_link = 0;
- break;
- } else {
- __current_obj -> _M_free_list_link = __next_obj;
- }
- }
- return(__result);
+ for (__i = 1; ; __i++)
+ {
+ __current_obj = __next_obj;
+ __next_obj = (_Obj*)((char*)__next_obj + __n);
+ if (__nobjs - 1 == __i)
+ {
+ __current_obj -> _M_free_list_link = 0;
+ break;
+ }
+ else
+ __current_obj -> _M_free_list_link = __next_obj;
+ }
+ return __result;
}
+ // _GLIBCPP_DEPRECATED
template<bool threads, int inst>
void*
- __default_alloc_template<threads, inst>::reallocate(void* __p,
- size_t __old_sz,
- size_t __new_sz)
+ __default_alloc_template<threads, inst>::
+ reallocate(void* __p, size_t __old_sz, size_t __new_sz)
{
void* __result;
size_t __copy_sz;
-
- if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) {
+
+ if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES)
return(realloc(__p, __new_sz));
- }
- if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
+ if (_S_round_up(__old_sz) == _S_round_up(__new_sz))
+ return(__p);
__result = allocate(__new_sz);
__copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
memcpy(__result, __p, __copy_sz);
deallocate(__p, __old_sz);
- return(__result);
+ return __result;
}
-
+
template<bool __threads, int __inst>
- _STL_mutex_lock
- __default_alloc_template<__threads, __inst>::_S_node_allocator_lock
- __STL_MUTEX_INITIALIZER;
-
+ _STL_mutex_lock
+ __default_alloc_template<__threads,__inst>::_S_node_allocator_lock
+ __STL_MUTEX_INITIALIZER;
+
template<bool __threads, int __inst>
- char* __default_alloc_template<__threads, __inst>::_S_start_free = 0;
-
+ char* __default_alloc_template<__threads,__inst>::_S_start_free = 0;
+
template<bool __threads, int __inst>
- char* __default_alloc_template<__threads, __inst>::_S_end_free = 0;
-
+ char* __default_alloc_template<__threads,__inst>::_S_end_free = 0;
+
template<bool __threads, int __inst>
- size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0;
-
+ size_t __default_alloc_template<__threads,__inst>::_S_heap_size = 0;
+
template<bool __threads, int __inst>
- typename __default_alloc_template<__threads, __inst>::_Obj* volatile
- __default_alloc_template<__threads, __inst>::_S_free_list[_NFREELISTS];
-
- typedef __default_alloc_template<true, 0> __alloc;
- typedef __default_alloc_template<false, 0> __single_client_alloc;
+ typename __default_alloc_template<__threads,__inst>::_Obj* volatile
+ __default_alloc_template<__threads,__inst>::_S_free_list[_NFREELISTS];
+ typedef __default_alloc_template<true,0> __alloc;
+ typedef __default_alloc_template<false,0> __single_client_alloc;
-#endif /* ! __USE_MALLOC */
+ /**
+ * @brief The "standard" allocator, as per [20.4].
+ *
+ * The private _Alloc is "SGI" style. (See comments at the top
+ * of stl_alloc.h.)
+ *
+ * The underlying allocator behaves as follows.
+ * - __default_alloc_template is used via two typedefs
+ * - "__single_client_alloc" typedef does no locking for threads
+ * - "__alloc" typedef is threadsafe via the locks
+ * - __new_alloc is used for memory requests
+ *
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<typename _Tp>
+ class allocator
+ {
+ typedef __alloc _Alloc; // The underlying allocator.
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp* pointer;
+ typedef const _Tp* const_pointer;
+ typedef _Tp& reference;
+ typedef const _Tp& const_reference;
+ typedef _Tp value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef allocator<_Tp1> other; };
+
+ allocator() throw() {}
+ allocator(const allocator&) throw() {}
+ template<typename _Tp1>
+ allocator(const allocator<_Tp1>&) throw() {}
+ ~allocator() throw() {}
+
+ pointer
+ address(reference __x) const { return &__x; }
+
+ const_pointer
+ address(const_reference __x) const { return &__x; }
+
+ // NB: __n is permitted to be 0. The C++ standard says nothing
+ // about what the return value is when __n == 0.
+ _Tp*
+ allocate(size_type __n, const void* = 0)
+ {
+ _Tp* __ret = 0;
+ if (__n)
+ {
+ if (__n <= this->max_size())
+ __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+ else
+ __throw_bad_alloc();
+ }
+ return __ret;
+ }
-/**
- * This is a "standard" allocator, as per [20.4]. The private _Alloc is
- * "SGI" style. (See comments at the top of stl_alloc.h.)
- *
- * The underlying allocator behaves as follows.
- * - if __USE_MALLOC then
- * - thread safety depends on malloc and is entirely out of our hands
- * - __malloc_alloc_template is used for memory requests
- * - else (the default)
- * - __default_alloc_template is used via two typedefs
- * - "__single_client_alloc" typedef does no locking for threads
- * - "__alloc" typedef is threadsafe via the locks
- * - __new_alloc is used for memory requests
- *
- * (See @link Allocators allocators info @endlink for more.)
-*/
-template <class _Tp>
-class allocator
-{
- typedef __alloc _Alloc; // The underlying allocator.
-public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Tp* pointer;
- typedef const _Tp* const_pointer;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
- typedef _Tp value_type;
-
- template <class _Tp1> struct rebind {
- typedef allocator<_Tp1> other;
- };
+ // __p is not permitted to be a null pointer.
+ void
+ deallocate(pointer __p, size_type __n)
+ { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
- allocator() throw() {}
- allocator(const allocator&) throw() {}
- template <class _Tp1> allocator(const allocator<_Tp1>&) throw() {}
- ~allocator() throw() {}
-
- pointer address(reference __x) const { return &__x; }
- const_pointer address(const_reference __x) const { return &__x; }
-
- // __n is permitted to be 0. The C++ standard says nothing about what
- // the return value is when __n == 0.
- _Tp* allocate(size_type __n, const void* = 0) {
- return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)))
- : 0;
- }
-
- // __p is not permitted to be a null pointer.
- void deallocate(pointer __p, size_type __n)
- { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
-
- size_type max_size() const throw()
- { return size_t(-1) / sizeof(_Tp); }
-
- void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
- void destroy(pointer __p) { __p->~_Tp(); }
-};
-
-template<>
-class allocator<void> {
-public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef void* pointer;
- typedef const void* const_pointer;
- typedef void value_type;
-
- template <class _Tp1> struct rebind {
- typedef allocator<_Tp1> other;
- };
-};
+ size_type
+ max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
+ void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+ void destroy(pointer __p) { __p->~_Tp(); }
+ };
-template <class _T1, class _T2>
-inline bool operator==(const allocator<_T1>&, const allocator<_T2>&)
-{
- return true;
-}
+ template<>
+ class allocator<void>
+ {
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef void* pointer;
+ typedef const void* const_pointer;
+ typedef void value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef allocator<_Tp1> other; };
+ };
-template <class _T1, class _T2>
-inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&)
-{
- return false;
-}
+ template<typename _T1, typename _T2>
+ inline bool
+ operator==(const allocator<_T1>&, const allocator<_T2>&)
+ { return true; }
-/**
- * @maint
- * Allocator adaptor to turn an "SGI" style allocator (e.g., __alloc,
- * __malloc_alloc_template) into a "standard" conforming allocator. Note
- * that this adaptor does *not* assume that all objects of the underlying
- * alloc class are identical, nor does it assume that all of the underlying
- * alloc's member functions are static member functions. Note, also, that
- * __allocator<_Tp, __alloc> is essentially the same thing as allocator<_Tp>.
- * @endmaint
- * (See @link Allocators allocators info @endlink for more.)
-*/
-template <class _Tp, class _Alloc>
-struct __allocator
-{
- _Alloc __underlying_alloc;
-
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Tp* pointer;
- typedef const _Tp* const_pointer;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
- typedef _Tp value_type;
-
- template <class _Tp1> struct rebind {
- typedef __allocator<_Tp1, _Alloc> other;
- };
+ template<typename _T1, typename _T2>
+ inline bool
+ operator!=(const allocator<_T1>&, const allocator<_T2>&)
+ { return false; }
- __allocator() throw() {}
- __allocator(const __allocator& __a) throw()
- : __underlying_alloc(__a.__underlying_alloc) {}
- template <class _Tp1>
- __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
- : __underlying_alloc(__a.__underlying_alloc) {}
- ~__allocator() throw() {}
-
- pointer address(reference __x) const { return &__x; }
- const_pointer address(const_reference __x) const { return &__x; }
-
- // __n is permitted to be 0.
- _Tp* allocate(size_type __n, const void* = 0) {
- return __n != 0
- ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp)))
- : 0;
- }
-
- // __p is not permitted to be a null pointer.
- void deallocate(pointer __p, size_type __n)
- { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
-
- size_type max_size() const throw()
- { return size_t(-1) / sizeof(_Tp); }
-
- void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
- void destroy(pointer __p) { __p->~_Tp(); }
-};
-
-template <class _Alloc>
-class __allocator<void, _Alloc> {
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef void* pointer;
- typedef const void* const_pointer;
- typedef void value_type;
-
- template <class _Tp1> struct rebind {
- typedef __allocator<_Tp1, _Alloc> other;
- };
-};
-template <class _Tp, class _Alloc>
-inline bool operator==(const __allocator<_Tp, _Alloc>& __a1,
- const __allocator<_Tp, _Alloc>& __a2)
-{
- return __a1.__underlying_alloc == __a2.__underlying_alloc;
-}
+ /**
+ * @if maint
+ * Allocator adaptor to turn an "SGI" style allocator (e.g.,
+ * __alloc, __malloc_alloc_template) into a "standard" conforming
+ * allocator. Note that this adaptor does *not* assume that all
+ * objects of the underlying alloc class are identical, nor does it
+ * assume that all of the underlying alloc's member functions are
+ * static member functions. Note, also, that __allocator<_Tp,
+ * __alloc> is essentially the same thing as allocator<_Tp>.
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<typename _Tp, typename _Alloc>
+ struct __allocator
+ {
+ _Alloc __underlying_alloc;
+
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp* pointer;
+ typedef const _Tp* const_pointer;
+ typedef _Tp& reference;
+ typedef const _Tp& const_reference;
+ typedef _Tp value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef __allocator<_Tp1, _Alloc> other; };
+
+ __allocator() throw() {}
+ __allocator(const __allocator& __a) throw()
+ : __underlying_alloc(__a.__underlying_alloc) {}
+
+ template<typename _Tp1>
+ __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
+ : __underlying_alloc(__a.__underlying_alloc) {}
+
+ ~__allocator() throw() {}
+
+ pointer
+ address(reference __x) const { return &__x; }
+
+ const_pointer
+ address(const_reference __x) const { return &__x; }
+
+ // NB: __n is permitted to be 0. The C++ standard says nothing
+ // about what the return value is when __n == 0.
+ _Tp*
+ allocate(size_type __n, const void* = 0)
+ {
+ _Tp* __ret = 0;
+ if (__n)
+ __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+ return __ret;
+ }
-template <class _Tp, class _Alloc>
-inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1,
- const __allocator<_Tp, _Alloc>& __a2)
-{
- return __a1.__underlying_alloc != __a2.__underlying_alloc;
-}
+ // __p is not permitted to be a null pointer.
+ void
+ deallocate(pointer __p, size_type __n)
+ { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
+
+ size_type
+ max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
+
+ void
+ construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+
+ void
+ destroy(pointer __p) { __p->~_Tp(); }
+ };
+ template<typename _Alloc>
+ struct __allocator<void, _Alloc>
+ {
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef void* pointer;
+ typedef const void* const_pointer;
+ typedef void value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef __allocator<_Tp1, _Alloc> other; };
+ };
-//@{
-/** Comparison operators for all of the predifined SGI-style allocators.
- * This ensures that __allocator<malloc_alloc> (for example) will work
- * correctly. As required, all allocators compare equal.
-*/
-template <int inst>
-inline bool operator==(const __malloc_alloc_template<inst>&,
- const __malloc_alloc_template<inst>&)
-{
- return true;
-}
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator==(const __allocator<_Tp,_Alloc>& __a1,
+ const __allocator<_Tp,_Alloc>& __a2)
+ { return __a1.__underlying_alloc == __a2.__underlying_alloc; }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator!=(const __allocator<_Tp, _Alloc>& __a1,
+ const __allocator<_Tp, _Alloc>& __a2)
+ { return __a1.__underlying_alloc != __a2.__underlying_alloc; }
+
+
+ //@{
+ /** Comparison operators for all of the predifined SGI-style allocators.
+ * This ensures that __allocator<malloc_alloc> (for example) will work
+ * correctly. As required, all allocators compare equal.
+ */
+ template<int inst>
+ inline bool
+ operator==(const __malloc_alloc_template<inst>&,
+ const __malloc_alloc_template<inst>&)
+ { return true; }
-template <int __inst>
-inline bool operator!=(const __malloc_alloc_template<__inst>&,
- const __malloc_alloc_template<__inst>&)
-{
- return false;
-}
+ template<int __inst>
+ inline bool
+ operator!=(const __malloc_alloc_template<__inst>&,
+ const __malloc_alloc_template<__inst>&)
+ { return false; }
-template <class _Alloc>
-inline bool operator==(const __debug_alloc<_Alloc>&,
- const __debug_alloc<_Alloc>&) {
- return true;
-}
+ template<typename _Alloc>
+ inline bool
+ operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+ { return true; }
-template <class _Alloc>
-inline bool operator!=(const __debug_alloc<_Alloc>&,
- const __debug_alloc<_Alloc>&) {
- return false;
-}
-//@}
+ template<typename _Alloc>
+ inline bool
+ operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+ { return false; }
+ //@}
-/**
- * @maint
- * Another allocator adaptor: _Alloc_traits. This serves two purposes.
- * First, make it possible to write containers that can use either "SGI"
- * style allocators or "standard" allocators. Second, provide a mechanism
- * so that containers can query whether or not the allocator has distinct
- * instances. If not, the container can avoid wasting a word of memory to
- * store an empty object. For examples of use, see stl_vector.h, etc, or
- * any of the other classes derived from this one.
- *
- * This adaptor uses partial specialization. The general case of
- * _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
- * standard-conforming allocator, possibly with non-equal instances and
- * non-static members. (It still behaves correctly even if _Alloc has
- * static member and if all instances are equal. Refinements affect
- * performance, not correctness.)
- *
- * There are always two members: allocator_type, which is a standard-
- * conforming allocator type for allocating objects of type _Tp, and
- * _S_instanceless, a static const member of type bool. If
- * _S_instanceless is true, this means that there is no difference
- * between any two instances of type allocator_type. Furthermore, if
- * _S_instanceless is true, then _Alloc_traits has one additional
- * member: _Alloc_type. This type encapsulates allocation and
- * deallocation of objects of type _Tp through a static interface; it
- * has two member functions, whose signatures are
- *
- * - static _Tp* allocate(size_t)
- * - static void deallocate(_Tp*, size_t)
- *
- * The size_t parameters are "standard" style (see top of stl_alloc.h) in
- * that they take counts, not sizes.
- *
- * @endmaint
- * (See @link Allocators allocators info @endlink for more.)
-*/
-//@{
-// The fully general version.
-template <class _Tp, class _Allocator>
-struct _Alloc_traits
-{
- static const bool _S_instanceless = false;
- typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
-};
+ /**
+ * @if maint
+ * Another allocator adaptor: _Alloc_traits. This serves two purposes.
+ * First, make it possible to write containers that can use either "SGI"
+ * style allocators or "standard" allocators. Second, provide a mechanism
+ * so that containers can query whether or not the allocator has distinct
+ * instances. If not, the container can avoid wasting a word of memory to
+ * store an empty object. For examples of use, see stl_vector.h, etc, or
+ * any of the other classes derived from this one.
+ *
+ * This adaptor uses partial specialization. The general case of
+ * _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
+ * standard-conforming allocator, possibly with non-equal instances and
+ * non-static members. (It still behaves correctly even if _Alloc has
+ * static member and if all instances are equal. Refinements affect
+ * performance, not correctness.)
+ *
+ * There are always two members: allocator_type, which is a standard-
+ * conforming allocator type for allocating objects of type _Tp, and
+ * _S_instanceless, a static const member of type bool. If
+ * _S_instanceless is true, this means that there is no difference
+ * between any two instances of type allocator_type. Furthermore, if
+ * _S_instanceless is true, then _Alloc_traits has one additional
+ * member: _Alloc_type. This type encapsulates allocation and
+ * deallocation of objects of type _Tp through a static interface; it
+ * has two member functions, whose signatures are
+ *
+ * - static _Tp* allocate(size_t)
+ * - static void deallocate(_Tp*, size_t)
+ *
+ * The size_t parameters are "standard" style (see top of stl_alloc.h) in
+ * that they take counts, not sizes.
+ *
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ //@{
+ // The fully general version.
+ template<typename _Tp, typename _Allocator>
+ struct _Alloc_traits
+ {
+ static const bool _S_instanceless = false;
+ typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
+ };
-template <class _Tp, class _Allocator>
-const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
+ template<typename _Tp, typename _Allocator>
+ const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
-/// The version for the default allocator.
-template <class _Tp, class _Tp1>
-struct _Alloc_traits<_Tp, allocator<_Tp1> >
-{
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
- typedef allocator<_Tp> allocator_type;
-};
-//@}
-
-//@{
-/// Versions for the predefined "SGI" style allocators.
-template <class _Tp, int __inst>
-struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> >
-{
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
- typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
-};
-
-#ifndef __USE_MALLOC
-template <class _Tp, bool __threads, int __inst>
-struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
-{
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> >
- _Alloc_type;
- typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> >
- allocator_type;
-};
-#endif
+ /// The version for the default allocator.
+ template<typename _Tp, typename _Tp1>
+ struct _Alloc_traits<_Tp, allocator<_Tp1> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
+ typedef allocator<_Tp> allocator_type;
+ };
+ //@}
-template <class _Tp, class _Alloc>
-struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
-{
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
- typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
-};
-//@}
-
-//@{
-/// Versions for the __allocator adaptor used with the predefined "SGI" style allocators.
-template <class _Tp, class _Tp1, int __inst>
-struct _Alloc_traits<_Tp,
- __allocator<_Tp1, __malloc_alloc_template<__inst> > >
-{
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
- typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
-};
-
-#ifndef __USE_MALLOC
-template <class _Tp, class _Tp1, bool __thr, int __inst>
-struct _Alloc_traits<_Tp,
- __allocator<_Tp1,
- __default_alloc_template<__thr, __inst> > >
-{
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> >
- _Alloc_type;
- typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
- allocator_type;
-};
-#endif
+ //@{
+ /// Versions for the predefined "SGI" style allocators.
+ template<typename _Tp, int __inst>
+ struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
+ typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
+ };
-template <class _Tp, class _Tp1, class _Alloc>
-struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
-{
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
- typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
-};
-//@}
+ template<typename _Tp, bool __threads, int __inst>
+ struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> >
+ _Alloc_type;
+ typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> >
+ allocator_type;
+ };
-} // namespace std
+ template<typename _Tp, typename _Alloc>
+ struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
+ typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
+ };
+ //@}
+
+ //@{
+ /// Versions for the __allocator adaptor used with the predefined
+ /// "SGI" style allocators.
+ template<typename _Tp, typename _Tp1, int __inst>
+ struct _Alloc_traits<_Tp,
+ __allocator<_Tp1, __malloc_alloc_template<__inst> > >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
+ typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
+ };
-#endif /* __GLIBCPP_INTERNAL_ALLOC_H */
+ template<typename _Tp, typename _Tp1, bool __thr, int __inst>
+ struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> >
+ _Alloc_type;
+ typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
+ allocator_type;
+ };
-// Local Variables:
-// mode:C++
-// End:
+ template<typename _Tp, typename _Tp1, typename _Alloc>
+ struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
+ typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
+ };
+ //@}
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+ extern template class allocator<char>;
+ extern template class allocator<wchar_t>;
+ extern template class __default_alloc_template<true,0>;
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 66c7e2de594..ce6df71b67f 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -63,17 +63,19 @@
namespace std
{
- extern const int __WORD_BIT;
+ typedef unsigned long _Bit_type;
+ enum { _M_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) };
struct _Bit_reference {
- unsigned int* _M_p;
- unsigned int _M_mask;
- _Bit_reference(unsigned int* __x, unsigned int __y)
+
+ _Bit_type * _M_p;
+ _Bit_type _M_mask;
+ _Bit_reference(_Bit_type * __x, _Bit_type __y)
: _M_p(__x), _M_mask(__y) {}
public:
_Bit_reference() : _M_p(0), _M_mask(0) {}
- operator bool() const { return !(!(*_M_p & _M_mask)); }
+ operator bool() const { return !!(*_M_p & _M_mask); }
_Bit_reference& operator=(bool __x)
{
if (__x) *_M_p |= _M_mask;
@@ -84,9 +86,8 @@ public:
{ return *this = bool(__x); }
bool operator==(const _Bit_reference& __x) const
{ return bool(*this) == bool(__x); }
- bool operator<(const _Bit_reference& __x) const {
- return !bool(*this) && bool(__x);
- }
+ bool operator<(const _Bit_reference& __x) const
+ { return !bool(*this) && bool(__x); }
void flip() { *_M_p ^= _M_mask; }
};
@@ -99,31 +100,31 @@ inline void swap(_Bit_reference __x, _Bit_reference __y)
struct _Bit_iterator_base : public iterator<random_access_iterator_tag, bool>
{
- unsigned int* _M_p;
+ _Bit_type * _M_p;
unsigned int _M_offset;
- _Bit_iterator_base(unsigned int* __x, unsigned int __y)
+ _Bit_iterator_base(_Bit_type * __x, unsigned int __y)
: _M_p(__x), _M_offset(__y) {}
void _M_bump_up() {
- if (_M_offset++ == __WORD_BIT - 1) {
+ if (_M_offset++ == _M_word_bit - 1) {
_M_offset = 0;
++_M_p;
}
}
void _M_bump_down() {
if (_M_offset-- == 0) {
- _M_offset = __WORD_BIT - 1;
+ _M_offset = _M_word_bit - 1;
--_M_p;
}
}
void _M_incr(ptrdiff_t __i) {
difference_type __n = __i + _M_offset;
- _M_p += __n / __WORD_BIT;
- __n = __n % __WORD_BIT;
+ _M_p += __n / _M_word_bit;
+ __n = __n % _M_word_bit;
if (__n < 0) {
- _M_offset = (unsigned int) __n + __WORD_BIT;
+ _M_offset = (unsigned int) __n + _M_word_bit;
--_M_p;
} else
_M_offset = (unsigned int) __n;
@@ -151,7 +152,7 @@ struct _Bit_iterator_base : public iterator<random_access_iterator_tag, bool>
inline ptrdiff_t
operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) {
- return __WORD_BIT * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset;
+ return _M_word_bit * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset;
}
@@ -162,10 +163,10 @@ struct _Bit_iterator : public _Bit_iterator_base
typedef _Bit_iterator iterator;
_Bit_iterator() : _Bit_iterator_base(0, 0) {}
- _Bit_iterator(unsigned int* __x, unsigned int __y)
+ _Bit_iterator(_Bit_type * __x, unsigned int __y)
: _Bit_iterator_base(__x, __y) {}
- reference operator*() const { return reference(_M_p, 1U << _M_offset); }
+ reference operator*() const { return reference(_M_p, 1UL << _M_offset); }
iterator& operator++() {
_M_bump_up();
return *this;
@@ -216,13 +217,13 @@ struct _Bit_const_iterator : public _Bit_iterator_base
typedef _Bit_const_iterator const_iterator;
_Bit_const_iterator() : _Bit_iterator_base(0, 0) {}
- _Bit_const_iterator(unsigned int* __x, unsigned int __y)
+ _Bit_const_iterator(_Bit_type * __x, unsigned int __y)
: _Bit_iterator_base(__x, __y) {}
_Bit_const_iterator(const _Bit_iterator& __x)
: _Bit_iterator_base(__x._M_p, __x._M_offset) {}
const_reference operator*() const {
- return _Bit_reference(_M_p, 1U << _M_offset);
+ return _Bit_reference(_M_p, 1UL << _M_offset);
}
const_iterator& operator++() {
_M_bump_up();
@@ -282,19 +283,19 @@ public:
: _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {}
protected:
- unsigned int* _M_bit_alloc(size_t __n)
- { return _M_data_allocator.allocate((__n + __WORD_BIT - 1)/__WORD_BIT); }
+ _Bit_type * _M_bit_alloc(size_t __n)
+ { return _M_data_allocator.allocate((__n + _M_word_bit - 1)/_M_word_bit); }
void _M_deallocate() {
if (_M_start._M_p)
_M_data_allocator.deallocate(_M_start._M_p,
_M_end_of_storage - _M_start._M_p);
}
- typename _Alloc_traits<unsigned int, _Allocator>::allocator_type
+ typename _Alloc_traits<_Bit_type, _Allocator>::allocator_type
_M_data_allocator;
_Bit_iterator _M_start;
_Bit_iterator _M_finish;
- unsigned int* _M_end_of_storage;
+ _Bit_type * _M_end_of_storage;
};
// Specialization for instanceless allocators.
@@ -309,11 +310,11 @@ public:
: _M_start(), _M_finish(), _M_end_of_storage(0) {}
protected:
- typedef typename _Alloc_traits<unsigned int, _Allocator>::_Alloc_type
+ typedef typename _Alloc_traits<_Bit_type, _Allocator>::_Alloc_type
_Alloc_type;
- unsigned int* _M_bit_alloc(size_t __n)
- { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); }
+ _Bit_type * _M_bit_alloc(size_t __n)
+ { return _Alloc_type::allocate((__n + _M_word_bit - 1)/_M_word_bit); }
void _M_deallocate() {
if (_M_start._M_p)
_Alloc_type::deallocate(_M_start._M_p,
@@ -322,7 +323,7 @@ protected:
_Bit_iterator _M_start;
_Bit_iterator _M_finish;
- unsigned int* _M_end_of_storage;
+ _Bit_type * _M_end_of_storage;
};
template <class _Alloc>
@@ -379,8 +380,8 @@ template <typename _Alloc>
protected:
void _M_initialize(size_type __n) {
- unsigned int* __q = _M_bit_alloc(__n);
- _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT;
+ _Bit_type * __q = _M_bit_alloc(__n);
+ _M_end_of_storage = __q + (__n + _M_word_bit - 1)/_M_word_bit;
_M_start = iterator(__q, 0);
_M_finish = _M_start + difference_type(__n);
}
@@ -391,13 +392,14 @@ template <typename _Alloc>
++_M_finish;
}
else {
- size_type __len = size() ? 2 * size() : __WORD_BIT;
- unsigned int* __q = _M_bit_alloc(__len);
+ size_type __len = size()
+ ? 2 * size() : static_cast<size_type>(_M_word_bit);
+ _Bit_type * __q = _M_bit_alloc(__len);
iterator __i = copy(begin(), __position, iterator(__q, 0));
*__i++ = __x;
_M_finish = copy(__position, end(), __i);
_M_deallocate();
- _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT;
+ _M_end_of_storage = __q + (__len + _M_word_bit - 1)/_M_word_bit;
_M_start = iterator(__q, 0);
}
}
@@ -443,12 +445,12 @@ template <typename _Alloc>
}
else {
size_type __len = size() + max(size(), __n);
- unsigned int* __q = _M_bit_alloc(__len);
+ _Bit_type * __q = _M_bit_alloc(__len);
iterator __i = copy(begin(), __position, iterator(__q, 0));
__i = copy(__first, __last, __i);
_M_finish = copy(__position, end(), __i);
_M_deallocate();
- _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT;
+ _M_end_of_storage = __q + (__len + _M_word_bit - 1)/_M_word_bit;
_M_start = iterator(__q, 0);
}
}
@@ -609,12 +611,14 @@ template <typename _Alloc>
}
void reserve(size_type __n) {
- if (capacity() < __n) {
- unsigned int* __q = _M_bit_alloc(__n);
+ if (__n > this->max_size())
+ __throw_length_error("vector::reserve");
+ if (this->capacity() < __n) {
+ _Bit_type * __q = _M_bit_alloc(__n);
_M_finish = copy(begin(), end(), iterator(__q, 0));
_M_deallocate();
_M_start = iterator(__q, 0);
- _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT;
+ _M_end_of_storage = __q + (__n + _M_word_bit - 1)/_M_word_bit;
}
}
@@ -673,12 +677,12 @@ template <typename _Alloc>
}
else {
size_type __len = size() + max(size(), __n);
- unsigned int* __q = _M_bit_alloc(__len);
+ _Bit_type * __q = _M_bit_alloc(__len);
iterator __i = copy(begin(), __position, iterator(__q, 0));
fill_n(__i, __n, __x);
_M_finish = copy(__position, end(), __i + difference_type(__n));
_M_deallocate();
- _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT;
+ _M_end_of_storage = __q + (__len + _M_word_bit - 1)/_M_word_bit;
_M_start = iterator(__q, 0);
}
}
@@ -705,7 +709,7 @@ template <typename _Alloc>
insert(end(), __new_size - size(), __x);
}
void flip() {
- for (unsigned int* __p = _M_start._M_p; __p != _M_end_of_storage; ++__p)
+ for (_Bit_type * __p = _M_start._M_p; __p != _M_end_of_storage; ++__p)
*__p = ~*__p;
}
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index 51bd8a013e7..685913888c8 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -1,6 +1,6 @@
// nonstandard construct and destroy functions -*- C++ -*-
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 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
@@ -67,10 +67,10 @@
namespace std
{
/**
- * @maint
+ * @if maint
* Constructs an object in existing memory by invoking an allocated
* object's constructor with an initializer.
- * @endmaint
+ * @endif
*/
template <class _T1, class _T2>
inline void
@@ -78,10 +78,10 @@ namespace std
{ new (static_cast<void*>(__p)) _T1(__value); }
/**
- * @maint
+ * @if maint
* Constructs an object in existing memory by invoking an allocated
* object's default constructor (no initializers).
- * @endmaint
+ * @endif
*/
template <class _T1>
inline void
@@ -89,11 +89,11 @@ namespace std
{ new (static_cast<void*>(__p)) _T1(); }
/**
- * @maint
+ * @if maint
* Destroy a range of objects with nontrivial destructors.
*
* This is a helper function used only by _Destroy().
- * @endmaint
+ * @endif
*/
template <class _ForwardIterator>
inline void
@@ -101,13 +101,13 @@ namespace std
{ for ( ; __first != __last; ++__first) _Destroy(&*__first); }
/**
- * @maint
+ * @if maint
* Destroy a range of objects with trivial destructors. Since the destructors
* are trivial, there's nothing to do and hopefully this function will be
* entirely optimized away.
*
* This is a helper function used only by _Destroy().
- * @endmaint
+ * @endif
*/
template <class _ForwardIterator>
inline void
@@ -115,9 +115,9 @@ namespace std
{ }
/**
- * @maint
+ * @if maint
* Destroy the object pointed to by a pointer type.
- * @endmaint
+ * @endif
*/
template <class _Tp>
inline void
@@ -125,11 +125,11 @@ namespace std
{ __pointer->~_Tp(); }
/**
- * @maint
+ * @if maint
* Destroy a range of objects. If the value_type of the object has
* a trivial destructor, the compiler should optimize all of this
* away, otherwise the objects' destructors must be invoked.
- * @endmaint
+ * @endif
*/
template <class _ForwardIterator>
inline void
@@ -146,6 +146,3 @@ namespace std
#endif /* _CPP_BITS_STL_CONSTRUCT_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 b2d58d8f0a6..cbe87796770 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -1,6 +1,6 @@
// deque implementation -*- C++ -*-
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 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
@@ -73,14 +73,14 @@ namespace std
{
/**
- * @maint
+ * @if maint
* @brief This function controls the size of memory nodes.
* @param size The size of an element.
* @return The number (not bytesize) of elements per node.
*
* This function started off as a compiler kludge from SGI, but seems to
* be a useful wrapper around a repeated constant expression.
- * @endmaint
+ * @endif
*/
inline size_t
__deque_buf_size(size_t __size)
@@ -94,9 +94,9 @@ __deque_buf_size(size_t __size)
* marking its valid range. Access to elements is done as offsets of either
* of those two, relying on operator overloading in this class.
*
- * @maint
+ * @if maint
* All the functions are op overloads except for _M_set_node.
- * @endmaint
+ * @endif
*/
template <class _Tp, class _Ref, class _Ptr>
struct _Deque_iterator
@@ -130,11 +130,6 @@ struct _Deque_iterator
reference operator*() const { return *_M_cur; }
pointer operator->() const { return _M_cur; }
- difference_type operator-(const _Self& __x) const {
- return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
- (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
- }
-
_Self& operator++() {
++_M_cur;
if (_M_cur == _M_last) {
@@ -194,21 +189,11 @@ struct _Deque_iterator
reference operator[](difference_type __n) const { return *(*this + __n); }
- bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
- bool operator!=(const _Self& __x) const { return !(*this == __x); }
- bool operator<(const _Self& __x) const {
- return (_M_node == __x._M_node) ?
- (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
- }
- bool operator>(const _Self& __x) const { return __x < *this; }
- bool operator<=(const _Self& __x) const { return !(__x < *this); }
- bool operator>=(const _Self& __x) const { return !(*this < __x); }
-
- /** @maint
+ /** @if maint
* Prepares to traverse new_node. Sets everything except _M_cur, which
* should therefore be set by the caller immediately afterwards, based on
* _M_first and _M_last.
- * @endmaint
+ * @endif
*/
void _M_set_node(_Map_pointer __new_node) {
_M_node = __new_node;
@@ -217,6 +202,123 @@ struct _Deque_iterator
}
};
+// Note: we also provide overloads whose operands are of the same type in
+// order to avoid ambiguos overload resolution when std::rel_ops operators
+// are in scope (for additional details, see libstdc++/3628)
+template <class _Tp, class _Ref, class _Ptr>
+inline bool
+operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+ const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+{
+ return __x._M_cur == __y._M_cur;
+}
+
+template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
+inline bool
+operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+ const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+{
+ return __x._M_cur == __y._M_cur;
+}
+
+template <class _Tp, class _Ref, class _Ptr>
+inline bool
+operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+ const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
+inline bool
+operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+ const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp, class _Ref, class _Ptr>
+inline bool
+operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+ const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+{
+ return (__x._M_node == __y._M_node) ?
+ (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
+}
+
+template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
+inline bool
+operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+ const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+{
+ return (__x._M_node == __y._M_node) ?
+ (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
+}
+
+template <class _Tp, class _Ref, class _Ptr>
+inline bool
+operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+ const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
+inline bool
+operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+ const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp, class _Ref, class _Ptr>
+inline bool
+operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+ const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+{
+ return !(__y < __x);
+}
+
+template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
+inline bool
+operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+ const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+{
+ return !(__y < __x);
+}
+
+template <class _Tp, class _Ref, class _Ptr>
+inline bool
+operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+ const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+{
+ return !(__x < __y);
+}
+
+template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
+inline bool
+operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+ const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+{
+ return !(__x < __y);
+}
+
+// _GLIBCPP_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 _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,
+ const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+{
+ return _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
+ (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) *
+ (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) +
+ (__y._M_last - __y._M_cur);
+}
+
template <class _Tp, class _Ref, class _Ptr>
inline _Deque_iterator<_Tp, _Ref, _Ptr>
operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
@@ -225,16 +327,16 @@ operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
}
-/// @maint Primary default version. @endmaint
+/// @if maint Primary default version. @endif
/**
- * @maint
+ * @if maint
* Deque base class. It has two purposes. First, its constructor
* and destructor allocate (but don't initialize) storage. This makes
* exception safety easier. Second, the base class encapsulates all of
* the differences between SGI-style allocators and standard-conforming
* allocators. There are two versions: this ordinary one, and the
* space-saving specialization for instanceless allocators.
- * @endmaint
+ * @endif
*/
template <class _Tp, class _Alloc, bool __is_static>
class _Deque_alloc_base
@@ -270,7 +372,7 @@ protected:
size_t _M_map_size;
};
-/// Specialization for instanceless allocators.
+/// @if maint Specialization for instanceless allocators. @endif
template <class _Tp, class _Alloc>
class _Deque_alloc_base<_Tp, _Alloc, true>
{
@@ -301,14 +403,14 @@ protected:
/**
- * @maint
+ * @if maint
* Deque base class. Using _Alloc_traits in the instantiation of the parent
* class provides the compile-time dispatching mentioned in the parent's docs.
* This class provides the unified face for deque's allocation.
*
* Nothing in this class ever constructs or destroys an actual Tp element.
* (Deque handles that itself.) Only/All memory management is performed here.
- * @endmaint
+ * @endif
*/
template <class _Tp, class _Alloc>
class _Deque_base
@@ -352,13 +454,13 @@ _Deque_base<_Tp,_Alloc>::~_Deque_base()
}
/**
- * @maint
+ * @if maint
* @brief Layout storage.
* @param num_elements The count of T's for which to allocate space at first.
* @return Nothing.
*
* The initial underlying memory layout is a bit complicated...
- * @endmaint
+ * @endif
*/
template <class _Tp, class _Alloc>
void
@@ -415,6 +517,14 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
/**
+ * @ingroup Containers
+ * @ingroup Sequences
+ *
+ * Meets the requirements of a <a href="tables.html#65">container</a>, a
+ * <a href="tables.html#66">reversible container</a>, and a
+ * <a href="tables.html#67">sequence</a>, including the
+ * <a href="tables.html#68">optional sequence requirements</a>.
+ *
* Placeholder: see http://www.sgi.com/tech/stl/Deque.html for now.
*
* In previous HP/SGI versions of deque, there was an extra template parameter
@@ -422,14 +532,15 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
* the C++ standard (it can be detected using template template parameters),
* and it was removed.
*
- * @maint
+ * @if maint
* Here's how a deque<Tp> manages memory. Each deque has 4 members:
*
* - Tp** _M_map
* - size_t _M_map_size
* - iterator _M_start, _M_finish
*
- * map_size is at least 8. map is an array of map_size pointers-to-"nodes".
+ * map_size is at least 8. %map is an array of map_size pointers-to-"nodes".
+ * (The name has nothing to do with the std::map class.)
*
* A "node" has no specific type name as such, but it is referred to as
* "node" in this file. It is a simple array-of-Tp. If Tp is very large,
@@ -443,18 +554,18 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
* memory pool. There are 20 hours left in the year; perhaps I can fix
* this before 2002.
*
- * Not every pointer in the map array will point to a node. If the initial
- * number of elements in the deque is small, the /middle/ map pointers will
+ * Not every pointer in the %map array will point to a node. If the initial
+ * number of elements in the deque is small, the /middle/ %map pointers will
* be valid, and the ones at the edges will be unused. This same situation
- * will arise as the map grows: available map pointers, if any, will be on
- * the ends. As new nodes are created, only a subset of the map's pointers
+ * will arise as the %map grows: available %map pointers, if any, will be on
+ * the ends. As new nodes are created, only a subset of the %map's pointers
* need to be copied "outward".
*
* Class invariants:
* - For any nonsingular iterator i:
- * - i.node points to a member of the map array. (Yes, you read that
+ * - i.node points to a member of the %map array. (Yes, you read that
* correctly: i.node does not actually point to a node.) The member of
- * the map array is what actually points to the node.
+ * the %map array is what actually points to the node.
* - i.first == *(i.node) (This points to the node (first Tp element).)
* - i.last == i.first + node_size
* - i.cur is a pointer in the range [i.first, i.last). NOTE:
@@ -470,10 +581,10 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
* that range are uninitialized storage. Otherwise, [start.cur, start.last)
* and [finish.first, finish.cur) are initialized objects, and [start.first,
* start.cur) and [finish.cur, finish.last) are uninitialized storage.
- * - [map, map + map_size) is a valid, non-empty range.
+ * - [%map, %map + map_size) is a valid, non-empty range.
* - [start.node, finish.node] is a valid range contained within
- * [map, map + map_size).
- * - A pointer in the range [map, map + map_size) points to an allocated node
+ * [%map, %map + map_size).
+ * - A pointer in the range [%map, %map + map_size) points to an allocated node
* if and only if the pointer is in the range [start.node, finish.node].
*
* Here's the magic: nothing in deque is "aware" of the discontiguous storage!
@@ -483,8 +594,7 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
* the implementation routines for deque itself work only through the start
* and finish iterators. This keeps the routines simple and sane, and we can
* use other standard algorithms as well.
- *
- * @endmaint
+ * @endif
*/
template <class _Tp, class _Alloc = allocator<_Tp> >
class deque : protected _Deque_base<_Tp, _Alloc>
@@ -524,11 +634,11 @@ protected:
using _Base::_M_allocate_map;
using _Base::_M_deallocate_map;
- /** @maint
+ /** @if maint
* A total of four data members accumulated down the heirarchy. If the
* _Alloc type requires separate instances, then two of them will also be
* included in each deque.
- * @endmaint
+ * @endif
*/
using _Base::_M_map;
using _Base::_M_map_size;
@@ -555,7 +665,7 @@ public: // Basic accessors
void _M_range_check(size_type __n) const {
if (__n >= this->size())
- __throw_range_error("deque");
+ __throw_out_of_range("deque");
}
reference at(size_type __n)
@@ -1035,7 +1145,7 @@ void deque<_Tp,_Alloc>::clear()
}
/**
- * @maint
+ * @if maint
* @brief Fills the deque with copies of value.
* @param value Initial value.
* @return Nothing.
@@ -1044,7 +1154,7 @@ void deque<_Tp,_Alloc>::clear()
*
* This function is called only when the user provides an explicit size (with
* or without an explicit exemplar value).
- * @endmaint
+ * @endif
*/
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value)
@@ -1063,7 +1173,7 @@ void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value)
}
/** @{
- * @maint
+ * @if maint
* @brief Fills the deque with whatever is in [first,last).
* @param first An input iterator.
* @param last An input iterator.
@@ -1072,7 +1182,7 @@ void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value)
* If the iterators are actually forward iterators (or better), then the
* memory layout can be done all at once. Else we move forward using
* push_back on each value from the iterator.
- * @endmaint
+ * @endif
*/
template <class _Tp, class _Alloc> template <class _InputIterator>
void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
@@ -1570,6 +1680,3 @@ inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) {
#endif /* __GLIBCPP_INTERNAL_DEQUE_H */
-// Local Variables:
-// mode:C++
-// End:
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index b42181f5ba2..6fb0d81339f 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -548,7 +548,10 @@ namespace std
return insert_iterator<_Container>(__x,
typename _Container::iterator(__i));
}
-
+} // namespace std
+
+namespace __gnu_cxx
+{
// This iterator adapter is 'normal' in the sense that it does not
// change the semantics of any of the operators of its iterator
// parameter. Its primary purpose is to convert an iterator that is
@@ -556,6 +559,8 @@ namespace std
// The _Container parameter exists solely so that different containers
// using this template can instantiate different types, even if the
// _Iterator parameter is the same.
+ using std::iterator_traits;
+ using std::iterator;
template<typename _Iterator, typename _Container>
class __normal_iterator
: public iterator<typename iterator_traits<_Iterator>::iterator_category,
@@ -624,14 +629,18 @@ namespace std
operator-(const difference_type& __n) const
{ return __normal_iterator(_M_current - __n); }
- difference_type
- operator-(const __normal_iterator& __i) const
- { return _M_current - __i._M_current; }
-
const _Iterator&
base() const { return _M_current; }
};
+ // Note: In what follows, the left- and right-hand-side iterators are
+ // allowed to vary in types (conceptually in cv-qualification) so that
+ // comparaison between cv-qualified and non-cv-qualified iterators be
+ // valid. However, the greedy and unfriendly operators in std::rel_ops
+ // will make overload resolution ambiguous (when in scope) if we don't
+ // provide overloads whose operands are of the same type. Can someone
+ // remind me what generic programming is about? -- Gaby
+
// Forward iterator requirements
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
@@ -639,11 +648,23 @@ namespace std
const __normal_iterator<_IteratorR, _Container>& __rhs)
{ return __lhs.base() == __rhs.base(); }
+ template<typename _Iterator, typename _Container>
+ inline bool
+ operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+ { return __lhs.base() == __rhs.base(); }
+
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
- { return !(__lhs == __rhs); }
+ { return __lhs.base() != __rhs.base(); }
+
+ template<typename _Iterator, typename _Container>
+ inline bool
+ operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+ { return __lhs.base() != __rhs.base(); }
// Random access iterator requirements
template<typename _IteratorL, typename _IteratorR, typename _Container>
@@ -652,30 +673,64 @@ namespace std
const __normal_iterator<_IteratorR, _Container>& __rhs)
{ return __lhs.base() < __rhs.base(); }
+ template<typename _Iterator, typename _Container>
+ inline bool
+ operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+ { return __lhs.base() < __rhs.base(); }
+
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
- { return __rhs < __lhs; }
+ { return __lhs.base() > __rhs.base(); }
+
+ template<typename _Iterator, typename _Container>
+ inline bool
+ operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+ { return __lhs.base() > __rhs.base(); }
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
- { return !(__rhs < __lhs); }
+ { return __lhs.base() <= __rhs.base(); }
+
+ template<typename _Iterator, typename _Container>
+ inline bool
+ operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+ { return __lhs.base() <= __rhs.base(); }
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
- { return !(__lhs < __rhs); }
+ { return __lhs.base() >= __rhs.base(); }
+
+ template<typename _Iterator, typename _Container>
+ inline bool
+ operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
+ const __normal_iterator<_Iterator, _Container>& __rhs)
+ { return __lhs.base() >= __rhs.base(); }
+
+ // _GLIBCPP_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 _Container>
+ inline typename __normal_iterator<_IteratorL, _Container>::difference_type
+ operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return __lhs.base() - __rhs.base(); }
template<typename _Iterator, typename _Container>
inline __normal_iterator<_Iterator, _Container>
operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n,
const __normal_iterator<_Iterator, _Container>& __i)
{ return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
-} // namespace std
+} // namespace __gnu_cxx
#endif
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_types.h b/libstdc++-v3/include/bits/stl_iterator_base_types.h
index e5b3fa461b4..5dff8fc3f44 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_types.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_types.h
@@ -146,10 +146,10 @@ namespace std
};
/**
- * @maint
+ * @if maint
* This function is not a part of the C++ standard but is syntactic
* sugar for internal library use only.
- * @endmaint
+ * @endif
*/
template<typename _Iter>
inline typename iterator_traits<_Iter>::iterator_category
@@ -160,7 +160,3 @@ namespace std
#endif /* __GLIBCPP_INTERNAL_ITERATOR_BASE_TYPES_H */
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index 99205791387..3d470b1f25f 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1,6 +1,6 @@
// List implementation -*- C++ -*-
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 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
@@ -273,7 +273,19 @@ namespace std
void clear();
};
-
+ /**
+ * @ingroup Containers
+ * @ingroup Sequences
+ *
+ * Meets the requirements of a <a href="tables.html#65">container</a>, a
+ * <a href="tables.html#66">reversible container</a>, and a
+ * <a href="tables.html#67">sequence</a>, including the
+ * <a href="tables.html#68">optional sequence requirements</a> with the
+ * %exception of @c at and @c operator[].
+ *
+ * @doctodo
+ *
+ */
template<typename _Tp, typename _Alloc = allocator<_Tp> >
class list : protected _List_base<_Tp, _Alloc>
{
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index d689ccc8d27..b0411b2becc 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -95,7 +95,7 @@ inline bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
return __x.first == __y.first && __x.second == __y.second;
}
-/// http://gcc.gnu.org/onlinedocs/libstdc++/20_util/howto.html#pairlt
+/// <http://gcc.gnu.org/onlinedocs/libstdc++/20_util/howto.html#pairlt>
template <class _T1, class _T2>
inline bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{
diff --git a/libstdc++-v3/include/bits/stl_relops.h b/libstdc++-v3/include/bits/stl_relops.h
index cc1ef782647..ce3dc0b9b39 100644
--- a/libstdc++-v3/include/bits/stl_relops.h
+++ b/libstdc++-v3/include/bits/stl_relops.h
@@ -57,7 +57,7 @@
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*
- * @maint
+ * @if maint
* Inclusion of this file has been removed from
* all of the other STL headers for safety reasons, except std_utility.h.
* For more information, see the thread of about twenty messages starting
@@ -65,7 +65,7 @@
* FAQ at http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#4_4 .
*
* Short summary: the rel_ops operators should be avoided for the present.
- * @endmaint
+ * @endif
*/
#ifndef _CPP_BITS_STL_RELOPS_H
diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h
index 088807fb82d..7b88f9333ec 100644
--- a/libstdc++-v3/include/bits/stl_tempbuf.h
+++ b/libstdc++-v3/include/bits/stl_tempbuf.h
@@ -65,11 +65,11 @@ namespace std
{
/**
- * @maint
+ * @if maint
* This class is used in two places: stl_algo.h and ext/memory, where it
* is wrapped as the temporary_buffer class. See temporary_buffer docs for
* more notes.
- * @endmaint
+ * @endif
*/
template <class _ForwardIterator, class _Tp>
class _Temporary_buffer
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index ef50c9ee38a..d2ae142e926 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -90,1207 +90,1373 @@ iterators invalidated are those referring to the deleted node.
namespace std
{
- typedef bool _Rb_tree_Color_type;
- extern const _Rb_tree_Color_type _S_rb_tree_red; // false
- extern const _Rb_tree_Color_type _S_rb_tree_black; // true
+ enum _Rb_tree_color { _M_red = false, _M_black = true };
-struct _Rb_tree_node_base
-{
- typedef _Rb_tree_Color_type _Color_type;
- typedef _Rb_tree_node_base* _Base_ptr;
+ struct _Rb_tree_node_base
+ {
+ typedef _Rb_tree_node_base* _Base_ptr;
+
+ _Rb_tree_color _M_color;
+ _Base_ptr _M_parent;
+ _Base_ptr _M_left;
+ _Base_ptr _M_right;
+
+ static _Base_ptr
+ _S_minimum(_Base_ptr __x)
+ {
+ while (__x->_M_left != 0) __x = __x->_M_left;
+ return __x;
+ }
- _Color_type _M_color;
- _Base_ptr _M_parent;
- _Base_ptr _M_left;
- _Base_ptr _M_right;
+ static _Base_ptr
+ _S_maximum(_Base_ptr __x)
+ {
+ while (__x->_M_right != 0) __x = __x->_M_right;
+ return __x;
+ }
+ };
- static _Base_ptr _S_minimum(_Base_ptr __x)
+ template<typename _Val>
+ struct _Rb_tree_node : public _Rb_tree_node_base
+ {
+ typedef _Rb_tree_node<_Val>* _Link_type;
+ _Val _M_value_field;
+ };
+
+ struct _Rb_tree_base_iterator
{
- while (__x->_M_left != 0) __x = __x->_M_left;
- return __x;
- }
+ typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
+ typedef bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+
+ _Base_ptr _M_node;
+
+ void
+ _M_increment()
+ {
+ if (_M_node->_M_right != 0)
+ {
+ _M_node = _M_node->_M_right;
+ while (_M_node->_M_left != 0)
+ _M_node = _M_node->_M_left;
+ }
+ else
+ {
+ _Base_ptr __y = _M_node->_M_parent;
+ while (_M_node == __y->_M_right)
+ {
+ _M_node = __y;
+ __y = __y->_M_parent;
+ }
+ if (_M_node->_M_right != __y)
+ _M_node = __y;
+ }
+ }
+
+ void
+ _M_decrement()
+ {
+ if (_M_node->_M_color == _M_red
+ && _M_node->_M_parent->_M_parent == _M_node)
+ _M_node = _M_node->_M_right;
+ else if (_M_node->_M_left != 0)
+ {
+ _Base_ptr __y = _M_node->_M_left;
+ while (__y->_M_right != 0)
+ __y = __y->_M_right;
+ _M_node = __y;
+ }
+ else
+ {
+ _Base_ptr __y = _M_node->_M_parent;
+ while (_M_node == __y->_M_left)
+ {
+ _M_node = __y;
+ __y = __y->_M_parent;
+ }
+ _M_node = __y;
+ }
+ }
+ };
+
+ template<typename _Val, typename _Ref, typename _Ptr>
+ struct _Rb_tree_iterator : public _Rb_tree_base_iterator
+ {
+ typedef _Val value_type;
+ typedef _Ref reference;
+ typedef _Ptr pointer;
+ typedef _Rb_tree_iterator<_Val, _Val&, _Val*> iterator;
+ typedef _Rb_tree_iterator<_Val, const _Val&, const _Val*>
+ const_iterator;
+ typedef _Rb_tree_iterator<_Val, _Ref, _Ptr> _Self;
+ typedef _Rb_tree_node<_Val>* _Link_type;
+
+ _Rb_tree_iterator() {}
+ _Rb_tree_iterator(_Link_type __x) { _M_node = __x; }
+ _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; }
+
+ reference
+ operator*() const { return _Link_type(_M_node)->_M_value_field; }
+
+ pointer
+ operator->() const { return &(operator*()); }
+
+ _Self&
+ operator++()
+ {
+ _M_increment();
+ return *this;
+ }
- static _Base_ptr _S_maximum(_Base_ptr __x)
+ _Self
+ operator++(int)
+ {
+ _Self __tmp = *this;
+ _M_increment();
+ return __tmp;
+ }
+
+ _Self&
+ operator--() { _M_decrement(); return *this; }
+
+ _Self
+ operator--(int)
+ {
+ _Self __tmp = *this;
+ _M_decrement();
+ return __tmp;
+ }
+ };
+
+ template<typename _Val, typename _Ref, typename _Ptr>
+ inline bool
+ operator==(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x,
+ const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y)
+ { return __x._M_node == __y._M_node; }
+
+ template<typename _Val>
+ inline bool
+ operator==(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x,
+ const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y)
+ { return __x._M_node == __y._M_node; }
+
+ template<typename _Val>
+ inline bool
+ operator==(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x,
+ const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y)
+ { return __x._M_node == __y._M_node; }
+
+ template<typename _Val, typename _Ref, typename _Ptr>
+ inline bool
+ operator!=(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x,
+ const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y)
+ { return __x._M_node != __y._M_node; }
+
+ template<typename _Val>
+ inline bool
+ operator!=(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x,
+ const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y)
+ { return __x._M_node != __y._M_node; }
+
+ template<typename _Val>
+ inline bool
+ operator!=(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x,
+ const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y)
+ { return __x._M_node != __y._M_node; }
+
+ inline void
+ _Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
{
- while (__x->_M_right != 0) __x = __x->_M_right;
- return __x;
+ _Rb_tree_node_base* __y = __x->_M_right;
+ __x->_M_right = __y->_M_left;
+ if (__y->_M_left !=0)
+ __y->_M_left->_M_parent = __x;
+ __y->_M_parent = __x->_M_parent;
+
+ if (__x == __root)
+ __root = __y;
+ else if (__x == __x->_M_parent->_M_left)
+ __x->_M_parent->_M_left = __y;
+ else
+ __x->_M_parent->_M_right = __y;
+ __y->_M_left = __x;
+ __x->_M_parent = __y;
}
-};
-
-template <class _Value>
-struct _Rb_tree_node : public _Rb_tree_node_base
-{
- typedef _Rb_tree_node<_Value>* _Link_type;
- _Value _M_value_field;
-};
+ inline void
+ _Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
+ {
+ _Rb_tree_node_base* __y = __x->_M_left;
+ __x->_M_left = __y->_M_right;
+ if (__y->_M_right != 0)
+ __y->_M_right->_M_parent = __x;
+ __y->_M_parent = __x->_M_parent;
-struct _Rb_tree_base_iterator
-{
- typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
- typedef bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
- _Base_ptr _M_node;
+ if (__x == __root)
+ __root = __y;
+ else if (__x == __x->_M_parent->_M_right)
+ __x->_M_parent->_M_right = __y;
+ else
+ __x->_M_parent->_M_left = __y;
+ __y->_M_right = __x;
+ __x->_M_parent = __y;
+ }
- void _M_increment()
+ inline void
+ _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
{
- if (_M_node->_M_right != 0) {
- _M_node = _M_node->_M_right;
- while (_M_node->_M_left != 0)
- _M_node = _M_node->_M_left;
- }
- else {
- _Base_ptr __y = _M_node->_M_parent;
- while (_M_node == __y->_M_right) {
- _M_node = __y;
- __y = __y->_M_parent;
+ __x->_M_color = _M_red;
+ while (__x != __root
+ && __x->_M_parent->_M_color == _M_red)
+ {
+ if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left)
+ {
+ _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right;
+ if (__y && __y->_M_color == _M_red)
+ {
+ __x->_M_parent->_M_color = _M_black;
+ __y->_M_color = _M_black;
+ __x->_M_parent->_M_parent->_M_color = _M_red;
+ __x = __x->_M_parent->_M_parent;
+ }
+ else
+ {
+ if (__x == __x->_M_parent->_M_right)
+ {
+ __x = __x->_M_parent;
+ _Rb_tree_rotate_left(__x, __root);
+ }
+ __x->_M_parent->_M_color = _M_black;
+ __x->_M_parent->_M_parent->_M_color = _M_red;
+ _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root);
+ }
+ }
+ else
+ {
+ _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left;
+ if (__y && __y->_M_color == _M_red)
+ {
+ __x->_M_parent->_M_color = _M_black;
+ __y->_M_color = _M_black;
+ __x->_M_parent->_M_parent->_M_color = _M_red;
+ __x = __x->_M_parent->_M_parent;
+ }
+ else
+ {
+ if (__x == __x->_M_parent->_M_left)
+ {
+ __x = __x->_M_parent;
+ _Rb_tree_rotate_right(__x, __root);
+ }
+ __x->_M_parent->_M_color = _M_black;
+ __x->_M_parent->_M_parent->_M_color = _M_red;
+ _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root);
+ }
+ }
}
- if (_M_node->_M_right != __y)
- _M_node = __y;
- }
+ __root->_M_color = _M_black;
}
- void _M_decrement()
+ inline _Rb_tree_node_base*
+ _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z,
+ _Rb_tree_node_base*& __root,
+ _Rb_tree_node_base*& __leftmost,
+ _Rb_tree_node_base*& __rightmost)
{
- if (_M_node->_M_color == _S_rb_tree_red &&
- _M_node->_M_parent->_M_parent == _M_node)
- _M_node = _M_node->_M_right;
- else if (_M_node->_M_left != 0) {
- _Base_ptr __y = _M_node->_M_left;
- while (__y->_M_right != 0)
- __y = __y->_M_right;
- _M_node = __y;
- }
- else {
- _Base_ptr __y = _M_node->_M_parent;
- while (_M_node == __y->_M_left) {
- _M_node = __y;
- __y = __y->_M_parent;
+ _Rb_tree_node_base* __y = __z;
+ _Rb_tree_node_base* __x = 0;
+ _Rb_tree_node_base* __x_parent = 0;
+ if (__y->_M_left == 0) // __z has at most one non-null child. y == z.
+ __x = __y->_M_right; // __x might be null.
+ else
+ if (__y->_M_right == 0) // __z has exactly one non-null child. y == z.
+ __x = __y->_M_left; // __x is not null.
+ else
+ {
+ // __z has two non-null children. Set __y to
+ __y = __y->_M_right; // __z's successor. __x might be null.
+ while (__y->_M_left != 0)
+ __y = __y->_M_left;
+ __x = __y->_M_right;
+ }
+ if (__y != __z)
+ {
+ // relink y in place of z. y is z's successor
+ __z->_M_left->_M_parent = __y;
+ __y->_M_left = __z->_M_left;
+ if (__y != __z->_M_right)
+ {
+ __x_parent = __y->_M_parent;
+ if (__x) __x->_M_parent = __y->_M_parent;
+ __y->_M_parent->_M_left = __x; // __y must be a child of _M_left
+ __y->_M_right = __z->_M_right;
+ __z->_M_right->_M_parent = __y;
+ }
+ else
+ __x_parent = __y;
+ if (__root == __z)
+ __root = __y;
+ else if (__z->_M_parent->_M_left == __z)
+ __z->_M_parent->_M_left = __y;
+ else
+ __z->_M_parent->_M_right = __y;
+ __y->_M_parent = __z->_M_parent;
+ std::swap(__y->_M_color, __z->_M_color);
+ __y = __z;
+ // __y now points to node to be actually deleted
}
- _M_node = __y;
- }
- }
-};
-
-template <class _Value, class _Ref, class _Ptr>
-struct _Rb_tree_iterator : public _Rb_tree_base_iterator
-{
- typedef _Value value_type;
- typedef _Ref reference;
- typedef _Ptr pointer;
- typedef _Rb_tree_iterator<_Value, _Value&, _Value*>
- iterator;
- typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*>
- const_iterator;
- typedef _Rb_tree_iterator<_Value, _Ref, _Ptr>
- _Self;
- typedef _Rb_tree_node<_Value>* _Link_type;
-
- _Rb_tree_iterator() {}
- _Rb_tree_iterator(_Link_type __x) { _M_node = __x; }
- _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; }
-
- reference operator*() const { return _Link_type(_M_node)->_M_value_field; }
- pointer operator->() const { return &(operator*()); }
-
- _Self& operator++() { _M_increment(); return *this; }
- _Self operator++(int) {
- _Self __tmp = *this;
- _M_increment();
- return __tmp;
- }
-
- _Self& operator--() { _M_decrement(); return *this; }
- _Self operator--(int) {
- _Self __tmp = *this;
- _M_decrement();
- return __tmp;
+ else
+ { // __y == __z
+ __x_parent = __y->_M_parent;
+ if (__x)
+ __x->_M_parent = __y->_M_parent;
+ if (__root == __z)
+ __root = __x;
+ else
+ if (__z->_M_parent->_M_left == __z)
+ __z->_M_parent->_M_left = __x;
+ else
+ __z->_M_parent->_M_right = __x;
+ if (__leftmost == __z)
+ if (__z->_M_right == 0) // __z->_M_left must be null also
+ __leftmost = __z->_M_parent;
+ // makes __leftmost == _M_header if __z == __root
+ else
+ __leftmost = _Rb_tree_node_base::_S_minimum(__x);
+ if (__rightmost == __z)
+ if (__z->_M_left == 0) // __z->_M_right must be null also
+ __rightmost = __z->_M_parent;
+ // makes __rightmost == _M_header if __z == __root
+ else // __x == __z->_M_left
+ __rightmost = _Rb_tree_node_base::_S_maximum(__x);
+ }
+ if (__y->_M_color != _M_red)
+ {
+ while (__x != __root && (__x == 0 || __x->_M_color == _M_black))
+ if (__x == __x_parent->_M_left)
+ {
+ _Rb_tree_node_base* __w = __x_parent->_M_right;
+ if (__w->_M_color == _M_red)
+ {
+ __w->_M_color = _M_black;
+ __x_parent->_M_color = _M_red;
+ _Rb_tree_rotate_left(__x_parent, __root);
+ __w = __x_parent->_M_right;
+ }
+ if ((__w->_M_left == 0 ||
+ __w->_M_left->_M_color == _M_black) &&
+ (__w->_M_right == 0 ||
+ __w->_M_right->_M_color == _M_black))
+ {
+ __w->_M_color = _M_red;
+ __x = __x_parent;
+ __x_parent = __x_parent->_M_parent;
+ }
+ else
+ {
+ if (__w->_M_right == 0
+ || __w->_M_right->_M_color == _M_black)
+ {
+ if (__w->_M_left) __w->_M_left->_M_color = _M_black;
+ __w->_M_color = _M_red;
+ _Rb_tree_rotate_right(__w, __root);
+ __w = __x_parent->_M_right;
+ }
+ __w->_M_color = __x_parent->_M_color;
+ __x_parent->_M_color = _M_black;
+ if (__w->_M_right)
+ __w->_M_right->_M_color = _M_black;
+ _Rb_tree_rotate_left(__x_parent, __root);
+ break;
+ }
+ }
+ else
+ {
+ // same as above, with _M_right <-> _M_left.
+ _Rb_tree_node_base* __w = __x_parent->_M_left;
+ if (__w->_M_color == _M_red)
+ {
+ __w->_M_color = _M_black;
+ __x_parent->_M_color = _M_red;
+ _Rb_tree_rotate_right(__x_parent, __root);
+ __w = __x_parent->_M_left;
+ }
+ if ((__w->_M_right == 0 ||
+ __w->_M_right->_M_color == _M_black) &&
+ (__w->_M_left == 0 ||
+ __w->_M_left->_M_color == _M_black))
+ {
+ __w->_M_color = _M_red;
+ __x = __x_parent;
+ __x_parent = __x_parent->_M_parent;
+ }
+ else
+ {
+ if (__w->_M_left == 0 || __w->_M_left->_M_color == _M_black)
+ {
+ if (__w->_M_right) __w->_M_right->_M_color = _M_black;
+ __w->_M_color = _M_red;
+ _Rb_tree_rotate_left(__w, __root);
+ __w = __x_parent->_M_left;
+ }
+ __w->_M_color = __x_parent->_M_color;
+ __x_parent->_M_color = _M_black;
+ if (__w->_M_left)
+ __w->_M_left->_M_color = _M_black;
+ _Rb_tree_rotate_right(__x_parent, __root);
+ break;
+ }
+ }
+ if (__x) __x->_M_color = _M_black;
+ }
+ return __y;
}
-};
-
-template <class _Value, class _Ref, class _Ptr>
-inline bool operator==(const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __x,
- const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __y) {
- return __x._M_node == __y._M_node;
-}
-
-template <class _Value>
-inline bool operator==(const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __x,
- const _Rb_tree_iterator<_Value, _Value&, _Value*>& __y) {
- return __x._M_node == __y._M_node;
-}
-
-template <class _Value>
-inline bool operator==(const _Rb_tree_iterator<_Value, _Value&, _Value*>& __x,
- const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __y) {
- return __x._M_node == __y._M_node;
-}
-
-template <class _Value, class _Ref, class _Ptr>
-inline bool operator!=(const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __x,
- const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __y) {
- return __x._M_node != __y._M_node;
-}
-
-template <class _Value>
-inline bool operator!=(const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __x,
- const _Rb_tree_iterator<_Value, _Value&, _Value*>& __y) {
- return __x._M_node != __y._M_node;
-}
-
-template <class _Value>
-inline bool operator!=(const _Rb_tree_iterator<_Value, _Value&, _Value*>& __x,
- const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __y) {
- return __x._M_node != __y._M_node;
-}
-
-inline void
-_Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
-{
- _Rb_tree_node_base* __y = __x->_M_right;
- __x->_M_right = __y->_M_left;
- if (__y->_M_left !=0)
- __y->_M_left->_M_parent = __x;
- __y->_M_parent = __x->_M_parent;
-
- if (__x == __root)
- __root = __y;
- else if (__x == __x->_M_parent->_M_left)
- __x->_M_parent->_M_left = __y;
- else
- __x->_M_parent->_M_right = __y;
- __y->_M_left = __x;
- __x->_M_parent = __y;
-}
-
-inline void
-_Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
-{
- _Rb_tree_node_base* __y = __x->_M_left;
- __x->_M_left = __y->_M_right;
- if (__y->_M_right != 0)
- __y->_M_right->_M_parent = __x;
- __y->_M_parent = __x->_M_parent;
-
- if (__x == __root)
- __root = __y;
- else if (__x == __x->_M_parent->_M_right)
- __x->_M_parent->_M_right = __y;
- else
- __x->_M_parent->_M_left = __y;
- __y->_M_right = __x;
- __x->_M_parent = __y;
-}
-
-inline void
-_Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
-{
- __x->_M_color = _S_rb_tree_red;
- while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) {
- if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) {
- _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right;
- if (__y && __y->_M_color == _S_rb_tree_red) {
- __x->_M_parent->_M_color = _S_rb_tree_black;
- __y->_M_color = _S_rb_tree_black;
- __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
- __x = __x->_M_parent->_M_parent;
+
+ // Base class to encapsulate the differences between old SGI-style
+ // allocators and standard-conforming allocators. In order to avoid
+ // having an empty base class, we arbitrarily move one of rb_tree's
+ // data members into the base class.
+
+ // _Base for general standard-conforming allocators.
+ template<typename _Tp, typename _Alloc, bool _S_instanceless>
+ class _Rb_tree_alloc_base
+ {
+ public:
+ typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
+
+ allocator_type
+ get_allocator() const { return _M_node_allocator; }
+
+ _Rb_tree_alloc_base(const allocator_type& __a)
+ : _M_node_allocator(__a), _M_header(0) {}
+
+ protected:
+ typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type
+ _M_node_allocator;
+
+ _Rb_tree_node<_Tp>* _M_header;
+
+ _Rb_tree_node<_Tp>*
+ _M_get_node() { return _M_node_allocator.allocate(1); }
+
+ void
+ _M_put_node(_Rb_tree_node<_Tp>* __p)
+ { _M_node_allocator.deallocate(__p, 1); }
+ };
+
+ // Specialization for instanceless allocators.
+ template<typename _Tp, typename _Alloc>
+ class _Rb_tree_alloc_base<_Tp, _Alloc, true>
+ {
+ public:
+ typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
+ allocator_type get_allocator() const { return allocator_type(); }
+
+ _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {}
+
+ protected:
+ _Rb_tree_node<_Tp>* _M_header;
+
+ typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type
+ _Alloc_type;
+
+ _Rb_tree_node<_Tp>*
+ _M_get_node() { return _Alloc_type::allocate(1); }
+
+ void
+ _M_put_node(_Rb_tree_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
+ };
+
+ template<typename _Tp, typename _Alloc>
+ struct _Rb_tree_base : public _Rb_tree_alloc_base<_Tp, _Alloc,
+ _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+ {
+ typedef _Rb_tree_alloc_base<_Tp,
+ _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base;
+ typedef typename _Base::allocator_type allocator_type;
+
+ _Rb_tree_base(const allocator_type& __a)
+ : _Base(__a) { _M_header = _M_get_node(); }
+ ~_Rb_tree_base() { _M_put_node(_M_header); }
+ };
+
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc = allocator<_Val> >
+ class _Rb_tree : protected _Rb_tree_base<_Val, _Alloc>
+ {
+ typedef _Rb_tree_base<_Val, _Alloc> _Base;
+
+ protected:
+ typedef _Rb_tree_node_base* _Base_ptr;
+ typedef _Rb_tree_node<_Val> _Rb_tree_node;
+
+ public:
+ typedef _Key key_type;
+ typedef _Val value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef _Rb_tree_node* _Link_type;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ typedef typename _Base::allocator_type allocator_type;
+ allocator_type get_allocator() const { return _Base::get_allocator(); }
+
+ protected:
+ using _Base::_M_get_node;
+ using _Base::_M_put_node;
+ using _Base::_M_header;
+
+ _Link_type
+ _M_create_node(const value_type& __x)
+ {
+ _Link_type __tmp = _M_get_node();
+ try
+ { _Construct(&__tmp->_M_value_field, __x); }
+ catch(...)
+ {
+ _M_put_node(__tmp);
+ __throw_exception_again;
+ }
+ return __tmp;
}
- else {
- if (__x == __x->_M_parent->_M_right) {
- __x = __x->_M_parent;
- _Rb_tree_rotate_left(__x, __root);
- }
- __x->_M_parent->_M_color = _S_rb_tree_black;
- __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
- _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root);
+
+ _Link_type
+ _M_clone_node(_Link_type __x)
+ {
+ _Link_type __tmp = _M_create_node(__x->_M_value_field);
+ __tmp->_M_color = __x->_M_color;
+ __tmp->_M_left = 0;
+ __tmp->_M_right = 0;
+ return __tmp;
}
- }
- else {
- _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left;
- if (__y && __y->_M_color == _S_rb_tree_red) {
- __x->_M_parent->_M_color = _S_rb_tree_black;
- __y->_M_color = _S_rb_tree_black;
- __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
- __x = __x->_M_parent->_M_parent;
+
+ void
+ destroy_node(_Link_type __p)
+ {
+ _Destroy(&__p->_M_value_field);
+ _M_put_node(__p);
+ }
+
+ size_type _M_node_count; // keeps track of size of tree
+ _Compare _M_key_compare;
+
+ _Link_type&
+ _M_root() const { return (_Link_type&) _M_header->_M_parent; }
+
+ _Link_type&
+ _M_leftmost() const { return (_Link_type&) _M_header->_M_left; }
+
+ _Link_type&
+ _M_rightmost() const { return (_Link_type&) _M_header->_M_right; }
+
+ static _Link_type&
+ _S_left(_Link_type __x) { return (_Link_type&)(__x->_M_left); }
+
+ static _Link_type&
+ _S_right(_Link_type __x) { return (_Link_type&)(__x->_M_right); }
+
+ static _Link_type&
+ _S_parent(_Link_type __x) { return (_Link_type&)(__x->_M_parent); }
+
+ static reference
+ _S_value(_Link_type __x) { return __x->_M_value_field; }
+
+ static const _Key&
+ _S_key(_Link_type __x) { return _KeyOfValue()(_S_value(__x)); }
+
+ static _Rb_tree_color&
+ _S_color(_Link_type __x) { return __x->_M_color; }
+
+ static _Link_type&
+ _S_left(_Base_ptr __x) { return (_Link_type&)(__x->_M_left); }
+
+ static _Link_type&
+ _S_right(_Base_ptr __x) { return (_Link_type&)(__x->_M_right); }
+
+ static _Link_type&
+ _S_parent(_Base_ptr __x) { return (_Link_type&)(__x->_M_parent); }
+
+ static reference
+ _S_value(_Base_ptr __x) { return ((_Link_type)__x)->_M_value_field; }
+
+ static const _Key&
+ _S_key(_Base_ptr __x) { return _KeyOfValue()(_S_value(_Link_type(__x)));}
+
+ static _Rb_tree_color&
+ _S_color(_Base_ptr __x) { return (_Link_type(__x)->_M_color); }
+
+ static _Link_type
+ _S_minimum(_Link_type __x)
+ { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); }
+
+ static _Link_type
+ _S_maximum(_Link_type __x)
+ { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); }
+
+ public:
+ typedef _Rb_tree_iterator<value_type, reference, pointer> iterator;
+ typedef _Rb_tree_iterator<value_type, const_reference, const_pointer>
+ const_iterator;
+
+ typedef reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef reverse_iterator<iterator> reverse_iterator;
+
+ private:
+ iterator
+ _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
+
+ _Link_type
+ _M_copy(_Link_type __x, _Link_type __p);
+
+ void
+ _M_erase(_Link_type __x);
+
+ public:
+ // allocation/deallocation
+ _Rb_tree()
+ : _Base(allocator_type()), _M_node_count(0), _M_key_compare()
+ { _M_empty_initialize(); }
+
+ _Rb_tree(const _Compare& __comp)
+ : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp)
+ { _M_empty_initialize(); }
+
+ _Rb_tree(const _Compare& __comp, const allocator_type& __a)
+ : _Base(__a), _M_node_count(0), _M_key_compare(__comp)
+ { _M_empty_initialize(); }
+
+ _Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x)
+ : _Base(__x.get_allocator()), _M_node_count(0),
+ _M_key_compare(__x._M_key_compare)
+ {
+ if (__x._M_root() == 0)
+ _M_empty_initialize();
+ else
+ {
+ _S_color(_M_header) = _M_red;
+ _M_root() = _M_copy(__x._M_root(), _M_header);
+ _M_leftmost() = _S_minimum(_M_root());
+ _M_rightmost() = _S_maximum(_M_root());
+ }
+ _M_node_count = __x._M_node_count;
}
- else {
- if (__x == __x->_M_parent->_M_left) {
- __x = __x->_M_parent;
- _Rb_tree_rotate_right(__x, __root);
- }
- __x->_M_parent->_M_color = _S_rb_tree_black;
- __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
- _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root);
+
+ ~_Rb_tree() { clear(); }
+
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>&
+ operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x);
+
+ private:
+ void _M_empty_initialize()
+ {
+ _S_color(_M_header) = _M_red; // used to distinguish header from
+ // __root, in iterator.operator++
+ _M_root() = 0;
+ _M_leftmost() = _M_header;
+ _M_rightmost() = _M_header;
+ }
+
+ public:
+ // Accessors.
+ _Compare
+ key_comp() const { return _M_key_compare; }
+
+ iterator
+ begin() { return _M_leftmost(); }
+
+ const_iterator
+ begin() const { return _M_leftmost(); }
+
+ iterator
+ end() { return _M_header; }
+
+ const_iterator
+ end() const { return _M_header; }
+
+ reverse_iterator
+ rbegin() { return reverse_iterator(end()); }
+
+ const_reverse_iterator
+ rbegin() const { return const_reverse_iterator(end()); }
+
+ reverse_iterator
+ rend() { return reverse_iterator(begin()); }
+
+ const_reverse_iterator
+ rend() const { return const_reverse_iterator(begin()); }
+
+ bool
+ empty() const { return _M_node_count == 0; }
+
+ size_type
+ size() const { return _M_node_count; }
+
+ size_type
+ max_size() const { return size_type(-1); }
+
+ void
+ swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t)
+ {
+ std::swap(_M_header, __t._M_header);
+ std::swap(_M_node_count, __t._M_node_count);
+ std::swap(_M_key_compare, __t._M_key_compare);
}
+
+ // Insert/erase.
+ pair<iterator,bool>
+ insert_unique(const value_type& __x);
+
+ iterator
+ insert_equal(const value_type& __x);
+
+ iterator
+ insert_unique(iterator __position, const value_type& __x);
+
+ iterator
+ insert_equal(iterator __position, const value_type& __x);
+
+ template<typename _InputIterator>
+ void
+ insert_unique(_InputIterator __first, _InputIterator __last);
+
+ template<typename _InputIterator>
+ void
+ insert_equal(_InputIterator __first, _InputIterator __last);
+
+ void
+ erase(iterator __position);
+
+ size_type
+ erase(const key_type& __x);
+
+ void
+ erase(iterator __first, iterator __last);
+
+ void
+ erase(const key_type* __first, const key_type* __last);
+
+ void
+ clear()
+ {
+ if (_M_node_count != 0)
+ {
+ _M_erase(_M_root());
+ _M_leftmost() = _M_header;
+ _M_root() = 0;
+ _M_rightmost() = _M_header;
+ _M_node_count = 0;
+ }
+ }
+
+ // Set operations.
+ iterator
+ find(const key_type& __x);
+
+ const_iterator
+ find(const key_type& __x) const;
+
+ size_type
+ count(const key_type& __x) const;
+
+ iterator
+ lower_bound(const key_type& __x);
+
+ const_iterator
+ lower_bound(const key_type& __x) const;
+
+ iterator
+ upper_bound(const key_type& __x);
+
+ const_iterator
+ upper_bound(const key_type& __x) const;
+
+ pair<iterator,iterator>
+ equal_range(const key_type& __x);
+
+ pair<const_iterator, const_iterator>
+ equal_range(const key_type& __x) const;
+
+ // Debugging.
+ bool
+ __rb_verify() const;
+ };
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline bool
+ operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
+ const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
+ {
+ return __x.size() == __y.size() &&
+ equal(__x.begin(), __x.end(), __y.begin());
}
- }
- __root->_M_color = _S_rb_tree_black;
-}
-
-inline _Rb_tree_node_base*
-_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z,
- _Rb_tree_node_base*& __root,
- _Rb_tree_node_base*& __leftmost,
- _Rb_tree_node_base*& __rightmost)
-{
- _Rb_tree_node_base* __y = __z;
- _Rb_tree_node_base* __x = 0;
- _Rb_tree_node_base* __x_parent = 0;
- if (__y->_M_left == 0) // __z has at most one non-null child. y == z.
- __x = __y->_M_right; // __x might be null.
- else
- if (__y->_M_right == 0) // __z has exactly one non-null child. y == z.
- __x = __y->_M_left; // __x is not null.
- else { // __z has two non-null children. Set __y to
- __y = __y->_M_right; // __z's successor. __x might be null.
- while (__y->_M_left != 0)
- __y = __y->_M_left;
- __x = __y->_M_right;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline bool
+ operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
+ const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
+ {
+ return lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end());
}
- if (__y != __z) { // relink y in place of z. y is z's successor
- __z->_M_left->_M_parent = __y;
- __y->_M_left = __z->_M_left;
- if (__y != __z->_M_right) {
- __x_parent = __y->_M_parent;
- if (__x) __x->_M_parent = __y->_M_parent;
- __y->_M_parent->_M_left = __x; // __y must be a child of _M_left
- __y->_M_right = __z->_M_right;
- __z->_M_right->_M_parent = __y;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline bool
+ operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
+ const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
+ { return !(__x == __y); }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline bool
+ operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
+ const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
+ { return __y < __x; }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline bool
+ operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
+ const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
+ { return !(__y < __x); }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline bool
+ operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
+ const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
+ { return !(__x < __y); }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline void
+ swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>&
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x)
+ {
+ if (this != &__x)
+ {
+ // Note that _Key may be a constant type.
+ clear();
+ _M_node_count = 0;
+ _M_key_compare = __x._M_key_compare;
+ if (__x._M_root() == 0)
+ {
+ _M_root() = 0;
+ _M_leftmost() = _M_header;
+ _M_rightmost() = _M_header;
+ }
+ else
+ {
+ _M_root() = _M_copy(__x._M_root(), _M_header);
+ _M_leftmost() = _S_minimum(_M_root());
+ _M_rightmost() = _S_maximum(_M_root());
+ _M_node_count = __x._M_node_count;
+ }
+ }
+ return *this;
}
- else
- __x_parent = __y;
- if (__root == __z)
- __root = __y;
- else if (__z->_M_parent->_M_left == __z)
- __z->_M_parent->_M_left = __y;
- else
- __z->_M_parent->_M_right = __y;
- __y->_M_parent = __z->_M_parent;
- std::swap(__y->_M_color, __z->_M_color);
- __y = __z;
- // __y now points to node to be actually deleted
- }
- else { // __y == __z
- __x_parent = __y->_M_parent;
- if (__x) __x->_M_parent = __y->_M_parent;
- if (__root == __z)
- __root = __x;
- else
- if (__z->_M_parent->_M_left == __z)
- __z->_M_parent->_M_left = __x;
- else
- __z->_M_parent->_M_right = __x;
- if (__leftmost == __z)
- if (__z->_M_right == 0) // __z->_M_left must be null also
- __leftmost = __z->_M_parent;
- // makes __leftmost == _M_header if __z == __root
- else
- __leftmost = _Rb_tree_node_base::_S_minimum(__x);
- if (__rightmost == __z)
- if (__z->_M_left == 0) // __z->_M_right must be null also
- __rightmost = __z->_M_parent;
- // makes __rightmost == _M_header if __z == __root
- else // __x == __z->_M_left
- __rightmost = _Rb_tree_node_base::_S_maximum(__x);
- }
- if (__y->_M_color != _S_rb_tree_red) {
- while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black))
- if (__x == __x_parent->_M_left) {
- _Rb_tree_node_base* __w = __x_parent->_M_right;
- if (__w->_M_color == _S_rb_tree_red) {
- __w->_M_color = _S_rb_tree_black;
- __x_parent->_M_color = _S_rb_tree_red;
- _Rb_tree_rotate_left(__x_parent, __root);
- __w = __x_parent->_M_right;
- }
- if ((__w->_M_left == 0 ||
- __w->_M_left->_M_color == _S_rb_tree_black) &&
- (__w->_M_right == 0 ||
- __w->_M_right->_M_color == _S_rb_tree_black)) {
- __w->_M_color = _S_rb_tree_red;
- __x = __x_parent;
- __x_parent = __x_parent->_M_parent;
- } else {
- if (__w->_M_right == 0 ||
- __w->_M_right->_M_color == _S_rb_tree_black) {
- if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;
- __w->_M_color = _S_rb_tree_red;
- _Rb_tree_rotate_right(__w, __root);
- __w = __x_parent->_M_right;
- }
- __w->_M_color = __x_parent->_M_color;
- __x_parent->_M_color = _S_rb_tree_black;
- if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;
- _Rb_tree_rotate_left(__x_parent, __root);
- break;
- }
- } else { // same as above, with _M_right <-> _M_left.
- _Rb_tree_node_base* __w = __x_parent->_M_left;
- if (__w->_M_color == _S_rb_tree_red) {
- __w->_M_color = _S_rb_tree_black;
- __x_parent->_M_color = _S_rb_tree_red;
- _Rb_tree_rotate_right(__x_parent, __root);
- __w = __x_parent->_M_left;
- }
- if ((__w->_M_right == 0 ||
- __w->_M_right->_M_color == _S_rb_tree_black) &&
- (__w->_M_left == 0 ||
- __w->_M_left->_M_color == _S_rb_tree_black)) {
- __w->_M_color = _S_rb_tree_red;
- __x = __x_parent;
- __x_parent = __x_parent->_M_parent;
- } else {
- if (__w->_M_left == 0 ||
- __w->_M_left->_M_color == _S_rb_tree_black) {
- if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;
- __w->_M_color = _S_rb_tree_red;
- _Rb_tree_rotate_left(__w, __root);
- __w = __x_parent->_M_left;
- }
- __w->_M_color = __x_parent->_M_color;
- __x_parent->_M_color = _S_rb_tree_black;
- if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;
- _Rb_tree_rotate_right(__x_parent, __root);
- break;
- }
- }
- if (__x) __x->_M_color = _S_rb_tree_black;
- }
- return __y;
-}
-
-// Base class to encapsulate the differences between old SGI-style
-// allocators and standard-conforming allocators. In order to avoid
-// having an empty base class, we arbitrarily move one of rb_tree's
-// data members into the base class.
-
-// _Base for general standard-conforming allocators.
-template <class _Tp, class _Alloc, bool _S_instanceless>
-class _Rb_tree_alloc_base {
-public:
- typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
- allocator_type get_allocator() const { return _M_node_allocator; }
-
- _Rb_tree_alloc_base(const allocator_type& __a)
- : _M_node_allocator(__a), _M_header(0) {}
-
-protected:
- typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type
- _M_node_allocator;
- _Rb_tree_node<_Tp>* _M_header;
-
- _Rb_tree_node<_Tp>* _M_get_node()
- { return _M_node_allocator.allocate(1); }
- void _M_put_node(_Rb_tree_node<_Tp>* __p)
- { _M_node_allocator.deallocate(__p, 1); }
-};
-
-// Specialization for instanceless allocators.
-template <class _Tp, class _Alloc>
-class _Rb_tree_alloc_base<_Tp, _Alloc, true> {
-public:
- typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
- allocator_type get_allocator() const { return allocator_type(); }
-
- _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {}
-
-protected:
- _Rb_tree_node<_Tp>* _M_header;
-
- typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type
- _Alloc_type;
-
- _Rb_tree_node<_Tp>* _M_get_node()
- { return _Alloc_type::allocate(1); }
- void _M_put_node(_Rb_tree_node<_Tp>* __p)
- { _Alloc_type::deallocate(__p, 1); }
-};
-
-template <class _Tp, class _Alloc>
-struct _Rb_tree_base
- : public _Rb_tree_alloc_base<_Tp, _Alloc,
- _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-{
- typedef _Rb_tree_alloc_base<_Tp, _Alloc,
- _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
- _Base;
- typedef typename _Base::allocator_type allocator_type;
-
- _Rb_tree_base(const allocator_type& __a)
- : _Base(__a) { _M_header = _M_get_node(); }
- ~_Rb_tree_base() { _M_put_node(_M_header); }
-
-};
-
-
-template <class _Key, class _Value, class _KeyOfValue, class _Compare,
- class _Alloc = allocator<_Value> >
-class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> {
- typedef _Rb_tree_base<_Value, _Alloc> _Base;
-protected:
- typedef _Rb_tree_node_base* _Base_ptr;
- typedef _Rb_tree_node<_Value> _Rb_tree_node;
- typedef _Rb_tree_Color_type _Color_type;
-public:
- typedef _Key key_type;
- typedef _Value value_type;
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
- typedef value_type& reference;
- typedef const value_type& const_reference;
- typedef _Rb_tree_node* _Link_type;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
-
- typedef typename _Base::allocator_type allocator_type;
- allocator_type get_allocator() const { return _Base::get_allocator(); }
-
-protected:
- using _Base::_M_get_node;
- using _Base::_M_put_node;
- using _Base::_M_header;
-
-protected:
-
- _Link_type
- _M_create_node(const value_type& __x)
- {
- _Link_type __tmp = _M_get_node();
- try {
- _Construct(&__tmp->_M_value_field, __x);
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ _M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Val& __v)
+ {
+ _Link_type __x = (_Link_type) __x_;
+ _Link_type __y = (_Link_type) __y_;
+ _Link_type __z;
+
+ if (__y == _M_header || __x != 0 ||
+ _M_key_compare(_KeyOfValue()(__v), _S_key(__y)))
+ {
+ __z = _M_create_node(__v);
+ _S_left(__y) = __z; // also makes _M_leftmost() = __z
+ // when __y == _M_header
+ if (__y == _M_header)
+ {
+ _M_root() = __z;
+ _M_rightmost() = __z;
+ }
+ else if (__y == _M_leftmost())
+ _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node
+ }
+ else
+ {
+ __z = _M_create_node(__v);
+ _S_right(__y) = __z;
+ // Maintain _M_rightmost() pointing to max node.
+ if (__y == _M_rightmost())
+ _M_rightmost() = __z;
+ }
+ _S_parent(__z) = __y;
+ _S_left(__z) = 0;
+ _S_right(__z) = 0;
+ _Rb_tree_rebalance(__z, _M_header->_M_parent);
+ ++_M_node_count;
+ return iterator(__z);
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ insert_equal(const _Val& __v)
+ {
+ _Link_type __y = _M_header;
+ _Link_type __x = _M_root();
+ while (__x != 0)
+ {
+ __y = __x;
+ __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
+ _S_left(__x) : _S_right(__x);
+ }
+ return _M_insert(__x, __y, __v);
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ pair<typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator,
+ bool>
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ insert_unique(const _Val& __v)
+ {
+ _Link_type __y = _M_header;
+ _Link_type __x = _M_root();
+ bool __comp = true;
+ while (__x != 0)
+ {
+ __y = __x;
+ __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x));
+ __x = __comp ? _S_left(__x) : _S_right(__x);
+ }
+ iterator __j = iterator(__y);
+ if (__comp)
+ if (__j == begin())
+ return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
+ else
+ --__j;
+ if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
+ return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
+ return pair<iterator,bool>(__j, false);
+ }
+
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ insert_unique(iterator __position, const _Val& __v)
+ {
+ if (__position._M_node == _M_header->_M_left)
+ {
+ // begin()
+ if (size() > 0 &&
+ _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node)))
+ return _M_insert(__position._M_node, __position._M_node, __v);
+ // first argument just needs to be non-null
+ else
+ return insert_unique(__v).first;
+ }
+ else if (__position._M_node == _M_header)
+ {
+ // end()
+ if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v)))
+ return _M_insert(0, _M_rightmost(), __v);
+ else
+ return insert_unique(__v).first;
+ }
+ else
+ {
+ iterator __before = __position;
+ --__before;
+ if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v))
+ && _M_key_compare(_KeyOfValue()(__v),_S_key(__position._M_node)))
+ {
+ if (_S_right(__before._M_node) == 0)
+ return _M_insert(0, __before._M_node, __v);
+ else
+ return _M_insert(__position._M_node, __position._M_node, __v);
+ // first argument just needs to be non-null
+ }
+ else
+ return insert_unique(__v).first;
+ }
}
- catch(...)
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ insert_equal(iterator __position, const _Val& __v)
+ {
+ if (__position._M_node == _M_header->_M_left)
+ {
+ // begin()
+ if (size() > 0 &&
+ !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v)))
+ return _M_insert(__position._M_node, __position._M_node, __v);
+ // first argument just needs to be non-null
+ else
+ return insert_equal(__v);
+ }
+ else if (__position._M_node == _M_header)
+ {
+ // end()
+ if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost())))
+ return _M_insert(0, _M_rightmost(), __v);
+ else
+ return insert_equal(__v);
+ }
+ else
+ {
+ iterator __before = __position;
+ --__before;
+ if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node))
+ && !_M_key_compare(_S_key(__position._M_node),
+ _KeyOfValue()(__v)))
+ {
+ if (_S_right(__before._M_node) == 0)
+ return _M_insert(0, __before._M_node, __v);
+ else
+ return _M_insert(__position._M_node, __position._M_node, __v);
+ // first argument just needs to be non-null
+ }
+ else
+ return insert_equal(__v);
+ }
+ }
+
+ template<typename _Key, typename _Val, typename _KoV,
+ typename _Cmp, typename _Alloc>
+ template<class _II>
+ void
+ _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>::
+ insert_equal(_II __first, _II __last)
{
- _M_put_node(__tmp);
- __throw_exception_again;
+ for ( ; __first != __last; ++__first)
+ insert_equal(*__first);
}
- return __tmp;
- }
- _Link_type _M_clone_node(_Link_type __x)
- {
- _Link_type __tmp = _M_create_node(__x->_M_value_field);
- __tmp->_M_color = __x->_M_color;
- __tmp->_M_left = 0;
- __tmp->_M_right = 0;
- return __tmp;
- }
+ template<typename _Key, typename _Val, typename _KoV,
+ typename _Cmp, typename _Alloc>
+ template<class _II>
+ void
+ _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>::
+ insert_unique(_II __first, _II __last)
+ {
+ for ( ; __first != __last; ++__first)
+ insert_unique(*__first);
+ }
- void
- destroy_node(_Link_type __p)
- {
- _Destroy(&__p->_M_value_field);
- _M_put_node(__p);
- }
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline void
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position)
+ {
+ _Link_type __y =
+ (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node,
+ _M_header->_M_parent,
+ _M_header->_M_left,
+ _M_header->_M_right);
+ destroy_node(__y);
+ --_M_node_count;
+ }
-protected:
- size_type _M_node_count; // keeps track of size of tree
- _Compare _M_key_compare;
-
- _Link_type& _M_root() const
- { return (_Link_type&) _M_header->_M_parent; }
- _Link_type& _M_leftmost() const
- { return (_Link_type&) _M_header->_M_left; }
- _Link_type& _M_rightmost() const
- { return (_Link_type&) _M_header->_M_right; }
-
- static _Link_type& _S_left(_Link_type __x)
- { return (_Link_type&)(__x->_M_left); }
- static _Link_type& _S_right(_Link_type __x)
- { return (_Link_type&)(__x->_M_right); }
- static _Link_type& _S_parent(_Link_type __x)
- { return (_Link_type&)(__x->_M_parent); }
- static reference _S_value(_Link_type __x)
- { return __x->_M_value_field; }
- static const _Key& _S_key(_Link_type __x)
- { return _KeyOfValue()(_S_value(__x)); }
- static _Color_type& _S_color(_Link_type __x)
- { return (_Color_type&)(__x->_M_color); }
-
- static _Link_type& _S_left(_Base_ptr __x)
- { return (_Link_type&)(__x->_M_left); }
- static _Link_type& _S_right(_Base_ptr __x)
- { return (_Link_type&)(__x->_M_right); }
- static _Link_type& _S_parent(_Base_ptr __x)
- { return (_Link_type&)(__x->_M_parent); }
- static reference _S_value(_Base_ptr __x)
- { return ((_Link_type)__x)->_M_value_field; }
- static const _Key& _S_key(_Base_ptr __x)
- { return _KeyOfValue()(_S_value(_Link_type(__x)));}
- static _Color_type& _S_color(_Base_ptr __x)
- { return (_Color_type&)(_Link_type(__x)->_M_color); }
-
- static _Link_type _S_minimum(_Link_type __x)
- { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); }
-
- static _Link_type _S_maximum(_Link_type __x)
- { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); }
-
-public:
- typedef _Rb_tree_iterator<value_type, reference, pointer> iterator;
- typedef _Rb_tree_iterator<value_type, const_reference, const_pointer>
- const_iterator;
-
- typedef reverse_iterator<const_iterator> const_reverse_iterator;
- typedef reverse_iterator<iterator> reverse_iterator;
-
-private:
- iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
- _Link_type _M_copy(_Link_type __x, _Link_type __p);
- void _M_erase(_Link_type __x);
-
-public:
- // allocation/deallocation
- _Rb_tree()
- : _Base(allocator_type()), _M_node_count(0), _M_key_compare()
- { _M_empty_initialize(); }
-
- _Rb_tree(const _Compare& __comp)
- : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp)
- { _M_empty_initialize(); }
-
- _Rb_tree(const _Compare& __comp, const allocator_type& __a)
- : _Base(__a), _M_node_count(0), _M_key_compare(__comp)
- { _M_empty_initialize(); }
-
- _Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x)
- : _Base(__x.get_allocator()),
- _M_node_count(0), _M_key_compare(__x._M_key_compare)
- {
- if (__x._M_root() == 0)
- _M_empty_initialize();
- else {
- _S_color(_M_header) = _S_rb_tree_red;
- _M_root() = _M_copy(__x._M_root(), _M_header);
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x)
+ {
+ pair<iterator,iterator> __p = equal_range(__x);
+ size_type __n = distance(__p.first, __p.second);
+ erase(__p.first, __p.second);
+ return __n;
}
- _M_node_count = __x._M_node_count;
- }
- ~_Rb_tree() { clear(); }
- _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>&
- operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x);
-
-private:
- void _M_empty_initialize() {
- _S_color(_M_header) = _S_rb_tree_red; // used to distinguish header from
- // __root, in iterator.operator++
- _M_root() = 0;
- _M_leftmost() = _M_header;
- _M_rightmost() = _M_header;
- }
-public:
- // accessors:
- _Compare key_comp() const { return _M_key_compare; }
- iterator begin() { return _M_leftmost(); }
- const_iterator begin() const { return _M_leftmost(); }
- iterator end() { return _M_header; }
- const_iterator end() const { return _M_header; }
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const {
- return const_reverse_iterator(end());
- }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const {
- return const_reverse_iterator(begin());
- }
- bool empty() const { return _M_node_count == 0; }
- size_type size() const { return _M_node_count; }
- size_type max_size() const { return size_type(-1); }
-
- void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __t) {
- std::swap(_M_header, __t._M_header);
- std::swap(_M_node_count, __t._M_node_count);
- std::swap(_M_key_compare, __t._M_key_compare);
- }
-
-public:
- // insert/erase
- pair<iterator,bool> insert_unique(const value_type& __x);
- iterator insert_equal(const value_type& __x);
-
- iterator insert_unique(iterator __position, const value_type& __x);
- iterator insert_equal(iterator __position, const value_type& __x);
-
- template <class _InputIterator>
- void insert_unique(_InputIterator __first, _InputIterator __last);
- template <class _InputIterator>
- void insert_equal(_InputIterator __first, _InputIterator __last);
-
- void erase(iterator __position);
- size_type erase(const key_type& __x);
- void erase(iterator __first, iterator __last);
- void erase(const key_type* __first, const key_type* __last);
- void clear() {
- if (_M_node_count != 0) {
- _M_erase(_M_root());
- _M_leftmost() = _M_header;
- _M_root() = 0;
- _M_rightmost() = _M_header;
- _M_node_count = 0;
+ template<typename _Key, typename _Val, typename _KoV,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
+ _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>::
+ _M_copy(_Link_type __x, _Link_type __p)
+ {
+ // Structural copy. __x and __p must be non-null.
+ _Link_type __top = _M_clone_node(__x);
+ __top->_M_parent = __p;
+
+ try
+ {
+ if (__x->_M_right)
+ __top->_M_right = _M_copy(_S_right(__x), __top);
+ __p = __top;
+ __x = _S_left(__x);
+
+ while (__x != 0)
+ {
+ _Link_type __y = _M_clone_node(__x);
+ __p->_M_left = __y;
+ __y->_M_parent = __p;
+ if (__x->_M_right)
+ __y->_M_right = _M_copy(_S_right(__x), __y);
+ __p = __y;
+ __x = _S_left(__x);
+ }
+ }
+ catch(...)
+ {
+ _M_erase(__top);
+ __throw_exception_again;
+ }
+ return __top;
}
- }
-
-public:
- // set operations:
- iterator find(const key_type& __x);
- const_iterator find(const key_type& __x) const;
- size_type count(const key_type& __x) const;
- iterator lower_bound(const key_type& __x);
- const_iterator lower_bound(const key_type& __x) const;
- iterator upper_bound(const key_type& __x);
- const_iterator upper_bound(const key_type& __x) const;
- pair<iterator,iterator> equal_range(const key_type& __x);
- pair<const_iterator, const_iterator> equal_range(const key_type& __x) const;
-
-public:
- // Debugging.
- bool __rb_verify() const;
-};
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline bool
-operator==(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
- const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y)
-{
- return __x.size() == __y.size() &&
- equal(__x.begin(), __x.end(), __y.begin());
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline bool
-operator<(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
- const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y)
-{
- return lexicographical_compare(__x.begin(), __x.end(),
- __y.begin(), __y.end());
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline bool
-operator!=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
- const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) {
- return !(__x == __y);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline bool
-operator>(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
- const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) {
- return __y < __x;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline bool
-operator<=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
- const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) {
- return !(__y < __x);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline bool
-operator>=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
- const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) {
- return !(__x < __y);
-}
-
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline void
-swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
- _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y)
-{
- __x.swap(__y);
-}
-
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>&
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x)
-{
- if (this != &__x) {
- // Note that _Key may be a constant type.
- clear();
- _M_node_count = 0;
- _M_key_compare = __x._M_key_compare;
- if (__x._M_root() == 0) {
- _M_root() = 0;
- _M_leftmost() = _M_header;
- _M_rightmost() = _M_header;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ void
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_erase(_Link_type __x)
+ {
+ // Erase without rebalancing.
+ while (__x != 0)
+ {
+ _M_erase(_S_right(__x));
+ _Link_type __y = _S_left(__x);
+ destroy_node(__x);
+ __x = __y;
+ }
}
- else {
- _M_root() = _M_copy(__x._M_root(), _M_header);
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
- _M_node_count = __x._M_node_count;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ void
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ erase(iterator __first, iterator __last)
+ {
+ if (__first == begin() && __last == end())
+ clear();
+ else
+ while (__first != __last) erase(__first++);
}
- }
- return *this;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v)
-{
- _Link_type __x = (_Link_type) __x_;
- _Link_type __y = (_Link_type) __y_;
- _Link_type __z;
-
- if (__y == _M_header || __x != 0 ||
- _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) {
- __z = _M_create_node(__v);
- _S_left(__y) = __z; // also makes _M_leftmost() = __z
- // when __y == _M_header
- if (__y == _M_header) {
- _M_root() = __z;
- _M_rightmost() = __z;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ void
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ erase(const _Key* __first, const _Key* __last)
+ {
+ while (__first != __last)
+ erase(*__first++);
}
- else if (__y == _M_leftmost())
- _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node
- }
- else {
- __z = _M_create_node(__v);
- _S_right(__y) = __z;
- if (__y == _M_rightmost())
- _M_rightmost() = __z; // maintain _M_rightmost() pointing to max node
- }
- _S_parent(__z) = __y;
- _S_left(__z) = 0;
- _S_right(__z) = 0;
- _Rb_tree_rebalance(__z, _M_header->_M_parent);
- ++_M_node_count;
- return iterator(__z);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::insert_equal(const _Value& __v)
-{
- _Link_type __y = _M_header;
- _Link_type __x = _M_root();
- while (__x != 0) {
- __y = __x;
- __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
- _S_left(__x) : _S_right(__x);
- }
- return _M_insert(__x, __y, __v);
-}
-
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-pair<typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator,
- bool>
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::insert_unique(const _Value& __v)
-{
- _Link_type __y = _M_header;
- _Link_type __x = _M_root();
- bool __comp = true;
- while (__x != 0) {
- __y = __x;
- __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x));
- __x = __comp ? _S_left(__x) : _S_right(__x);
- }
- iterator __j = iterator(__y);
- if (__comp)
- if (__j == begin())
- return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
- else
- --__j;
- if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
- return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
- return pair<iterator,bool>(__j, false);
-}
-
-
-template <class _Key, class _Val, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
-_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>
- ::insert_unique(iterator __position, const _Val& __v)
-{
- if (__position._M_node == _M_header->_M_left) { // begin()
- if (size() > 0 &&
- _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node)))
- return _M_insert(__position._M_node, __position._M_node, __v);
- // first argument just needs to be non-null
- else
- return insert_unique(__v).first;
- } else if (__position._M_node == _M_header) { // end()
- if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v)))
- return _M_insert(0, _M_rightmost(), __v);
- else
- return insert_unique(__v).first;
- } else {
- iterator __before = __position;
- --__before;
- if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v))
- && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) {
- if (_S_right(__before._M_node) == 0)
- return _M_insert(0, __before._M_node, __v);
- else
- return _M_insert(__position._M_node, __position._M_node, __v);
- // first argument just needs to be non-null
- } else
- return insert_unique(__v).first;
- }
-}
-
-template <class _Key, class _Val, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
-_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>
- ::insert_equal(iterator __position, const _Val& __v)
-{
- if (__position._M_node == _M_header->_M_left) { // begin()
- if (size() > 0 &&
- !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v)))
- return _M_insert(__position._M_node, __position._M_node, __v);
- // first argument just needs to be non-null
- else
- return insert_equal(__v);
- } else if (__position._M_node == _M_header) {// end()
- if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost())))
- return _M_insert(0, _M_rightmost(), __v);
- else
- return insert_equal(__v);
- } else {
- iterator __before = __position;
- --__before;
- if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node))
- && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) {
- if (_S_right(__before._M_node) == 0)
- return _M_insert(0, __before._M_node, __v);
- else
- return _M_insert(__position._M_node, __position._M_node, __v);
- // first argument just needs to be non-null
- } else
- return insert_equal(__v);
- }
-}
-
-template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
- template<class _II>
-void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
- ::insert_equal(_II __first, _II __last)
-{
- for ( ; __first != __last; ++__first)
- insert_equal(*__first);
-}
-
-template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
- template<class _II>
-void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
- ::insert_unique(_II __first, _II __last) {
- for ( ; __first != __last; ++__first)
- insert_unique(*__first);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::erase(iterator __position)
-{
- _Link_type __y =
- (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node,
- _M_header->_M_parent,
- _M_header->_M_left,
- _M_header->_M_right);
- destroy_node(__y);
- --_M_node_count;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x)
-{
- pair<iterator,iterator> __p = equal_range(__x);
- size_type __n = distance(__p.first, __p.second);
- erase(__p.first, __p.second);
- return __n;
-}
-
-template <class _Key, class _Val, class _KoV, class _Compare, class _Alloc>
-typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
-_Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>
- ::_M_copy(_Link_type __x, _Link_type __p)
-{
- // structural copy. __x and __p must be non-null.
- _Link_type __top = _M_clone_node(__x);
- __top->_M_parent = __p;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k)
+ {
+ _Link_type __y = _M_header; // Last node which is not less than __k.
+ _Link_type __x = _M_root(); // Current node.
+
+ while (__x != 0)
+ if (!_M_key_compare(_S_key(__x), __k))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+
+ iterator __j = iterator(__y);
+ return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ?
+ end() : __j;
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ find(const _Key& __k) const
+ {
+ _Link_type __y = _M_header; // Last node which is not less than __k.
+ _Link_type __x = _M_root(); // Current node.
- try {
- if (__x->_M_right)
- __top->_M_right = _M_copy(_S_right(__x), __top);
- __p = __top;
- __x = _S_left(__x);
-
- while (__x != 0) {
- _Link_type __y = _M_clone_node(__x);
- __p->_M_left = __y;
- __y->_M_parent = __p;
- if (__x->_M_right)
- __y->_M_right = _M_copy(_S_right(__x), __y);
- __p = __y;
- __x = _S_left(__x);
+ while (__x != 0)
+ {
+ if (!_M_key_compare(_S_key(__x), __k))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+ }
+ const_iterator __j = const_iterator(__y);
+ return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ?
+ end() : __j;
}
- }
- catch(...)
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ count(const _Key& __k) const
{
- _M_erase(__top);
- __throw_exception_again;
+ pair<const_iterator, const_iterator> __p = equal_range(__k);
+ size_type __n = distance(__p.first, __p.second);
+ return __n;
}
- return __top;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::_M_erase(_Link_type __x)
-{
- // erase without rebalancing
- while (__x != 0) {
- _M_erase(_S_right(__x));
- _Link_type __y = _S_left(__x);
- destroy_node(__x);
- __x = __y;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ lower_bound(const _Key& __k)
+ {
+ _Link_type __y = _M_header; /* Last node which is not less than __k. */
+ _Link_type __x = _M_root(); /* Current node. */
+
+ while (__x != 0)
+ if (!_M_key_compare(_S_key(__x), __k))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+
+ return iterator(__y);
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ lower_bound(const _Key& __k) const
+ {
+ _Link_type __y = _M_header; /* Last node which is not less than __k. */
+ _Link_type __x = _M_root(); /* Current node. */
+
+ while (__x != 0)
+ if (!_M_key_compare(_S_key(__x), __k))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+
+ return const_iterator(__y);
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ upper_bound(const _Key& __k)
+ {
+ _Link_type __y = _M_header; /* Last node which is greater than __k. */
+ _Link_type __x = _M_root(); /* Current node. */
+
+ while (__x != 0)
+ if (_M_key_compare(__k, _S_key(__x)))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+
+ return iterator(__y);
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ upper_bound(const _Key& __k) const
+ {
+ _Link_type __y = _M_header; /* Last node which is greater than __k. */
+ _Link_type __x = _M_root(); /* Current node. */
+
+ while (__x != 0)
+ if (_M_key_compare(__k, _S_key(__x)))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+
+ return const_iterator(__y);
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline
+ pair<typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator,
+ typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator>
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
+ equal_range(const _Key& __k)
+ { return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k)); }
+
+ template<typename _Key, typename _Val, typename _KoV,
+ typename _Compare, typename _Alloc>
+ inline
+ pair<typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator,
+ typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator>
+ _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>
+ ::equal_range(const _Key& __k) const
+ {
+ return pair<const_iterator,const_iterator>(lower_bound(__k),
+ upper_bound(__k));
}
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::erase(iterator __first, iterator __last)
-{
- if (__first == begin() && __last == end())
- clear();
- else
- while (__first != __last) erase(__first++);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::erase(const _Key* __first, const _Key* __last)
-{
- while (__first != __last) erase(*__first++);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k)
-{
- _Link_type __y = _M_header; // Last node which is not less than __k.
- _Link_type __x = _M_root(); // Current node.
-
- while (__x != 0)
- if (!_M_key_compare(_S_key(__x), __k))
- __y = __x, __x = _S_left(__x);
- else
- __x = _S_right(__x);
-
- iterator __j = iterator(__y);
- return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ?
- end() : __j;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) const
-{
- _Link_type __y = _M_header; /* Last node which is not less than __k. */
- _Link_type __x = _M_root(); /* Current node. */
-
- while (__x != 0) {
- if (!_M_key_compare(_S_key(__x), __k))
- __y = __x, __x = _S_left(__x);
- else
- __x = _S_right(__x);
+
+ inline int
+ __black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root)
+ {
+ if (__node == 0)
+ return 0;
+ int __sum = 0;
+ do
+ {
+ if (__node->_M_color == _M_black)
+ ++__sum;
+ if (__node == __root)
+ break;
+ __node = __node->_M_parent;
+ }
+ while (1);
+ return __sum;
}
- const_iterator __j = const_iterator(__y);
- return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ?
- end() : __j;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::count(const _Key& __k) const
-{
- pair<const_iterator, const_iterator> __p = equal_range(__k);
- size_type __n = distance(__p.first, __p.second);
- return __n;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::lower_bound(const _Key& __k)
-{
- _Link_type __y = _M_header; /* Last node which is not less than __k. */
- _Link_type __x = _M_root(); /* Current node. */
-
- while (__x != 0)
- if (!_M_key_compare(_S_key(__x), __k))
- __y = __x, __x = _S_left(__x);
- else
- __x = _S_right(__x);
-
- return iterator(__y);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::lower_bound(const _Key& __k) const
-{
- _Link_type __y = _M_header; /* Last node which is not less than __k. */
- _Link_type __x = _M_root(); /* Current node. */
-
- while (__x != 0)
- if (!_M_key_compare(_S_key(__x), __k))
- __y = __x, __x = _S_left(__x);
- else
- __x = _S_right(__x);
-
- return const_iterator(__y);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::upper_bound(const _Key& __k)
-{
- _Link_type __y = _M_header; /* Last node which is greater than __k. */
- _Link_type __x = _M_root(); /* Current node. */
-
- while (__x != 0)
- if (_M_key_compare(__k, _S_key(__x)))
- __y = __x, __x = _S_left(__x);
- else
- __x = _S_right(__x);
-
- return iterator(__y);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::upper_bound(const _Key& __k) const
-{
- _Link_type __y = _M_header; /* Last node which is greater than __k. */
- _Link_type __x = _M_root(); /* Current node. */
-
- while (__x != 0)
- if (_M_key_compare(__k, _S_key(__x)))
- __y = __x, __x = _S_left(__x);
- else
- __x = _S_right(__x);
-
- return const_iterator(__y);
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-inline
-pair<typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator,
- typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator>
-_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
- ::equal_range(const _Key& __k)
-{
- return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k));
-}
-
-template <class _Key, class _Value, class _KoV, class _Compare, class _Alloc>
-inline
-pair<typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator,
- typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator>
-_Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>
- ::equal_range(const _Key& __k) const
-{
- return pair<const_iterator,const_iterator>(lower_bound(__k),
- upper_bound(__k));
-}
-
-inline int
-__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root)
-{
- if (__node == 0)
- return 0;
- int __sum = 0;
- do {
- if (__node->_M_color == _S_rb_tree_black)
- ++__sum;
- if (__node == __root)
- break;
- __node = __node->_M_parent;
- } while (1);
- return __sum;
-}
-
-template <class _Key, class _Value, class _KeyOfValue,
- class _Compare, class _Alloc>
-bool _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
-{
- if (_M_node_count == 0 || begin() == end())
- return _M_node_count == 0 && begin() == end() &&
- _M_header->_M_left == _M_header && _M_header->_M_right == _M_header;
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ bool
+ _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
+ {
+ if (_M_node_count == 0 || begin() == end())
+ return _M_node_count == 0 && begin() == end() &&
+ _M_header->_M_left == _M_header && _M_header->_M_right == _M_header;
- int __len = __black_count(_M_leftmost(), _M_root());
- for (const_iterator __it = begin(); __it != end(); ++__it) {
- _Link_type __x = (_Link_type) __it._M_node;
- _Link_type __L = _S_left(__x);
- _Link_type __R = _S_right(__x);
-
- if (__x->_M_color == _S_rb_tree_red)
- if ((__L && __L->_M_color == _S_rb_tree_red) ||
- (__R && __R->_M_color == _S_rb_tree_red))
- return false;
-
- if (__L && _M_key_compare(_S_key(__x), _S_key(__L)))
- return false;
- if (__R && _M_key_compare(_S_key(__R), _S_key(__x)))
+ int __len = __black_count(_M_leftmost(), _M_root());
+ for (const_iterator __it = begin(); __it != end(); ++__it)
+ {
+ _Link_type __x = (_Link_type) __it._M_node;
+ _Link_type __L = _S_left(__x);
+ _Link_type __R = _S_right(__x);
+
+ if (__x->_M_color == _M_red)
+ if ((__L && __L->_M_color == _M_red)
+ || (__R && __R->_M_color == _M_red))
+ return false;
+
+ if (__L && _M_key_compare(_S_key(__x), _S_key(__L)))
+ return false;
+ if (__R && _M_key_compare(_S_key(__R), _S_key(__x)))
+ return false;
+
+ if (!__L && !__R && __black_count(__x, _M_root()) != __len)
+ return false;
+ }
+
+ if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
return false;
-
- if (!__L && !__R && __black_count(__x, _M_root()) != __len)
+ if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
return false;
- }
-
- if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
- return false;
- if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
- return false;
-
- return true;
-}
-
+ return true;
+ }
} // namespace std
-#endif /* __GLIBCPP_INTERNAL_TREE_H */
-
-// Local Variables:
-// mode:C++
-// End:
+#endif
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index 866b20bf37e..b5f7b8c40b6 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -107,7 +107,7 @@ namespace std
inline _ForwardIter
uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result)
{
- typedef typename iterator_traits<_InputIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD;
return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());
}
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 4d8e7513e9f..ef3b1c26e74 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1,6 +1,6 @@
// Vector implementation -*- C++ -*-
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 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
@@ -148,6 +148,15 @@ struct _Vector_base
* @brief A standard container which offers fixed time access to individual
* elements in any order.
*
+ * @ingroup Containers
+ * @ingroup Sequences
+ *
+ * Meets the requirements of a <a href="tables.html#65">container</a>, a
+ * <a href="tables.html#66">reversible container</a>, and a
+ * <a href="tables.html#67">sequence</a>, including the
+ * <a href="tables.html#68">optional sequence requirements</a> with the
+ * %exception of @c push_front and @c pop_front.
+ *
* In some terminology a vector can be described as a dynamic C-style array,
* it offers fast and efficient access to individual elements in any order
* and saves the user from worrying about memory and size allocation.
@@ -166,8 +175,9 @@ public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
- typedef __normal_iterator<pointer, vector_type> iterator;
- typedef __normal_iterator<const_pointer, vector_type> const_iterator;
+ typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
+ typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
+ const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
@@ -381,7 +391,9 @@ public:
* reallocation of memory and copy of vector data.
*/
void reserve(size_type __n) {
- if (capacity() < __n) {
+ if (__n > this->max_size())
+ __throw_length_error("vector::reserve");
+ if (this->capacity() < __n) {
const size_type __old_size = size();
pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
_Destroy(_M_start, _M_finish);
@@ -413,32 +425,34 @@ public:
template<class _InputIterator>
void
- assign(_InputIterator __first, _InputIterator __last)
- {
+ assign(_InputIterator __first, _InputIterator __last)
+ {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_assign_dispatch(__first, __last, _Integral());
}
template<class _Integer>
void
- _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
- { _M_fill_assign((size_type) __n, (_Tp) __val); }
+ _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+ { _M_fill_assign((size_type) __n, (_Tp) __val); }
template<class _InputIter>
void
- _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
+ _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
{
- typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
- _M_assign_aux(__first, __last, _IterCategory());
- }
+ typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
+ _M_assign_aux(__first, __last, _IterCategory());
+ }
template <class _InputIterator>
- void _M_assign_aux(_InputIterator __first, _InputIterator __last,
- input_iterator_tag);
+ void
+ _M_assign_aux(_InputIterator __first, _InputIterator __last,
+ input_iterator_tag);
template <class _ForwardIterator>
- void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
- forward_iterator_tag);
+ void
+ _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag);
/**
* Returns a read/write reference to the data at the first element of the
@@ -484,9 +498,13 @@ public:
_M_insert_aux(end(), __x);
}
+#ifdef _GLIBCPP_DEPRECATED
/**
* Add an element to the end of the vector. The element is
* default-constructed.
+ *
+ * @note You must define _GLIBCPP_DEPRECATED to make this visible; see
+ * c++config.h.
*/
void
push_back()
@@ -498,6 +516,7 @@ public:
else
_M_insert_aux(end());
}
+#endif
void
swap(vector<_Tp, _Alloc>& __x)
diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc
index dc7921527d9..5f57df583a7 100644
--- a/libstdc++-v3/include/bits/streambuf.tcc
+++ b/libstdc++-v3/include/bits/streambuf.tcc
@@ -40,6 +40,10 @@
namespace std
{
template<typename _CharT, typename _Traits>
+ const size_t
+ basic_streambuf<_CharT, _Traits>::_S_pback_size;
+
+ template<typename _CharT, typename _Traits>
typename basic_streambuf<_CharT, _Traits>::int_type
basic_streambuf<_CharT, _Traits>::
sbumpc()
@@ -47,7 +51,7 @@ namespace std
int_type __ret;
if (_M_in_cur && _M_in_cur < _M_in_end)
{
- char_type __c = *gptr();
+ char_type __c = *(this->gptr());
_M_in_cur_move(1);
__ret = traits_type::to_int_type(__c);
}
@@ -65,7 +69,7 @@ namespace std
bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]);
if (!__testpos || __testne)
- __ret = pbackfail(traits_type::to_int_type(__c));
+ __ret = this->pbackfail(traits_type::to_int_type(__c));
else
{
_M_in_cur_move(-1);
@@ -134,7 +138,7 @@ namespace std
if (__ret < __n)
{
int_type __c = this->uflow();
- if (__c != traits_type::eof())
+ if (!traits_type::eq_int_type(__c, traits_type::eof()))
{
traits_type::assign(*__s++, traits_type::to_char_type(__c));
++__ret;
@@ -173,7 +177,7 @@ namespace std
if (__ret < __n)
{
int_type __c = this->overflow(traits_type::to_int_type(*__s));
- if (__c != traits_type::eof())
+ if (!traits_type::eq_int_type(__c, traits_type::eof()))
{
++__ret;
++__s;
@@ -204,19 +208,32 @@ namespace std
try
{
while (__testput && __bufsize != -1)
- {
- __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
- __ret += __xtrct;
- __sbin->_M_in_cur_move(__xtrct);
- if (__xtrct == __bufsize)
+ {
+ if (__bufsize != 0 && __sbin->gptr() != NULL
+ && __sbin->gptr() + __bufsize <= __sbin->egptr())
{
- if (__sbin->sgetc() == _Traits::eof())
+ __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
+ __ret += __xtrct;
+ __sbin->_M_in_cur_move(__xtrct);
+ if (__xtrct != __bufsize)
break;
- __bufsize = __sbin->in_avail();
}
- else
- break;
- }
+ else
+ {
+ size_t __size =
+ __sbin->_M_buf_size_opt > 0 ? __sbin->_M_buf_size_opt : 1;
+ _CharT* __buf =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __size));
+ streamsize __charsread = __sbin->sgetn(__buf, __size);
+ __xtrct = __sbout->sputn(__buf, __charsread);
+ __ret += __xtrct;
+ if (__xtrct != __charsread)
+ break;
+ }
+ if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof()))
+ break;
+ __bufsize = __sbin->in_avail();
+ }
}
catch(exception& __fail)
{
@@ -236,11 +253,13 @@ namespace std
__copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
basic_streambuf<char>*);
+#ifdef _GLIBCPP_USE_WCHAR_T
extern template class basic_streambuf<wchar_t>;
extern template
streamsize
__copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*,
basic_streambuf<wchar_t>*);
+#endif
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h
index 88ae25eab18..152df9c6e4b 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -1,6 +1,7 @@
// Streambuf iterators
-// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// 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
@@ -41,60 +42,6 @@
namespace std
{
- template<typename _CharT, typename _Traits>
- class ostreambuf_iterator
- : public iterator<output_iterator_tag, void, void, void, void>
- {
- public:
- // Types:
- typedef _CharT char_type;
- typedef _Traits traits_type;
- typedef basic_streambuf<_CharT, _Traits> streambuf_type;
- typedef basic_ostream<_CharT, _Traits> ostream_type;
-
- private:
- streambuf_type* _M_sbuf;
- bool _M_failed;
-
- public:
- inline
- ostreambuf_iterator(ostream_type& __s) throw ()
- : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
-
- ostreambuf_iterator(streambuf_type* __s) throw ()
- : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
-
- ostreambuf_iterator&
- operator=(_CharT __c);
-
- ostreambuf_iterator&
- operator*() throw()
- { return *this; }
-
- ostreambuf_iterator&
- operator++(int) throw()
- { return *this; }
-
- ostreambuf_iterator&
- operator++() throw()
- { return *this; }
-
- bool
- failed() const throw()
- { return _M_failed; }
- };
-
- template<typename _CharT, typename _Traits>
- inline ostreambuf_iterator<_CharT, _Traits>&
- ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c)
- {
- if (!_M_failed &&
- _Traits::eq_int_type(_M_sbuf->sputc(__c),_Traits::eof()))
- _M_failed = true;
- return *this;
- }
-
-
// 24.5.3 Template class istreambuf_iterator
template<typename _CharT, typename _Traits>
class istreambuf_iterator
@@ -117,76 +64,78 @@ namespace std
// the "end of stream" iterator value.
// NB: This implementation assumes the "end of stream" value
// is EOF, or -1.
- streambuf_type* _M_sbuf;
+ mutable streambuf_type* _M_sbuf;
int_type _M_c;
public:
istreambuf_iterator() throw()
- : _M_sbuf(NULL), _M_c(-2) { }
+ : _M_sbuf(0), _M_c(traits_type::eof()) { }
istreambuf_iterator(istream_type& __s) throw()
- : _M_sbuf(__s.rdbuf()), _M_c(-2) { }
+ : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
istreambuf_iterator(streambuf_type* __s) throw()
- : _M_sbuf(__s), _M_c(-2) { }
+ : _M_sbuf(__s), _M_c(traits_type::eof()) { }
- // NB: This should really have an int_type return
- // value, so "end of stream" postion can be checked without
- // hacking.
+ // NB: The result of operator*() on an end of stream is undefined.
char_type
operator*() const
- {
- // The result of operator*() on an end of stream is undefined.
- char_type __ret;
- if (_M_sbuf && _M_c != static_cast<int_type>(-2))
- __ret = _M_c;
- else if (_M_sbuf)
- __ret = traits_type::to_char_type(_M_sbuf->sgetc());
- else
- __ret = static_cast<char_type>(traits_type::eof());
- return __ret;
- }
+ { return traits_type::to_char_type(_M_get()); }
istreambuf_iterator&
operator++()
{
- if (_M_sbuf)
- _M_sbuf->sbumpc();
- _M_c = -2;
+ const int_type __eof = traits_type::eof();
+ if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof))
+ _M_sbuf = 0;
+ else
+ _M_c = __eof;
return *this;
}
istreambuf_iterator
operator++(int)
{
+ const int_type __eof = traits_type::eof();
istreambuf_iterator __old = *this;
- if (_M_sbuf)
- __old._M_c = _M_sbuf->sbumpc();
- _M_c = -2;
+ if (_M_sbuf
+ && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()),
+ __eof))
+ _M_sbuf = 0;
+ else
+ _M_c = __eof;
return __old;
}
- bool
- equal(const istreambuf_iterator& __b)
- {
- int_type __eof = traits_type::eof();
- bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
- bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
- return (__thiseof && __beof || (!__thiseof && !__beof));
- }
-
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 110 istreambuf_iterator::equal not const
// NB: there is also number 111 (NAD, Future) pending on this function.
bool
equal(const istreambuf_iterator& __b) const
{
- int_type __eof = traits_type::eof();
- bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
- bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
+ const int_type __eof = traits_type::eof();
+ bool __thiseof = traits_type::eq_int_type(_M_get(), __eof);
+ bool __beof = traits_type::eq_int_type(__b._M_get(), __eof);
return (__thiseof && __beof || (!__thiseof && !__beof));
}
#endif
+
+ private:
+ int_type
+ _M_get() const
+ {
+ const int_type __eof = traits_type::eof();
+ int_type __ret = __eof;
+ if (_M_sbuf)
+ {
+ if (!traits_type::eq_int_type(_M_c, __eof))
+ __ret = _M_c;
+ else
+ if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof))
+ _M_sbuf = 0;
+ }
+ return __ret;
+ }
};
template<typename _CharT, typename _Traits>
@@ -200,5 +149,58 @@ namespace std
operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
const istreambuf_iterator<_CharT, _Traits>& __b)
{ return !__a.equal(__b); }
+
+ template<typename _CharT, typename _Traits>
+ class ostreambuf_iterator
+ : public iterator<output_iterator_tag, void, void, void, void>
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _Traits traits_type;
+ typedef basic_streambuf<_CharT, _Traits> streambuf_type;
+ typedef basic_ostream<_CharT, _Traits> ostream_type;
+
+ private:
+ streambuf_type* _M_sbuf;
+ bool _M_failed;
+
+ public:
+ inline
+ ostreambuf_iterator(ostream_type& __s) throw ()
+ : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
+
+ ostreambuf_iterator(streambuf_type* __s) throw ()
+ : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
+
+ ostreambuf_iterator&
+ operator=(_CharT __c);
+
+ ostreambuf_iterator&
+ operator*() throw()
+ { return *this; }
+
+ ostreambuf_iterator&
+ operator++(int) throw()
+ { return *this; }
+
+ ostreambuf_iterator&
+ operator++() throw()
+ { return *this; }
+
+ bool
+ failed() const throw()
+ { return _M_failed; }
+ };
+
+ template<typename _CharT, typename _Traits>
+ inline ostreambuf_iterator<_CharT, _Traits>&
+ ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c)
+ {
+ if (!_M_failed &&
+ _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
+ _M_failed = true;
+ return *this;
+ }
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/stringfwd.h b/libstdc++-v3/include/bits/stringfwd.h
index b7418a67a7e..db40befdab6 100644
--- a/libstdc++-v3/include/bits/stringfwd.h
+++ b/libstdc++-v3/include/bits/stringfwd.h
@@ -45,23 +45,25 @@
namespace std
{
- template<class _CharT>
- struct char_traits;
-
- template<> struct char_traits<char>;
-#ifdef _GLIBCPP_USE_WCHAR_T
- template<> struct char_traits<wchar_t>;
-#endif
-
template<typename _Alloc>
class allocator;
+ template<class _CharT>
+ struct char_traits;
+
template<typename _CharT, typename _Traits = char_traits<_CharT>,
typename _Alloc = allocator<_CharT> >
class basic_string;
+
+ template<> struct char_traits<char>;
typedef basic_string<char> string;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<> struct char_traits<wchar_t>;
+
typedef basic_string<wchar_t> wstring;
+#endif
} // namespace std
#endif // _CPP_BITS_STRINGFWD_H
diff --git a/libstdc++-v3/include/bits/type_traits.h b/libstdc++-v3/include/bits/type_traits.h
index 89e50f39a3f..61bc4369275 100644
--- a/libstdc++-v3/include/bits/type_traits.h
+++ b/libstdc++-v3/include/bits/type_traits.h
@@ -322,13 +322,13 @@ template<typename _Tp> struct _Is_normal_iterator {
};
// Forward declaration hack, should really include this from somewhere.
-namespace std
+namespace __gnu_cxx
{
template<typename _Iterator, typename _Container> class __normal_iterator;
}
template<typename _Iterator, typename _Container>
-struct _Is_normal_iterator< std::__normal_iterator<_Iterator, _Container> > {
+struct _Is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, _Container> > {
typedef __true_type _Normal;
};