aboutsummaryrefslogtreecommitdiff
path: root/contrib/libstdc++/include/bits
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2002-05-28 16:16:03 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2002-05-28 16:16:03 +0000
commit00db7afddd93b9febd88ed0a8567dc3201852b70 (patch)
tree7b14e1142a8f8cf48f311f5246aa3b355f2380b6 /contrib/libstdc++/include/bits
parentdd49f056383051d19affcdbe7677e72a9b761c18 (diff)
Notes
Diffstat (limited to 'contrib/libstdc++/include/bits')
-rw-r--r--contrib/libstdc++/include/bits/basic_ios.h210
-rw-r--r--contrib/libstdc++/include/bits/basic_ios.tcc193
-rw-r--r--contrib/libstdc++/include/bits/basic_string.h1084
-rw-r--r--contrib/libstdc++/include/bits/basic_string.tcc981
-rw-r--r--contrib/libstdc++/include/bits/boost_concept_check.h899
-rw-r--r--contrib/libstdc++/include/bits/c++config77
-rw-r--r--contrib/libstdc++/include/bits/char_traits.h280
-rw-r--r--contrib/libstdc++/include/bits/codecvt.h336
-rw-r--r--contrib/libstdc++/include/bits/concept_check.h86
-rw-r--r--contrib/libstdc++/include/bits/cpp_type_traits.h300
-rw-r--r--contrib/libstdc++/include/bits/fpos.h123
-rw-r--r--contrib/libstdc++/include/bits/fstream.tcc589
-rw-r--r--contrib/libstdc++/include/bits/functexcept.h85
-rw-r--r--contrib/libstdc++/include/bits/generic_shadow.h59
-rw-r--r--contrib/libstdc++/include/bits/gslice.h124
-rw-r--r--contrib/libstdc++/include/bits/gslice_array.h176
-rw-r--r--contrib/libstdc++/include/bits/indirect_array.h176
-rw-r--r--contrib/libstdc++/include/bits/ios_base.h589
-rw-r--r--contrib/libstdc++/include/bits/istream.tcc1228
-rw-r--r--contrib/libstdc++/include/bits/locale_facets.h1813
-rw-r--r--contrib/libstdc++/include/bits/locale_facets.tcc2401
-rw-r--r--contrib/libstdc++/include/bits/localefwd.h476
-rw-r--r--contrib/libstdc++/include/bits/mask_array.h167
-rw-r--r--contrib/libstdc++/include/bits/ostream.tcc704
-rw-r--r--contrib/libstdc++/include/bits/pthread_allocimpl.h525
-rw-r--r--contrib/libstdc++/include/bits/slice.h85
-rw-r--r--contrib/libstdc++/include/bits/slice_array.h180
-rw-r--r--contrib/libstdc++/include/bits/sstream.tcc238
-rw-r--r--contrib/libstdc++/include/bits/stl_algo.h4351
-rw-r--r--contrib/libstdc++/include/bits/stl_algobase.h820
-rw-r--r--contrib/libstdc++/include/bits/stl_alloc.h941
-rw-r--r--contrib/libstdc++/include/bits/stl_bvector.h726
-rw-r--r--contrib/libstdc++/include/bits/stl_construct.h148
-rw-r--r--contrib/libstdc++/include/bits/stl_deque.h1580
-rw-r--r--contrib/libstdc++/include/bits/stl_function.h736
-rw-r--r--contrib/libstdc++/include/bits/stl_heap.h308
-rw-r--r--contrib/libstdc++/include/bits/stl_iterator.h733
-rw-r--r--contrib/libstdc++/include/bits/stl_iterator_base_funcs.h179
-rw-r--r--contrib/libstdc++/include/bits/stl_iterator_base_types.h162
-rw-r--r--contrib/libstdc++/include/bits/stl_list.h989
-rw-r--r--contrib/libstdc++/include/bits/stl_map.h503
-rw-r--r--contrib/libstdc++/include/bits/stl_multimap.h491
-rw-r--r--contrib/libstdc++/include/bits/stl_multiset.h277
-rw-r--r--contrib/libstdc++/include/bits/stl_numeric.h215
-rw-r--r--contrib/libstdc++/include/bits/stl_pair.h157
-rw-r--r--contrib/libstdc++/include/bits/stl_pthread_alloc.h60
-rw-r--r--contrib/libstdc++/include/bits/stl_queue.h244
-rw-r--r--contrib/libstdc++/include/bits/stl_raw_storage_iter.h112
-rw-r--r--contrib/libstdc++/include/bits/stl_relops.h141
-rw-r--r--contrib/libstdc++/include/bits/stl_set.h274
-rw-r--r--contrib/libstdc++/include/bits/stl_stack.h160
-rw-r--r--contrib/libstdc++/include/bits/stl_tempbuf.h149
-rw-r--r--contrib/libstdc++/include/bits/stl_threads.h236
-rw-r--r--contrib/libstdc++/include/bits/stl_tree.h1462
-rw-r--r--contrib/libstdc++/include/bits/stl_uninitialized.h290
-rw-r--r--contrib/libstdc++/include/bits/stl_vector.h1083
-rw-r--r--contrib/libstdc++/include/bits/stream_iterator.h156
-rw-r--r--contrib/libstdc++/include/bits/streambuf.tcc250
-rw-r--r--contrib/libstdc++/include/bits/streambuf_iterator.h201
-rw-r--r--contrib/libstdc++/include/bits/stringfwd.h67
-rw-r--r--contrib/libstdc++/include/bits/type_traits.h339
-rw-r--r--contrib/libstdc++/include/bits/valarray_array.h630
-rw-r--r--contrib/libstdc++/include/bits/valarray_array.tcc161
-rw-r--r--contrib/libstdc++/include/bits/valarray_meta.h1075
64 files changed, 34590 insertions, 0 deletions
diff --git a/contrib/libstdc++/include/bits/basic_ios.h b/contrib/libstdc++/include/bits/basic_ios.h
new file mode 100644
index 0000000000000..13ad0f82e9906
--- /dev/null
+++ b/contrib/libstdc++/include/bits/basic_ios.h
@@ -0,0 +1,210 @@
+// Iostreams base classes -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file basic_ios.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_BASICIOS_H
+#define _CPP_BITS_BASICIOS_H 1
+
+#pragma GCC system_header
+
+#include <bits/streambuf_iterator.h>
+#include <bits/locale_facets.h>
+
+namespace std
+{
+ // 27.4.5 Template class basic_ios
+ template<typename _CharT, typename _Traits>
+ class basic_ios : public ios_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef typename _Traits::int_type int_type;
+ typedef typename _Traits::pos_type pos_type;
+ typedef typename _Traits::off_type off_type;
+ typedef _Traits traits_type;
+
+ // Non-standard Types:
+ typedef ctype<_CharT> __ctype_type;
+ typedef ostreambuf_iterator<_CharT, _Traits> __ostreambuf_iter;
+ typedef num_put<_CharT, __ostreambuf_iter> __numput_type;
+ typedef istreambuf_iterator<_CharT, _Traits> __istreambuf_iter;
+ typedef num_get<_CharT, __istreambuf_iter> __numget_type;
+
+ // Data members:
+ protected:
+ basic_ostream<_CharT, _Traits>* _M_tie;
+ mutable char_type _M_fill;
+ mutable bool _M_fill_init;
+ basic_streambuf<_CharT, _Traits>* _M_streambuf;
+
+ // Cached use_facet<ctype>, which is based on the current locale info.
+ const __ctype_type* _M_fctype;
+ // From ostream.
+ const __numput_type* _M_fnumput;
+ // From istream.
+ const __numget_type* _M_fnumget;
+
+ public:
+ operator void*() const
+ { return this->fail() ? 0 : const_cast<basic_ios*>(this); }
+
+ bool
+ operator!() const
+ { return this->fail(); }
+
+ iostate
+ rdstate() const
+ { return _M_streambuf_state; }
+
+ void
+ clear(iostate __state = goodbit);
+
+ void
+ setstate(iostate __state)
+ { this->clear(this->rdstate() | __state); }
+
+ bool
+ good() const
+ { return this->rdstate() == 0; }
+
+ bool
+ eof() const
+ { return (this->rdstate() & eofbit) != 0; }
+
+ bool
+ fail() const
+ { return (this->rdstate() & (badbit | failbit)) != 0; }
+
+ bool
+ bad() const
+ { return (this->rdstate() & badbit) != 0; }
+
+ iostate
+ exceptions() const
+ { return _M_exception; }
+
+ void
+ exceptions(iostate __except)
+ {
+ _M_exception = __except;
+ this->clear(_M_streambuf_state);
+ }
+
+ // Constructor/destructor:
+ explicit
+ basic_ios(basic_streambuf<_CharT, _Traits>* __sb) : ios_base()
+ { this->init(__sb); }
+
+ virtual
+ ~basic_ios() { }
+
+ // Members:
+ basic_ostream<_CharT, _Traits>*
+ tie() const
+ { return _M_tie; }
+
+ basic_ostream<_CharT, _Traits>*
+ tie(basic_ostream<_CharT, _Traits>* __tiestr)
+ {
+ basic_ostream<_CharT, _Traits>* __old = _M_tie;
+ _M_tie = __tiestr;
+ return __old;
+ }
+
+ basic_streambuf<_CharT, _Traits>*
+ rdbuf() const
+ { return _M_streambuf; }
+
+ basic_streambuf<_CharT, _Traits>*
+ rdbuf(basic_streambuf<_CharT, _Traits>* __sb);
+
+ basic_ios&
+ copyfmt(const basic_ios& __rhs);
+
+ char_type
+ fill() const
+ {
+ if (!_M_fill_init)
+ {
+ _M_fill = this->widen(' ');
+ _M_fill_init = true;
+ }
+ return _M_fill;
+ }
+
+ char_type
+ fill(char_type __ch)
+ {
+ char_type __old = this->fill();
+ _M_fill = __ch;
+ return __old;
+ }
+
+ // Locales:
+ locale
+ imbue(const locale& __loc);
+
+ char
+ narrow(char_type __c, char __dfault) const;
+
+ char_type
+ widen(char __c) const;
+
+ protected:
+ // 27.4.5.1 basic_ios constructors
+ basic_ios() : ios_base()
+ { }
+
+ void
+ init(basic_streambuf<_CharT, _Traits>* __sb);
+
+ bool
+ _M_check_facet(const locale::facet* __f) const
+ {
+ if (!__f)
+ __throw_bad_cast();
+ return true;
+ }
+
+ void
+ _M_cache_facets(const locale& __loc);
+ };
+} // namespace std
+
+#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
+# define export
+#include <bits/basic_ios.tcc>
+#endif
+
+#endif /* _CPP_BITS_BASICIOS_H */
diff --git a/contrib/libstdc++/include/bits/basic_ios.tcc b/contrib/libstdc++/include/bits/basic_ios.tcc
new file mode 100644
index 0000000000000..1e345dc211720
--- /dev/null
+++ b/contrib/libstdc++/include/bits/basic_ios.tcc
@@ -0,0 +1,193 @@
+// basic_ios locale and locale-related member functions -*- C++ -*-
+
+// Copyright (C) 1999, 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _CPP_BITS_BASICIOS_TCC
+#define _CPP_BITS_BASICIOS_TCC 1
+
+#pragma GCC system_header
+
+namespace std
+{
+ template<typename _CharT, typename _Traits>
+ void
+ basic_ios<_CharT, _Traits>::clear(iostate __state)
+ {
+ if (this->rdbuf())
+ _M_streambuf_state = __state;
+ else
+ _M_streambuf_state = __state | badbit;
+ if ((this->rdstate() & this->exceptions()))
+ __throw_ios_failure("basic_ios::clear(iostate) caused exception");
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_streambuf<_CharT, _Traits>*
+ basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb)
+ {
+ basic_streambuf<_CharT, _Traits>* __old = _M_streambuf;
+ _M_streambuf = __sb;
+ this->clear();
+ return __old;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ios<_CharT, _Traits>&
+ basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs)
+ {
+ // Per 27.1.1.1, do not call imbue, yet must trash all caches
+ // associated with imbue()
+
+ // Alloc any new word array first, so if it fails we have "rollback".
+ _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_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_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());
+ this->precision(__rhs.precision());
+ this->tie(__rhs.tie());
+ this->fill(__rhs.fill());
+ // The next is required to be the last assignment.
+ this->exceptions(__rhs.exceptions());
+
+ _M_call_callbacks(copyfmt_event);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ char
+ basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const
+ {
+ char __ret = __dfault;
+ if (_M_check_facet(_M_fctype))
+ __ret = _M_fctype->narrow(__c, __dfault);
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ _CharT
+ basic_ios<_CharT, _Traits>::widen(char __c) const
+ {
+ char_type __ret = char_type();
+ if (_M_check_facet(_M_fctype))
+ __ret = _M_fctype->widen(__c);
+ return __ret;
+ }
+
+ // Locales:
+ template<typename _CharT, typename _Traits>
+ locale
+ basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
+ {
+ locale __old(this->getloc());
+ ios_base::imbue(__loc);
+ _M_cache_facets(__loc);
+ if (this->rdbuf() != 0)
+ this->rdbuf()->pubimbue(__loc);
+ return __old;
+ }
+
+ template<typename _CharT, typename _Traits>
+ void
+ basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb)
+ {
+ // NB: This may be called more than once on the same object.
+ ios_base::_M_init();
+ _M_cache_facets(_M_ios_locale);
+ _M_tie = 0;
+
+ // 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 = 0;
+ _M_fill_init = false;
+
+ _M_exception = goodbit;
+ _M_streambuf = __sb;
+ _M_streambuf_state = __sb ? goodbit : badbit;
+ }
+
+ template<typename _CharT, typename _Traits>
+ void
+ basic_ios<_CharT, _Traits>::_M_cache_facets(const locale& __loc)
+ {
+ if (has_facet<__ctype_type>(__loc))
+ _M_fctype = &use_facet<__ctype_type>(__loc);
+ else
+ _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);
+ else
+ _M_fnumput = 0;
+ if (has_facet<__numget_type>(__loc))
+ _M_fnumget = &use_facet<__numget_type>(__loc);
+ else
+ _M_fnumget = 0;
+ }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+ extern template class basic_ios<char>;
+ extern template class basic_ios<wchar_t>;
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/basic_string.h b/contrib/libstdc++/include/bits/basic_string.h
new file mode 100644
index 0000000000000..e05a1c6ef6143
--- /dev/null
+++ b/contrib/libstdc++/include/bits/basic_string.h
@@ -0,0 +1,1084 @@
+// Components for manipulating sequences of characters -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 21 Strings library
+//
+
+/** @file basic_string.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STRING_H
+#define _CPP_BITS_STRING_H 1
+
+#pragma GCC system_header
+
+#include <bits/atomicity.h>
+
+namespace std
+{
+ // Documentation? What's that?
+ // Nathan Myers <ncm@cantrip.org>.
+ //
+ // A string looks like this:
+ //
+ // [_Rep]
+ // _M_length
+ // [basic_string<char_type>] _M_capacity
+ // _M_dataplus _M_state
+ // _M_p ----------------> unnamed array of char_type
+
+ // Where the _M_p points to the first character in the string, and
+ // you cast it to a pointer-to-_Rep and subtract 1 to get a
+ // pointer to the header.
+
+ // This approach has the enormous advantage that a string object
+ // requires only one allocation. All the ugliness is confined
+ // within a single pair of inline functions, which each compile to
+ // a single "add" instruction: _Rep::_M_data(), and
+ // string::_M_rep(); and the allocation function which gets a
+ // block of raw bytes and with room enough and constructs a _Rep
+ // object at the front.
+
+ // The reason you want _M_data pointing to the character array and
+ // not the _Rep is so that the debugger can see the string
+ // contents. (Probably we should add a non-inline member to get
+ // the _Rep for the debugger to use, so users can check the actual
+ // string length.)
+
+ // Note that the _Rep object is a POD so that you can have a
+ // static "empty string" _Rep object already "constructed" before
+ // static constructors have run. The reference-count encoding is
+ // chosen so that a 0 indicates one reference, so you never try to
+ // destroy the empty-string _Rep object.
+
+ // All but the last paragraph is considered pretty conventional
+ // for a C++ string implementation.
+
+ // 21.3 Template class basic_string
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ class basic_string
+ {
+ // Types:
+ public:
+ typedef _Traits traits_type;
+ typedef typename _Traits::char_type value_type;
+ typedef _Alloc allocator_type;
+ typedef typename _Alloc::size_type size_type;
+ typedef typename _Alloc::difference_type difference_type;
+ typedef typename _Alloc::reference reference;
+ typedef typename _Alloc::const_reference const_reference;
+ typedef typename _Alloc::pointer pointer;
+ typedef typename _Alloc::const_pointer const_pointer;
+ 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;
+
+ private:
+ // _Rep: string representation
+ // Invariants:
+ // 1. String really contains _M_length + 1 characters; last is set
+ // to 0 only on call to c_str(). We avoid instantiating
+ // _CharT() where the interface does not require it.
+ // 2. _M_capacity >= _M_length
+ // Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
+ // 3. _M_references has three states:
+ // -1: leaked, one reference, no ref-copies allowed, non-const.
+ // 0: one reference, non-const.
+ // n>0: n + 1 references, operations require a lock, const.
+ // 4. All fields==0 is an empty string, given the extra storage
+ // beyond-the-end for a null terminator; thus, the shared
+ // empty string representation needs no constructor.
+ struct _Rep
+ {
+ // Types:
+ typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
+
+ // (Public) Data members:
+
+ // The maximum number of individual char_type elements of an
+ // individual string is determined by _S_max_size. This is the
+ // value that will be returned by max_size(). (Whereas npos
+ // is the maximum number of bytes the allocator can allocate.)
+ // If one was to divvy up the theoretical largest size string,
+ // with a terminating character and m _CharT elements, it'd
+ // look like this:
+ // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
+ // Solving for m:
+ // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
+ // In addition, this implementation quarters this ammount.
+ static const size_type _S_max_size;
+ static const _CharT _S_terminal;
+
+ size_type _M_length;
+ size_type _M_capacity;
+ _Atomic_word _M_references;
+
+ bool
+ _M_is_leaked() const
+ { return _M_references < 0; }
+
+ bool
+ _M_is_shared() const
+ { return _M_references > 0; }
+
+ void
+ _M_set_leaked()
+ { _M_references = -1; }
+
+ void
+ _M_set_sharable()
+ { _M_references = 0; }
+
+ _CharT*
+ _M_refdata() throw()
+ { return reinterpret_cast<_CharT*>(this + 1); }
+
+ _CharT&
+ operator[](size_t __s) throw()
+ { return _M_refdata() [__s]; }
+
+ _CharT*
+ _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
+ {
+ return (!_M_is_leaked() && __alloc1 == __alloc2)
+ ? _M_refcopy() : _M_clone(__alloc1);
+ }
+
+ // Create & Destroy
+ static _Rep*
+ _S_create(size_t, const _Alloc&);
+
+ void
+ _M_dispose(const _Alloc& __a)
+ {
+ if (__exchange_and_add(&_M_references, -1) <= 0)
+ _M_destroy(__a);
+ } // XXX MT
+
+ void
+ _M_destroy(const _Alloc&) throw();
+
+ _CharT*
+ _M_refcopy() throw()
+ {
+ __atomic_add(&_M_references, 1);
+ return _M_refdata();
+ } // XXX MT
+
+ _CharT*
+ _M_clone(const _Alloc&, size_type __res = 0);
+ };
+
+ // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
+ struct _Alloc_hider : _Alloc
+ {
+ _Alloc_hider(_CharT* __dat, const _Alloc& __a)
+ : _Alloc(__a), _M_p(__dat) { }
+
+ _CharT* _M_p; // The actual data.
+ };
+
+ public:
+ // Data Members (public):
+ // NB: This is an unsigned type, and thus represents the maximum
+ // size that the allocator can hold.
+ static const size_type npos = static_cast<size_type>(-1);
+
+ private:
+ // Data Members (private):
+ mutable _Alloc_hider _M_dataplus;
+
+ // The following storage is init'd to 0 by the linker, resulting
+ // (carefully) in an empty string with one reference.
+ static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
+
+ _CharT*
+ _M_data() const
+ { return _M_dataplus._M_p; }
+
+ _CharT*
+ _M_data(_CharT* __p)
+ { return (_M_dataplus._M_p = __p); }
+
+ _Rep*
+ _M_rep() const
+ { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
+
+ // For the internal use we have functions similar to `begin'/`end'
+ // but they do not call _M_leak.
+ iterator
+ _M_ibegin() const { return iterator(_M_data()); }
+
+ iterator
+ _M_iend() const { return iterator(_M_data() + this->size()); }
+
+ void
+ _M_leak() // for use in begin() & non-const op[]
+ {
+ if (!_M_rep()->_M_is_leaked())
+ _M_leak_hard();
+ }
+
+ iterator
+ _M_check(size_type __pos) const
+ {
+ if (__pos > this->size())
+ __throw_out_of_range("basic_string::_M_check");
+ return _M_ibegin() + __pos;
+ }
+
+ // NB: _M_fold doesn't check for a bad __pos1 value.
+ iterator
+ _M_fold(size_type __pos, size_type __off) const
+ {
+ bool __testoff = __off < this->size() - __pos;
+ size_type __newoff = __testoff ? __off : this->size() - __pos;
+ return (_M_ibegin() + __pos + __newoff);
+ }
+
+ // _S_copy_chars is a separate template to permit specialization
+ // to optimize for the common case of pointers as iterators.
+ template<class _Iterator>
+ static void
+ _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
+ {
+ for (; __k1 != __k2; ++__k1, ++__p)
+ traits_type::assign(*__p, *__k1); // These types are off.
+ }
+
+ static void
+ _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
+ { _S_copy_chars(__p, __k1.base(), __k2.base()); }
+
+ static void
+ _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
+ { _S_copy_chars(__p, __k1.base(), __k2.base()); }
+
+ static void
+ _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
+ { traits_type::copy(__p, __k1, __k2 - __k1); }
+
+ static void
+ _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
+ { traits_type::copy(__p, __k1, __k2 - __k1); }
+
+ void
+ _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+
+ void
+ _M_leak_hard();
+
+ static _Rep&
+ _S_empty_rep()
+ { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
+
+ public:
+ // Construct/copy/destroy:
+ // NB: We overload ctors in some cases instead of using default
+ // arguments, per 17.4.4.4 para. 2 item 2.
+
+ inline
+ basic_string();
+
+ explicit
+ basic_string(const _Alloc& __a);
+
+ // NB: per LWG issue 42, semantics different from IS:
+ basic_string(const basic_string& __str);
+ basic_string(const basic_string& __str, size_type __pos,
+ size_type __n = npos);
+ basic_string(const basic_string& __str, size_type __pos,
+ size_type __n, const _Alloc& __a);
+
+ basic_string(const _CharT* __s, size_type __n,
+ const _Alloc& __a = _Alloc());
+ basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
+ basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
+
+ template<class _InputIterator>
+ basic_string(_InputIterator __beg, _InputIterator __end,
+ const _Alloc& __a = _Alloc());
+
+ ~basic_string()
+ { _M_rep()->_M_dispose(this->get_allocator()); }
+
+ basic_string&
+ operator=(const basic_string& __str) { return this->assign(__str); }
+
+ basic_string&
+ operator=(const _CharT* __s) { return this->assign(__s); }
+
+ basic_string&
+ operator=(_CharT __c) { return this->assign(1, __c); }
+
+ // Iterators:
+ iterator
+ begin()
+ {
+ _M_leak();
+ return iterator(_M_data());
+ }
+
+ const_iterator
+ begin() const
+ { return const_iterator(_M_data()); }
+
+ iterator
+ end()
+ {
+ _M_leak();
+ return iterator(_M_data() + this->size());
+ }
+
+ const_iterator
+ end() const
+ { return const_iterator(_M_data() + this->size()); }
+
+ reverse_iterator
+ rbegin()
+ { return reverse_iterator(this->end()); }
+
+ const_reverse_iterator
+ rbegin() const
+ { return const_reverse_iterator(this->end()); }
+
+ reverse_iterator
+ rend()
+ { return reverse_iterator(this->begin()); }
+
+ const_reverse_iterator
+ rend() const
+ { return const_reverse_iterator(this->begin()); }
+
+ public:
+ // Capacity:
+ size_type
+ size() const { return _M_rep()->_M_length; }
+
+ size_type
+ length() const { return _M_rep()->_M_length; }
+
+ size_type
+ max_size() const { return _Rep::_S_max_size; }
+
+ void
+ resize(size_type __n, _CharT __c);
+
+ void
+ resize(size_type __n) { this->resize(__n, _CharT()); }
+
+ size_type
+ capacity() const { return _M_rep()->_M_capacity; }
+
+ void
+ reserve(size_type __res_arg = 0);
+
+ void
+ clear() { _M_mutate(0, this->size(), 0); }
+
+ bool
+ empty() const { return this->size() == 0; }
+
+ // Element access:
+ const_reference
+ operator[] (size_type __pos) const
+ { return _M_data()[__pos]; }
+
+ reference
+ operator[](size_type __pos)
+ {
+ _M_leak();
+ return _M_data()[__pos];
+ }
+
+ const_reference
+ at(size_type __n) const
+ {
+ if (__n >= this->size())
+ __throw_out_of_range("basic_string::at");
+ return _M_data()[__n];
+ }
+
+ reference
+ at(size_type __n)
+ {
+ if (__n >= size())
+ __throw_out_of_range("basic_string::at");
+ _M_leak();
+ return _M_data()[__n];
+ }
+
+ // Modifiers:
+ basic_string&
+ operator+=(const basic_string& __str) { return this->append(__str); }
+
+ basic_string&
+ operator+=(const _CharT* __s) { return this->append(__s); }
+
+ basic_string&
+ operator+=(_CharT __c) { return this->append(size_type(1), __c); }
+
+ basic_string&
+ append(const basic_string& __str);
+
+ basic_string&
+ append(const basic_string& __str, size_type __pos, size_type __n);
+
+ basic_string&
+ append(const _CharT* __s, size_type __n);
+
+ basic_string&
+ append(const _CharT* __s)
+ { return this->append(__s, traits_type::length(__s)); }
+
+ basic_string&
+ append(size_type __n, _CharT __c);
+
+ template<class _InputIterator>
+ basic_string&
+ append(_InputIterator __first, _InputIterator __last)
+ { return this->replace(_M_iend(), _M_iend(), __first, __last); }
+
+ void
+ push_back(_CharT __c)
+ { this->replace(_M_iend(), _M_iend(), 1, __c); }
+
+ basic_string&
+ assign(const basic_string& __str);
+
+ basic_string&
+ assign(const basic_string& __str, size_type __pos, size_type __n)
+ {
+ const size_type __strsize = __str.size();
+ if (__pos > __strsize)
+ __throw_out_of_range("basic_string::assign");
+ const bool __testn = __n < __strsize - __pos;
+ const size_type __newsize = __testn ? __n : __strsize - __pos;
+ return this->assign(__str._M_data() + __pos, __newsize);
+ }
+
+ basic_string&
+ assign(const _CharT* __s, size_type __n)
+ {
+ if (__n > this->max_size())
+ __throw_length_error("basic_string::assign");
+ if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
+ || less<const _CharT*>()(_M_data() + this->size(), __s))
+ return _M_replace_safe(_M_ibegin(), _M_iend(), __s, __s + __n);
+ else
+ {
+ // Work in-place
+ const size_type __pos = __s - _M_data();
+ if (__pos >= __n)
+ traits_type::copy(_M_data(), __s, __n);
+ else if (__pos)
+ traits_type::move(_M_data(), __s, __n);
+ _M_rep()->_M_length = __n;
+ _M_data()[__n] = _Rep::_S_terminal;
+ return *this;
+ }
+ }
+
+ basic_string&
+ assign(const _CharT* __s)
+ { return this->assign(__s, traits_type::length(__s)); }
+
+ basic_string&
+ assign(size_type __n, _CharT __c)
+ { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
+
+ template<class _InputIterator>
+ basic_string&
+ assign(_InputIterator __first, _InputIterator __last)
+ { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
+
+ void
+ insert(iterator __p, size_type __n, _CharT __c)
+ { this->replace(__p, __p, __n, __c); }
+
+ template<class _InputIterator>
+ void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
+ { this->replace(__p, __p, __beg, __end); }
+
+ basic_string&
+ insert(size_type __pos1, const basic_string& __str)
+ { return this->insert(__pos1, __str, 0, __str.size()); }
+
+ basic_string&
+ insert(size_type __pos1, const basic_string& __str,
+ size_type __pos2, size_type __n)
+ {
+ const size_type __strsize = __str.size();
+ if (__pos2 > __strsize)
+ __throw_out_of_range("basic_string::insert");
+ const bool __testn = __n < __strsize - __pos2;
+ const size_type __newsize = __testn ? __n : __strsize - __pos2;
+ return this->insert(__pos1, __str._M_data() + __pos2, __newsize);
+ }
+
+ basic_string&
+ insert(size_type __pos, const _CharT* __s, size_type __n)
+ {
+ const size_type __size = this->size();
+ if (__pos > __size)
+ __throw_out_of_range("basic_string::insert");
+ if (__size > this->max_size() - __n)
+ __throw_length_error("basic_string::insert");
+ 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,
+ __s, __s + __n);
+ else
+ {
+ // Work in-place. If _M_mutate reallocates the string, __s
+ // does not point anymore to valid data, therefore we save its
+ // offset, then we restore it.
+ const size_type __off = __s - _M_data();
+ _M_mutate(__pos, 0, __n);
+ __s = _M_data() + __off;
+ _CharT* __p = _M_data() + __pos;
+ if (__s + __n <= __p)
+ traits_type::copy(__p, __s, __n);
+ else if (__s >= __p)
+ traits_type::copy(__p, __s + __n, __n);
+ else
+ {
+ traits_type::copy(__p, __s, __p - __s);
+ traits_type::copy(__p + (__p - __s), __p + __n, __n - (__p - __s));
+ }
+ return *this;
+ }
+ }
+
+ basic_string&
+ insert(size_type __pos, const _CharT* __s)
+ { return this->insert(__pos, __s, traits_type::length(__s)); }
+
+ basic_string&
+ insert(size_type __pos, size_type __n, _CharT __c)
+ {
+ this->insert(_M_check(__pos), __n, __c);
+ return *this;
+ }
+
+ iterator
+ insert(iterator __p, _CharT __c = _CharT())
+ {
+ size_type __pos = __p - _M_ibegin();
+ this->insert(_M_check(__pos), size_type(1), __c);
+ _M_rep()->_M_set_leaked();
+ return this->_M_ibegin() + __pos;
+ }
+
+ basic_string&
+ erase(size_type __pos = 0, size_type __n = npos)
+ {
+ return this->replace(_M_check(__pos), _M_fold(__pos, __n),
+ _M_data(), _M_data());
+ }
+
+ iterator
+ erase(iterator __position)
+ {
+ size_type __i = __position - _M_ibegin();
+ this->replace(__position, __position + 1, _M_data(), _M_data());
+ _M_rep()->_M_set_leaked();
+ return _M_ibegin() + __i;
+ }
+
+ iterator
+ erase(iterator __first, iterator __last)
+ {
+ size_type __i = __first - _M_ibegin();
+ this->replace(__first, __last, _M_data(), _M_data());
+ _M_rep()->_M_set_leaked();
+ return _M_ibegin() + __i;
+ }
+
+ basic_string&
+ replace(size_type __pos, size_type __n, const basic_string& __str)
+ { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
+
+ basic_string&
+ replace(size_type __pos1, size_type __n1, const basic_string& __str,
+ size_type __pos2, size_type __n2);
+
+ basic_string&
+ replace(size_type __pos, size_type __n1, const _CharT* __s,
+ size_type __n2)
+ {
+ const size_type __size = this->size();
+ if (__pos > __size)
+ __throw_out_of_range("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);
+ }
+
+ basic_string&
+ replace(size_type __pos, size_type __n1, const _CharT* __s)
+ { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
+
+ basic_string&
+ replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
+ { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
+
+ basic_string&
+ replace(iterator __i1, iterator __i2, const basic_string& __str)
+ { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
+
+ basic_string&
+ replace(iterator __i1, iterator __i2,
+ const _CharT* __s, size_type __n)
+ { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
+
+ basic_string&
+ replace(iterator __i1, iterator __i2, const _CharT* __s)
+ { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
+
+ basic_string&
+ replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
+
+ template<class _InputIterator>
+ basic_string&
+ replace(iterator __i1, iterator __i2,
+ _InputIterator __k1, _InputIterator __k2)
+ { return _M_replace(__i1, __i2, __k1, __k2,
+ typename iterator_traits<_InputIterator>::iterator_category()); }
+
+ private:
+ template<class _InputIterator>
+ basic_string&
+ _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
+ _InputIterator __k2, input_iterator_tag);
+
+ template<class _ForwardIterator>
+ basic_string&
+ _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1,
+ _ForwardIterator __k2);
+
+ // _S_construct_aux is used to implement the 21.3.1 para 15 which
+ // requires special behaviour if _InIter is an integral type
+ template<class _InIter>
+ static _CharT*
+ _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
+ __false_type)
+ {
+ typedef typename iterator_traits<_InIter>::iterator_category _Tag;
+ return _S_construct(__beg, __end, __a, _Tag());
+ }
+
+ template<class _InIter>
+ static _CharT*
+ _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
+ __true_type)
+ {
+ return _S_construct(static_cast<size_type>(__beg),
+ static_cast<value_type>(__end), __a);
+ }
+
+ template<class _InIter>
+ static _CharT*
+ _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
+ {
+ typedef typename _Is_integer<_InIter>::_Integral _Integral;
+ return _S_construct_aux(__beg, __end, __a, _Integral());
+ }
+
+ // For Input Iterators, used in istreambuf_iterators, etc.
+ template<class _InIter>
+ static _CharT*
+ _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
+ input_iterator_tag);
+
+ // For forward_iterators up to random_access_iterators, used for
+ // string::iterator, _CharT*, etc.
+ template<class _FwdIter>
+ static _CharT*
+ _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a,
+ forward_iterator_tag);
+
+ static _CharT*
+ _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
+
+ public:
+
+ size_type
+ copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+
+ void
+ swap(basic_string<_CharT, _Traits, _Alloc>& __s);
+
+ // String operations:
+ const _CharT*
+ c_str() const
+ {
+ // MT: This assumes concurrent writes are OK.
+ size_type __n = this->size();
+ traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
+ return _M_data();
+ }
+
+ const _CharT*
+ data() const { return _M_data(); }
+
+ allocator_type
+ get_allocator() const { return _M_dataplus; }
+
+ size_type
+ find(const _CharT* __s, size_type __pos, size_type __n) const;
+
+ size_type
+ find(const basic_string& __str, size_type __pos = 0) const
+ { return this->find(__str.data(), __pos, __str.size()); }
+
+ size_type
+ find(const _CharT* __s, size_type __pos = 0) const
+ { return this->find(__s, __pos, traits_type::length(__s)); }
+
+ size_type
+ find(_CharT __c, size_type __pos = 0) const;
+
+ size_type
+ rfind(const basic_string& __str, size_type __pos = npos) const
+ { return this->rfind(__str.data(), __pos, __str.size()); }
+
+ size_type
+ rfind(const _CharT* __s, size_type __pos, size_type __n) const;
+
+ size_type
+ rfind(const _CharT* __s, size_type __pos = npos) const
+ { return this->rfind(__s, __pos, traits_type::length(__s)); }
+
+ size_type
+ rfind(_CharT __c, size_type __pos = npos) const;
+
+ size_type
+ find_first_of(const basic_string& __str, size_type __pos = 0) const
+ { return this->find_first_of(__str.data(), __pos, __str.size()); }
+
+ size_type
+ find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
+
+ size_type
+ find_first_of(const _CharT* __s, size_type __pos = 0) const
+ { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
+
+ size_type
+ find_first_of(_CharT __c, size_type __pos = 0) const
+ { return this->find(__c, __pos); }
+
+ size_type
+ find_last_of(const basic_string& __str, size_type __pos = npos) const
+ { return this->find_last_of(__str.data(), __pos, __str.size()); }
+
+ size_type
+ find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
+
+ size_type
+ find_last_of(const _CharT* __s, size_type __pos = npos) const
+ { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
+
+ size_type
+ find_last_of(_CharT __c, size_type __pos = npos) const
+ { return this->rfind(__c, __pos); }
+
+ size_type
+ find_first_not_of(const basic_string& __str, size_type __pos = 0) const
+ { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
+
+ size_type
+ find_first_not_of(const _CharT* __s, size_type __pos,
+ size_type __n) const;
+
+ size_type
+ find_first_not_of(const _CharT* __s, size_type __pos = 0) const
+ { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
+
+ size_type
+ find_first_not_of(_CharT __c, size_type __pos = 0) const;
+
+ size_type
+ find_last_not_of(const basic_string& __str, size_type __pos = npos) const
+ { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
+
+ size_type
+ find_last_not_of(const _CharT* __s, size_type __pos,
+ size_type __n) const;
+ size_type
+ find_last_not_of(const _CharT* __s, size_type __pos = npos) const
+ { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
+
+ size_type
+ find_last_not_of(_CharT __c, size_type __pos = npos) const;
+
+ basic_string
+ substr(size_type __pos = 0, size_type __n = npos) const
+ {
+ if (__pos > this->size())
+ __throw_out_of_range("basic_string::substr");
+ return basic_string(*this, __pos, __n);
+ }
+
+ int
+ compare(const basic_string& __str) const
+ {
+ size_type __size = this->size();
+ size_type __osize = __str.size();
+ size_type __len = min(__size, __osize);
+
+ int __r = traits_type::compare(_M_data(), __str.data(), __len);
+ if (!__r)
+ __r = __size - __osize;
+ return __r;
+ }
+
+ int
+ compare(size_type __pos, size_type __n, const basic_string& __str) const;
+
+ int
+ compare(size_type __pos1, size_type __n1, const basic_string& __str,
+ size_type __pos2, size_type __n2) const;
+
+ int
+ compare(const _CharT* __s) const;
+
+ // _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;
+ };
+
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline basic_string<_CharT, _Traits, _Alloc>::
+ basic_string()
+ : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
+
+ // operator+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>
+ operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ {
+ basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
+ __str.append(__rhs);
+ return __str;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT,_Traits,_Alloc>
+ operator+(const _CharT* __lhs,
+ const basic_string<_CharT,_Traits,_Alloc>& __rhs);
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT,_Traits,_Alloc>
+ operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline basic_string<_CharT, _Traits, _Alloc>
+ operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const _CharT* __rhs)
+ {
+ basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
+ __str.append(__rhs);
+ return __str;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline basic_string<_CharT, _Traits, _Alloc>
+ operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
+ {
+ typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
+ typedef typename __string_type::size_type __size_type;
+ __string_type __str(__lhs);
+ __str.append(__size_type(1), __rhs);
+ return __str;
+ }
+
+ // operator ==
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __lhs.compare(__rhs) == 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator==(const _CharT* __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __rhs.compare(__lhs) == 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const _CharT* __rhs)
+ { return __lhs.compare(__rhs) == 0; }
+
+ // operator !=
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __rhs.compare(__lhs) != 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator!=(const _CharT* __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __rhs.compare(__lhs) != 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const _CharT* __rhs)
+ { return __lhs.compare(__rhs) != 0; }
+
+ // operator <
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __lhs.compare(__rhs) < 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const _CharT* __rhs)
+ { return __lhs.compare(__rhs) < 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator<(const _CharT* __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __rhs.compare(__lhs) > 0; }
+
+ // operator >
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __lhs.compare(__rhs) > 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const _CharT* __rhs)
+ { return __lhs.compare(__rhs) > 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator>(const _CharT* __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __rhs.compare(__lhs) < 0; }
+
+ // operator <=
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __lhs.compare(__rhs) <= 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const _CharT* __rhs)
+ { return __lhs.compare(__rhs) <= 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator<=(const _CharT* __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __rhs.compare(__lhs) >= 0; }
+
+ // operator >=
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __lhs.compare(__rhs) >= 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ const _CharT* __rhs)
+ { return __lhs.compare(__rhs) >= 0; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline bool
+ operator>=(const _CharT* __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { return __rhs.compare(__lhs) <= 0; }
+
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline void
+ swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
+ basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>& __is,
+ basic_string<_CharT, _Traits, _Alloc>& __str);
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __os,
+ const basic_string<_CharT, _Traits, _Alloc>& __str);
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_istream<_CharT,_Traits>&
+ getline(basic_istream<_CharT, _Traits>& __is,
+ basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ inline basic_istream<_CharT,_Traits>&
+ getline(basic_istream<_CharT, _Traits>& __is,
+ basic_string<_CharT, _Traits, _Alloc>& __str);
+} // namespace std
+
+#endif /* _CPP_BITS_STRING_H */
diff --git a/contrib/libstdc++/include/bits/basic_string.tcc b/contrib/libstdc++/include/bits/basic_string.tcc
new file mode 100644
index 0000000000000..35a2f11f7e761
--- /dev/null
+++ b/contrib/libstdc++/include/bits/basic_string.tcc
@@ -0,0 +1,981 @@
+// Components for manipulating sequences of characters -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 21 Strings library
+//
+
+// This file is included by <string>. It is not meant to be included
+// separately.
+
+// Written by Jason Merrill based upon the specification by Takanori Adachi
+// in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882.
+
+#ifndef _CPP_BITS_STRING_TCC
+#define _CPP_BITS_STRING_TCC 1
+
+#pragma GCC system_header
+
+namespace std
+{
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ const typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4;
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ const _CharT
+ basic_string<_CharT, _Traits, _Alloc>::
+ _Rep::_S_terminal = _CharT();
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ const typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::npos;
+
+ // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
+ // at static init time (before static ctors are run).
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[
+ (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
+
+ // NB: This is the special case for Input Iterators, used in
+ // istreambuf_iterators, etc.
+ // Input Iterators have a cost structure very different from
+ // pointers, calling for a different coding style.
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ template<typename _InIter>
+ _CharT*
+ basic_string<_CharT, _Traits, _Alloc>::
+ _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
+ input_iterator_tag)
+ {
+ if (__beg == __end && __a == _Alloc())
+ return _S_empty_rep()._M_refcopy();
+ // Avoid reallocation for common case.
+ _CharT __buf[100];
+ size_type __i = 0;
+ while (__beg != __end && __i < sizeof(__buf) / sizeof(_CharT))
+ {
+ __buf[__i++] = *__beg;
+ ++__beg;
+ }
+ _Rep* __r = _Rep::_S_create(__i, __a);
+ traits_type::copy(__r->_M_refdata(), __buf, __i);
+ __r->_M_length = __i;
+ try
+ {
+ // NB: this loop looks precisely this way because
+ // it avoids comparing __beg != __end any more
+ // than strictly necessary; != might be expensive!
+ for (;;)
+ {
+ _CharT* __p = __r->_M_refdata() + __r->_M_length;
+ _CharT* __last = __r->_M_refdata() + __r->_M_capacity;
+ for (;;)
+ {
+ if (__beg == __end)
+ {
+ __r->_M_length = __p - __r->_M_refdata();
+ *__p = _Rep::_S_terminal; // grrr.
+ return __r->_M_refdata();
+ }
+ if (__p == __last)
+ break;
+ *__p++ = *__beg;
+ ++__beg;
+ }
+ // Allocate more space.
+ size_type __len = __p - __r->_M_refdata();
+ _Rep* __another = _Rep::_S_create(__len + 1, __a);
+ traits_type::copy(__another->_M_refdata(),
+ __r->_M_refdata(), __len);
+ __r->_M_destroy(__a);
+ __r = __another;
+ __r->_M_length = __len;
+ }
+ }
+ catch(...)
+ {
+ __r->_M_destroy(__a);
+ __throw_exception_again;
+ }
+ return 0;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ template <class _InIter>
+ _CharT*
+ basic_string<_CharT, _Traits, _Alloc>::
+ _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
+ forward_iterator_tag)
+ {
+ size_type __dnew = static_cast<size_type>(distance(__beg, __end));
+
+ // NB: Not required, but considered best practice.
+ if (__builtin_expect(__beg == _InIter(0), 0))
+ __throw_logic_error("attempt to create string with null pointer");
+
+ if (__beg == __end && __a == _Alloc())
+ return _S_empty_rep()._M_refcopy();
+
+ // Check for out_of_range and length_error exceptions.
+ _Rep* __r = _Rep::_S_create(__dnew, __a);
+ try
+ { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
+ catch(...)
+ {
+ __r->_M_destroy(__a);
+ __throw_exception_again;
+ }
+ __r->_M_length = __dnew;
+
+ __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr.
+ return __r->_M_refdata();
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ _CharT*
+ basic_string<_CharT, _Traits, _Alloc>::
+ _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
+ {
+ if (__n == 0 && __a == _Alloc())
+ return _S_empty_rep()._M_refcopy();
+
+ // Check for out_of_range and length_error exceptions.
+ _Rep* __r = _Rep::_S_create(__n, __a);
+ try
+ {
+ if (__n)
+ traits_type::assign(__r->_M_refdata(), __n, __c);
+ }
+ catch(...)
+ {
+ __r->_M_destroy(__a);
+ __throw_exception_again;
+ }
+ __r->_M_length = __n;
+ __r->_M_refdata()[__n] = _Rep::_S_terminal; // grrr
+ return __r->_M_refdata();
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(const basic_string& __str)
+ : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(), __str.get_allocator()),
+ __str.get_allocator())
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(const _Alloc& __a)
+ : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(const basic_string& __str, size_type __pos, size_type __n)
+ : _M_dataplus(_S_construct(__str._M_check(__pos),
+ __str._M_fold(__pos, __n), _Alloc()), _Alloc())
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(const basic_string& __str, size_type __pos,
+ size_type __n, const _Alloc& __a)
+ : _M_dataplus(_S_construct(__str._M_check(__pos),
+ __str._M_fold(__pos, __n), __a), __a)
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
+ : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
+ { }
+
+ 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 ? __s + traits_type::length(__s) : 0,
+ __a), __a)
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(size_type __n, _CharT __c, const _Alloc& __a)
+ : _M_dataplus(_S_construct(__n, __c, __a), __a)
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ template<typename _InputIter>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(_InputIter __beg, _InputIter __end, const _Alloc& __a)
+ : _M_dataplus(_S_construct(__beg, __end, __a), __a)
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::assign(const basic_string& __str)
+ {
+ if (_M_rep() != __str._M_rep())
+ {
+ // XXX MT
+ allocator_type __a = this->get_allocator();
+ _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
+ _M_rep()->_M_dispose(__a);
+ _M_data(__tmp);
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ basic_string<_CharT, _Traits, _Alloc>::_Rep::
+ _M_destroy(const _Alloc& __a) throw ()
+ {
+ size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT);
+ _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard()
+ {
+ if (_M_rep()->_M_is_shared())
+ _M_mutate(0, 0, 0);
+ _M_rep()->_M_set_leaked();
+ }
+
+ // _M_mutate and, below, _M_clone, include, in the same form, an exponential
+ // growth policy, necessary to meet amortized linear time requirements of
+ // the library: see http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
+ // The policy is active for allocations requiring an amount of memory above
+ // system pagesize. This is consistent with the requirements of the standard:
+ // see, f.i., http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ basic_string<_CharT, _Traits, _Alloc>::
+ _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+ {
+ size_type __old_size = this->size();
+ const size_type __new_size = __old_size + __len2 - __len1;
+ const _CharT* __src = _M_data() + __pos + __len1;
+ const size_type __how_much = __old_size - __pos - __len1;
+
+ if (_M_rep()->_M_is_shared() || __new_size > capacity())
+ {
+ // Must reallocate.
+ allocator_type __a = get_allocator();
+ // See below (_S_create) for the meaning and value of these
+ // constants.
+ const size_type __pagesize = 4096;
+ const size_type __malloc_header_size = 4 * sizeof (void*);
+ // The biggest string which fits in a memory page
+ const size_type __page_capacity = (__pagesize - __malloc_header_size
+ - sizeof(_Rep) - sizeof(_CharT))
+ / sizeof(_CharT);
+ _Rep* __r;
+ if (__new_size > capacity() && __new_size > __page_capacity)
+ // Growing exponentially.
+ __r = _Rep::_S_create(__new_size > 2*capacity() ?
+ __new_size : 2*capacity(), __a);
+ else
+ __r = _Rep::_S_create(__new_size, __a);
+ try
+ {
+ if (__pos)
+ traits_type::copy(__r->_M_refdata(), _M_data(), __pos);
+ if (__how_much)
+ traits_type::copy(__r->_M_refdata() + __pos + __len2,
+ __src, __how_much);
+ }
+ catch(...)
+ {
+ __r->_M_dispose(get_allocator());
+ __throw_exception_again;
+ }
+ _M_rep()->_M_dispose(__a);
+ _M_data(__r->_M_refdata());
+ }
+ else if (__how_much && __len1 != __len2)
+ {
+ // Work in-place
+ traits_type::move(_M_data() + __pos + __len2, __src, __how_much);
+ }
+ _M_rep()->_M_set_sharable();
+ _M_rep()->_M_length = __new_size;
+ _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4)
+ // You cannot leave those LWG people alone for a second.
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res)
+ {
+ if (__res > this->capacity() || _M_rep()->_M_is_shared())
+ {
+ if (__res > this->max_size())
+ __throw_length_error("basic_string::reserve");
+ // Make sure we don't shrink below the current size
+ if (__res < this->size())
+ __res = this->size();
+ allocator_type __a = get_allocator();
+ _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
+ _M_rep()->_M_dispose(__a);
+ _M_data(__tmp);
+ }
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s)
+ {
+ if (_M_rep()->_M_is_leaked())
+ _M_rep()->_M_set_sharable();
+ if (__s._M_rep()->_M_is_leaked())
+ __s._M_rep()->_M_set_sharable();
+ if (this->get_allocator() == __s.get_allocator())
+ {
+ _CharT* __tmp = _M_data();
+ _M_data(__s._M_data());
+ __s._M_data(__tmp);
+ }
+ // The code below can usually be optimized away.
+ else
+ {
+ basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator());
+ basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
+ this->get_allocator());
+ *this = __tmp2;
+ __s = __tmp1;
+ }
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
+ basic_string<_CharT, _Traits, _Alloc>::_Rep::
+ _S_create(size_t __capacity, const _Alloc& __alloc)
+ {
+ typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // 83. String::npos vs. string::max_size()
+ if (__capacity > _S_max_size)
+#else
+ if (__capacity == npos)
+#endif
+ __throw_length_error("basic_string::_S_create");
+
+ // NB: Need an array of char_type[__capacity], plus a
+ // terminating null char_type() element, plus enough for the
+ // _Rep data structure. Whew. Seemingly so needy, yet so elemental.
+ size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+
+ // The standard places no restriction on allocating more memory
+ // than is strictly needed within this layer at the moment or as
+ // requested by an explicit application call to reserve(). Many
+ // malloc implementations perform quite poorly when an
+ // application attempts to allocate memory in a stepwise fashion
+ // growing each allocation size by only 1 char. Additionally,
+ // it makes little sense to allocate less linear memory than the
+ // natural blocking size of the malloc implementation.
+ // Unfortunately, we would need a somewhat low-level calculation
+ // with tuned parameters to get this perfect for any particular
+ // malloc implementation. Fortunately, generalizations about
+ // common features seen among implementations seems to suffice.
+
+ // __pagesize need not match the actual VM page size for good
+ // results in practice, thus we pick a common value on the low
+ // side. __malloc_header_size is an estimate of the amount of
+ // overhead per memory allocation (in practice seen N * sizeof
+ // (void*) where N is 0, 2 or 4). According to folklore,
+ // picking this value on the high side is better than
+ // low-balling it (especially when this algorithm is used with
+ // malloc implementations that allocate memory blocks rounded up
+ // to a size which is a power of 2).
+ const size_t __pagesize = 4096; // must be 2^i * __subpagesize
+ const size_t __subpagesize = 128; // should be >> __malloc_header_size
+ const size_t __malloc_header_size = 4 * sizeof (void*);
+ if ((__size + __malloc_header_size) > __pagesize)
+ {
+ size_t __extra =
+ (__pagesize - ((__size + __malloc_header_size) % __pagesize))
+ % __pagesize;
+ __capacity += __extra / sizeof(_CharT);
+ __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+ }
+ else if (__size > __subpagesize)
+ {
+ size_t __extra =
+ (__subpagesize - ((__size + __malloc_header_size) % __subpagesize))
+ % __subpagesize;
+ __capacity += __extra / sizeof(_CharT);
+ __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
+ }
+
+ // NB: Might throw, but no worries about a leak, mate: _Rep()
+ // does not throw.
+ 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_length = 0;
+ return __p;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ _CharT*
+ basic_string<_CharT, _Traits, _Alloc>::_Rep::
+ _M_clone(const _Alloc& __alloc, size_type __res)
+ {
+ // Requested capacity of the clone.
+ const size_type __requested_cap = _M_length + __res;
+ // See above (_S_create) for the meaning and value of these constants.
+ const size_type __pagesize = 4096;
+ const size_type __malloc_header_size = 4 * sizeof (void*);
+ // The biggest string which fits in a memory page.
+ const size_type __page_capacity =
+ (__pagesize - __malloc_header_size - sizeof(_Rep) - sizeof(_CharT))
+ / sizeof(_CharT);
+ _Rep* __r;
+ if (__requested_cap > _M_capacity && __requested_cap > __page_capacity)
+ // Growing exponentially.
+ __r = _Rep::_S_create(__requested_cap > 2*_M_capacity ?
+ __requested_cap : 2*_M_capacity, __alloc);
+ else
+ __r = _Rep::_S_create(__requested_cap, __alloc);
+
+ if (_M_length)
+ {
+ try
+ { traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length); }
+ catch(...)
+ {
+ __r->_M_destroy(__alloc);
+ __throw_exception_again;
+ }
+ }
+ __r->_M_length = _M_length;
+ return __r->_M_refdata();
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)
+ {
+ if (__n > max_size())
+ __throw_length_error("basic_string::resize");
+ size_type __size = this->size();
+ if (__size < __n)
+ this->append(__n - __size, __c);
+ else if (__n < __size)
+ 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)
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ template<typename _InputIter>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ _M_replace(iterator __i1, iterator __i2, _InputIter __k1,
+ _InputIter __k2, input_iterator_tag)
+ {
+ // Save concerned source string data in a temporary.
+ basic_string __s(__k1, __k2);
+ return _M_replace_safe(__i1, __i2, __s._M_ibegin(), __s._M_iend());
+ }
+
+ // This is a special replace helper, which does not buffer internally
+ // and can be used in the "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>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ _M_replace_safe(iterator __i1, iterator __i2, _ForwardIter __k1,
+ _ForwardIter __k2)
+ {
+ size_type __dnew = static_cast<size_type>(distance(__k1, __k2));
+ size_type __dold = __i2 - __i1;
+ size_type __dmax = this->max_size();
+
+ if (__dmax <= __dnew)
+ __throw_length_error("basic_string::_M_replace");
+ size_type __off = __i1 - _M_ibegin();
+ _M_mutate(__off, __dold, __dnew);
+
+ // Invalidated __i1, __i2
+ if (__dnew)
+ _S_copy_chars(_M_data() + __off, __k1, __k2);
+
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ replace(size_type __pos1, size_type __n1, const basic_string& __str,
+ size_type __pos2, size_type __n2)
+ {
+ const size_type __strsize = __str.size();
+ if (__pos2 > __strsize)
+ __throw_out_of_range("basic_string::replace");
+ const bool __testn2 = __n2 < __strsize - __pos2;
+ const size_type __foldn2 = __testn2 ? __n2 : __strsize - __pos2;
+ return this->replace(__pos1, __n1,
+ __str._M_data() + __pos2, __foldn2);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ append(const basic_string& __str)
+ {
+ // Iff appending itself, string needs to pre-reserve the
+ // correct size so that _M_mutate does not clobber the
+ // iterators formed here.
+ size_type __size = __str.size();
+ size_type __len = __size + this->size();
+ if (__len > this->capacity())
+ this->reserve(__len);
+ return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(),
+ __str._M_iend());
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ append(const basic_string& __str, size_type __pos, size_type __n)
+ {
+ // Iff appending itself, string needs to pre-reserve the
+ // correct size so that _M_mutate does not clobber the
+ // iterators formed here.
+ size_type __len = min(__str.size() - __pos, __n) + this->size();
+ if (__len > this->capacity())
+ this->reserve(__len);
+ return _M_replace_safe(_M_iend(), _M_iend(), __str._M_check(__pos),
+ __str._M_fold(__pos, __n));
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ append(const _CharT* __s, size_type __n)
+ {
+ size_type __len = __n + this->size();
+ if (__len > this->capacity())
+ this->reserve(__len);
+ return _M_replace_safe(_M_iend(), _M_iend(), __s, __s + __n);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ append(size_type __n, _CharT __c)
+ {
+ size_type __len = __n + this->size();
+ if (__len > this->capacity())
+ this->reserve(__len);
+ return this->replace(_M_iend(), _M_iend(), __n, __c);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>
+ operator+(const _CharT* __lhs,
+ const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ {
+ typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
+ typedef typename __string_type::size_type __size_type;
+ __size_type __len = _Traits::length(__lhs);
+ __string_type __str;
+ __str.reserve(__len + __rhs.size());
+ __str.append(__lhs, __lhs + __len);
+ __str.append(__rhs);
+ return __str;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>
+ operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ {
+ typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
+ typedef typename __string_type::size_type __size_type;
+ __string_type __str;
+ __size_type __len = __rhs.size();
+ __str.reserve(__len + 1);
+ __str.append(__size_type(1), __lhs);
+ __str.append(__rhs);
+ return __str;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>&
+ basic_string<_CharT, _Traits, _Alloc>::
+ replace(iterator __i1, iterator __i2, size_type __n2, _CharT __c)
+ {
+ size_type __n1 = __i2 - __i1;
+ size_type __off1 = __i1 - _M_ibegin();
+ if (max_size() - (this->size() - __n1) <= __n2)
+ __throw_length_error("basic_string::replace");
+ _M_mutate (__off1, __n1, __n2);
+ // Invalidated __i1, __i2
+ if (__n2)
+ traits_type::assign(_M_data() + __off1, __n2, __c);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ copy(_CharT* __s, size_type __n, size_type __pos) const
+ {
+ if (__pos > this->size())
+ __throw_out_of_range("basic_string::copy");
+
+ if (__n > this->size() - __pos)
+ __n = this->size() - __pos;
+
+ traits_type::copy(__s, _M_data() + __pos, __n);
+ // 21.3.5.7 par 3: do not append null. (good.)
+ return __n;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find(const _CharT* __s, size_type __pos, size_type __n) const
+ {
+ size_type __size = this->size();
+ size_t __xpos = __pos;
+ const _CharT* __data = _M_data();
+ for (; __xpos + __n <= __size; ++__xpos)
+ if (traits_type::compare(__data + __xpos, __s, __n) == 0)
+ return __xpos;
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find(_CharT __c, size_type __pos) const
+ {
+ size_type __size = this->size();
+ size_type __ret = npos;
+ if (__pos < __size)
+ {
+ const _CharT* __data = _M_data();
+ size_type __n = __size - __pos;
+ const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
+ if (__p)
+ __ret = __p - __data;
+ }
+ return __ret;
+ }
+
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ rfind(const _CharT* __s, size_type __pos, size_type __n) const
+ {
+ size_type __size = this->size();
+ if (__n <= __size)
+ {
+ __pos = std::min(__size - __n, __pos);
+ const _CharT* __data = _M_data();
+ do
+ {
+ if (traits_type::compare(__data + __pos, __s, __n) == 0)
+ return __pos;
+ }
+ while (__pos-- > 0);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ rfind(_CharT __c, size_type __pos) const
+ {
+ size_type __size = this->size();
+ if (__size)
+ {
+ size_t __xpos = __size - 1;
+ if (__xpos > __pos)
+ __xpos = __pos;
+
+ for (++__xpos; __xpos-- > 0; )
+ if (traits_type::eq(_M_data()[__xpos], __c))
+ return __xpos;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+ {
+ for (; __n && __pos < this->size(); ++__pos)
+ {
+ const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
+ if (__p)
+ return __pos;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+ {
+ size_type __size = this->size();
+ if (__size && __n)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (traits_type::find(__s, __n, _M_data()[__size]))
+ return __size;
+ }
+ while (__size-- != 0);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+ {
+ size_t __xpos = __pos;
+ for (; __xpos < this->size(); ++__xpos)
+ if (!traits_type::find(__s, __n, _M_data()[__xpos]))
+ return __xpos;
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find_first_not_of(_CharT __c, size_type __pos) const
+ {
+ size_t __xpos = __pos;
+ for (; __xpos < this->size(); ++__xpos)
+ if (!traits_type::eq(_M_data()[__xpos], __c))
+ return __xpos;
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+ {
+ size_type __size = this->size();
+ if (__size)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (!traits_type::find(__s, __n, _M_data()[__size]))
+ return __size;
+ }
+ while (__size--);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ typename basic_string<_CharT, _Traits, _Alloc>::size_type
+ basic_string<_CharT, _Traits, _Alloc>::
+ find_last_not_of(_CharT __c, size_type __pos) const
+ {
+ size_type __size = this->size();
+ if (__size)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (!traits_type::eq(_M_data()[__size], __c))
+ return __size;
+ }
+ while (__size--);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ int
+ basic_string<_CharT, _Traits, _Alloc>::
+ compare(size_type __pos, size_type __n, const basic_string& __str) const
+ {
+ size_type __size = this->size();
+ size_type __osize = __str.size();
+ if (__pos > __size)
+ __throw_out_of_range("basic_string::compare");
+
+ size_type __rsize= min(__size - __pos, __n);
+ size_type __len = min(__rsize, __osize);
+ int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
+ if (!__r)
+ __r = __rsize - __osize;
+ return __r;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ int
+ basic_string<_CharT, _Traits, _Alloc>::
+ compare(size_type __pos1, size_type __n1, const basic_string& __str,
+ size_type __pos2, size_type __n2) const
+ {
+ size_type __size = this->size();
+ size_type __osize = __str.size();
+ if (__pos1 > __size || __pos2 > __osize)
+ __throw_out_of_range("basic_string::compare");
+
+ size_type __rsize = min(__size - __pos1, __n1);
+ size_type __rosize = min(__osize - __pos2, __n2);
+ size_type __len = min(__rsize, __rosize);
+ int __r = traits_type::compare(_M_data() + __pos1,
+ __str.data() + __pos2, __len);
+ if (!__r)
+ __r = __rsize - __rosize;
+ return __r;
+ }
+
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ int
+ basic_string<_CharT, _Traits, _Alloc>::
+ compare(const _CharT* __s) const
+ {
+ size_type __size = this->size();
+ int __r = traits_type::compare(_M_data(), __s, __size);
+ if (!__r)
+ __r = __size - traits_type::length(__s);
+ return __r;
+ }
+
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ int
+ basic_string <_CharT, _Traits, _Alloc>::
+ compare(size_type __pos, size_type __n1, const _CharT* __s) const
+ {
+ size_type __size = this->size();
+ if (__pos > __size)
+ __throw_out_of_range("basic_string::compare");
+
+ size_type __osize = traits_type::length(__s);
+ size_type __rsize = min(__size - __pos, __n1);
+ size_type __len = min(__rsize, __osize);
+ int __r = traits_type::compare(_M_data() + __pos, __s, __len);
+ if (!__r)
+ __r = __rsize - __osize;
+ return __r;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ int
+ basic_string <_CharT, _Traits, _Alloc>::
+ compare(size_type __pos, size_type __n1, const _CharT* __s,
+ size_type __n2) const
+ {
+ size_type __size = this->size();
+ if (__pos > __size)
+ __throw_out_of_range("basic_string::compare");
+
+ size_type __osize = min(traits_type::length(__s), __n2);
+ size_type __rsize = min(__size - __pos, __n1);
+ size_type __len = min(__rsize, __osize);
+ int __r = traits_type::compare(_M_data() + __pos, __s, __len);
+ if (!__r)
+ __r = __rsize - __osize;
+ return __r;
+ }
+
+ template <class _CharT, class _Traits, class _Alloc>
+ void
+ _S_string_copy(const basic_string<_CharT, _Traits, _Alloc>& __str,
+ _CharT* __buf, typename _Alloc::size_type __bufsiz)
+ {
+ typedef typename _Alloc::size_type size_type;
+ size_type __strsize = __str.size();
+ size_type __bytes = min(__strsize, __bufsiz - 1);
+ _Traits::copy(__buf, __str.data(), __bytes);
+ __buf[__bytes] = _CharT();
+ }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+ extern template class basic_string<char>;
+ extern template
+ basic_istream<char>&
+ operator>>(basic_istream<char>&, string&);
+ extern template
+ basic_ostream<char>&
+ operator<<(basic_ostream<char>&, const string&);
+ extern template
+ basic_istream<char>&
+ getline(basic_istream<char>&, string&, char);
+ extern template
+ basic_istream<char>&
+ getline(basic_istream<char>&, string&);
+
+ extern template class basic_string<wchar_t>;
+ extern template
+ basic_istream<wchar_t>&
+ operator>>(basic_istream<wchar_t>&, wstring&);
+ extern template
+ basic_ostream<wchar_t>&
+ operator<<(basic_ostream<wchar_t>&, const wstring&);
+ extern template
+ basic_istream<wchar_t>&
+ getline(basic_istream<wchar_t>&, wstring&, wchar_t);
+ extern template
+ basic_istream<wchar_t>&
+ getline(basic_istream<wchar_t>&, wstring&);
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/boost_concept_check.h b/contrib/libstdc++/include/bits/boost_concept_check.h
new file mode 100644
index 0000000000000..29ca61baef72c
--- /dev/null
+++ b/contrib/libstdc++/include/bits/boost_concept_check.h
@@ -0,0 +1,899 @@
+//
+// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
+// sell and distribute this software is granted provided this
+// copyright notice appears in all copies. This software is provided
+// "as is" without express or implied warranty, and with no claim as
+// to its suitability for any purpose.
+//
+
+// GCC Note: based on version 1.12.0 of the Boost library.
+
+/** @file boost_concept_check.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCPP_BOOST_CONCEPT_CHECK
+#define _GLIBCPP_BOOST_CONCEPT_CHECK 1
+
+#pragma GCC system_header
+#include <cstddef> // for ptrdiff_t, used next
+#include <bits/stl_iterator_base_types.h> // for traits and tags
+#include <utility> // for pair<>
+
+
+namespace __gnu_cxx
+{
+
+#define _IsUnused __attribute__ ((__unused__))
+
+// When the C-C code is in use, we would like this function to do as little
+// as possible at runtime, use as few resources as possible, and hopefully
+// be elided out of existence... hmmm.
+template <class _Concept>
+inline void __function_requires()
+{
+ void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
+}
+
+
+// ??? Should the "concept_checking*" structs begin with more than _ ?
+#define _GLIBCPP_CLASS_REQUIRES(_type_var, _ns, _concept) \
+ typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
+ template <_func##_type_var##_concept _Tp1> \
+ struct _concept_checking##_type_var##_concept { }; \
+ typedef _concept_checking##_type_var##_concept< \
+ &_ns::_concept <_type_var>::__constraints> \
+ _concept_checking_typedef##_type_var##_concept
+
+#define _GLIBCPP_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
+ typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
+ template <_func##_type_var1##_type_var2##_concept _Tp1> \
+ struct _concept_checking##_type_var1##_type_var2##_concept { }; \
+ typedef _concept_checking##_type_var1##_type_var2##_concept< \
+ &_ns::_concept <_type_var1,_type_var2>::__constraints> \
+ _concept_checking_typedef##_type_var1##_type_var2##_concept
+
+#define _GLIBCPP_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
+ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
+ template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
+ struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
+ typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
+ &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \
+ _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
+
+#define _GLIBCPP_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
+ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
+ template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
+ struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
+ typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
+ &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
+ _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
+
+
+template <class _Tp1, class _Tp2>
+struct _Aux_require_same { };
+
+template <class _Tp>
+struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
+
+ template <class _Tp1, class _Tp2>
+ struct _SameTypeConcept
+ {
+ void __constraints() {
+ typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
+ }
+ };
+
+ template <class _Tp>
+ struct _IntegerConcept {
+ void __constraints() {
+ __error_type_must_be_an_integer_type();
+ }
+ };
+ template <> struct _IntegerConcept<short> { void __constraints() {} };
+ template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
+ template <> struct _IntegerConcept<int> { void __constraints() {} };
+ template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
+ template <> struct _IntegerConcept<long> { void __constraints() {} };
+ template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
+ template <> struct _IntegerConcept<long long> { void __constraints() {} };
+ template <> struct _IntegerConcept<unsigned long long>
+ { void __constraints() {} };
+
+ template <class _Tp>
+ struct _SignedIntegerConcept {
+ void __constraints() {
+ __error_type_must_be_a_signed_integer_type();
+ }
+ };
+ template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
+ template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
+ template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
+ template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
+
+ template <class _Tp>
+ struct _UnsignedIntegerConcept {
+ void __constraints() {
+ __error_type_must_be_an_unsigned_integer_type();
+ }
+ };
+ template <> struct _UnsignedIntegerConcept<unsigned short>
+ { void __constraints() {} };
+ template <> struct _UnsignedIntegerConcept<unsigned int>
+ { void __constraints() {} };
+ template <> struct _UnsignedIntegerConcept<unsigned long>
+ { void __constraints() {} };
+ template <> struct _UnsignedIntegerConcept<unsigned long long>
+ { void __constraints() {} };
+
+ //===========================================================================
+ // Basic Concepts
+
+ template <class _Tp>
+ struct _DefaultConstructibleConcept
+ {
+ void __constraints() {
+ _Tp __a _IsUnused; // require default constructor
+ }
+ };
+
+ template <class _Tp>
+ struct _AssignableConcept
+ {
+ void __constraints() {
+ __a = __a; // require assignment operator
+ __const_constraints(__a);
+ }
+ void __const_constraints(const _Tp& __b) {
+ __a = __b; // const required for argument to assignment
+ }
+ _Tp __a;
+ };
+
+ template <class _Tp>
+ struct _CopyConstructibleConcept
+ {
+ void __constraints() {
+ _Tp __a(__b); // require copy constructor
+ _Tp* __ptr _IsUnused = &__a; // require address of operator
+ __const_constraints(__a);
+ }
+ void __const_constraints(const _Tp& __a) {
+ _Tp __c(__a) _IsUnused; // require const copy constructor
+ const _Tp* __ptr _IsUnused = &__a; // require const address of operator
+ }
+ _Tp __b;
+ };
+
+ // The SGI STL version of Assignable requires copy constructor and operator=
+ template <class _Tp>
+ struct _SGIAssignableConcept
+ {
+ void __constraints() {
+ _Tp __b(__a) _IsUnused;
+ __a = __a; // require assignment operator
+ __const_constraints(__a);
+ }
+ void __const_constraints(const _Tp& __b) {
+ _Tp __c(__b) _IsUnused;
+ __a = __b; // const required for argument to assignment
+ }
+ _Tp __a;
+ };
+
+ template <class _From, class _To>
+ struct _ConvertibleConcept
+ {
+ void __constraints() {
+ _To __y _IsUnused = __x;
+ }
+ _From __x;
+ };
+
+ // The C++ standard requirements for many concepts talk about return
+ // types that must be "convertible to bool". The problem with this
+ // requirement is that it leaves the door open for evil proxies that
+ // define things like operator|| with strange return types. Two
+ // possible solutions are:
+ // 1) require the return type to be exactly bool
+ // 2) stay with convertible to bool, and also
+ // specify stuff about all the logical operators.
+ // For now we just test for convertible to bool.
+ template <class _Tp>
+ void __aux_require_boolean_expr(const _Tp& __t) {
+ bool __x _IsUnused = __t;
+ }
+
+// FIXME
+ template <class _Tp>
+ struct _EqualityComparableConcept
+ {
+ void __constraints() {
+ __aux_require_boolean_expr(__a == __b);
+ __aux_require_boolean_expr(__a != __b);
+ }
+ _Tp __a, __b;
+ };
+
+ template <class _Tp>
+ struct _LessThanComparableConcept
+ {
+ void __constraints() {
+ __aux_require_boolean_expr(__a < __b);
+ }
+ _Tp __a, __b;
+ };
+
+ // This is equivalent to SGI STL's LessThanComparable.
+ template <class _Tp>
+ struct _ComparableConcept
+ {
+ void __constraints() {
+ __aux_require_boolean_expr(__a < __b);
+ __aux_require_boolean_expr(__a > __b);
+ __aux_require_boolean_expr(__a <= __b);
+ __aux_require_boolean_expr(__a >= __b);
+ }
+ _Tp __a, __b;
+ };
+
+#define _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
+ template <class _First, class _Second> \
+ struct _NAME { \
+ void __constraints() { (void)__constraints_(); } \
+ bool __constraints_() { \
+ return __a _OP __b; \
+ } \
+ _First __a; \
+ _Second __b; \
+ }
+
+#define _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
+ template <class _Ret, class _First, class _Second> \
+ struct _NAME { \
+ void __constraints() { (void)__constraints_(); } \
+ _Ret __constraints_() { \
+ return __a _OP __b; \
+ } \
+ _First __a; \
+ _Second __b; \
+ }
+
+ _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
+ _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
+ _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
+ _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
+ _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
+ _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
+
+ _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
+ _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
+ _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
+ _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
+ _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
+
+#undef _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
+#undef _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT
+
+ //===========================================================================
+ // Function Object Concepts
+
+ template <class _Func, class _Return>
+ struct _GeneratorConcept
+ {
+ void __constraints() {
+ const _Return& __r _IsUnused = __f();// require operator() member function
+ }
+ _Func __f;
+ };
+
+
+ template <class _Func>
+ struct _GeneratorConcept<_Func,void>
+ {
+ void __constraints() {
+ __f(); // require operator() member function
+ }
+ _Func __f;
+ };
+
+ template <class _Func, class _Return, class _Arg>
+ struct _UnaryFunctionConcept
+ {
+ void __constraints() {
+ __r = __f(__arg); // require operator()
+ }
+ _Func __f;
+ _Arg __arg;
+ _Return __r;
+ };
+
+ template <class _Func, class _Arg>
+ struct _UnaryFunctionConcept<_Func, void, _Arg> {
+ void __constraints() {
+ __f(__arg); // require operator()
+ }
+ _Func __f;
+ _Arg __arg;
+ };
+
+ template <class _Func, class _Return, class _First, class _Second>
+ struct _BinaryFunctionConcept
+ {
+ void __constraints() {
+ __r = __f(__first, __second); // require operator()
+ }
+ _Func __f;
+ _First __first;
+ _Second __second;
+ _Return __r;
+ };
+
+ template <class _Func, class _First, class _Second>
+ struct _BinaryFunctionConcept<_Func, void, _First, _Second>
+ {
+ void __constraints() {
+ __f(__first, __second); // require operator()
+ }
+ _Func __f;
+ _First __first;
+ _Second __second;
+ };
+
+ template <class _Func, class _Arg>
+ struct _UnaryPredicateConcept
+ {
+ void __constraints() {
+ __aux_require_boolean_expr(__f(__arg)); // require op() returning bool
+ }
+ _Func __f;
+ _Arg __arg;
+ };
+
+ template <class _Func, class _First, class _Second>
+ struct _BinaryPredicateConcept
+ {
+ void __constraints() {
+ __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
+ }
+ _Func __f;
+ _First __a;
+ _Second __b;
+ };
+
+ // use this when functor is used inside a container class like std::set
+ template <class _Func, class _First, class _Second>
+ struct _Const_BinaryPredicateConcept {
+ void __constraints() {
+ __const_constraints(__f);
+ }
+ void __const_constraints(const _Func& __fun) {
+ __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
+ // operator() must be a const member function
+ __aux_require_boolean_expr(__fun(__a, __b));
+ }
+ _Func __f;
+ _First __a;
+ _Second __b;
+ };
+
+ //===========================================================================
+ // Iterator Concepts
+
+ template <class _Tp>
+ struct _TrivialIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _DefaultConstructibleConcept<_Tp> >();
+ __function_requires< _AssignableConcept<_Tp> >();
+ __function_requires< _EqualityComparableConcept<_Tp> >();
+// typedef typename std::iterator_traits<_Tp>::value_type _V;
+ (void)*__i; // require dereference operator
+ }
+ _Tp __i;
+ };
+
+ template <class _Tp>
+ struct _Mutable_TrivialIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _TrivialIteratorConcept<_Tp> >();
+ *__i = *__j; // require dereference and assignment
+ }
+ _Tp __i, __j;
+ };
+
+ template <class _Tp>
+ struct _InputIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _TrivialIteratorConcept<_Tp> >();
+ // require iterator_traits typedef's
+ typedef typename std::iterator_traits<_Tp>::difference_type _D;
+// __function_requires< _SignedIntegerConcept<_D> >();
+ typedef typename std::iterator_traits<_Tp>::reference _R;
+ typedef typename std::iterator_traits<_Tp>::pointer _Pt;
+ typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
+ __function_requires< _ConvertibleConcept<
+ typename std::iterator_traits<_Tp>::iterator_category,
+ std::input_iterator_tag> >();
+ ++__i; // require preincrement operator
+ __i++; // require postincrement operator
+ }
+ _Tp __i;
+ };
+
+ template <class _Tp, class _ValueT>
+ struct _OutputIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _AssignableConcept<_Tp> >();
+ ++__i; // require preincrement operator
+ __i++; // require postincrement operator
+ *__i++ = __t; // require postincrement and assignment
+ }
+ _Tp __i;
+ _ValueT __t;
+ };
+
+ template <class _Tp>
+ struct _ForwardIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _InputIteratorConcept<_Tp> >();
+ __function_requires< _ConvertibleConcept<
+ typename std::iterator_traits<_Tp>::iterator_category,
+ std::forward_iterator_tag> >();
+ typedef typename std::iterator_traits<_Tp>::reference _R;
+ _R __r _IsUnused = *__i;
+ }
+ _Tp __i;
+ };
+
+ template <class _Tp>
+ struct _Mutable_ForwardIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _ForwardIteratorConcept<_Tp> >();
+ *__i++ = *__i; // require postincrement and assignment
+ }
+ _Tp __i;
+ };
+
+ template <class _Tp>
+ struct _BidirectionalIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _ForwardIteratorConcept<_Tp> >();
+ __function_requires< _ConvertibleConcept<
+ typename std::iterator_traits<_Tp>::iterator_category,
+ std::bidirectional_iterator_tag> >();
+ --__i; // require predecrement operator
+ __i--; // require postdecrement operator
+ }
+ _Tp __i;
+ };
+
+ template <class _Tp>
+ struct _Mutable_BidirectionalIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _BidirectionalIteratorConcept<_Tp> >();
+ __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
+ *__i-- = *__i; // require postdecrement and assignment
+ }
+ _Tp __i;
+ };
+
+
+ template <class _Tp>
+ struct _RandomAccessIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _BidirectionalIteratorConcept<_Tp> >();
+ __function_requires< _ComparableConcept<_Tp> >();
+ __function_requires< _ConvertibleConcept<
+ typename std::iterator_traits<_Tp>::iterator_category,
+ std::random_access_iterator_tag> >();
+ // ??? We don't use _R, are we just checking for "referenceability"?
+ typedef typename std::iterator_traits<_Tp>::reference _R;
+
+ __i += __n; // require assignment addition operator
+ __i = __i + __n; __i = __n + __i; // require addition with difference type
+ __i -= __n; // require assignment subtraction op
+ __i = __i - __n; // require subtraction with
+ // difference type
+ __n = __i - __j; // require difference operator
+ (void)__i[__n]; // require element access operator
+ }
+ _Tp __a, __b;
+ _Tp __i, __j;
+ typename std::iterator_traits<_Tp>::difference_type __n;
+ };
+
+ template <class _Tp>
+ struct _Mutable_RandomAccessIteratorConcept
+ {
+ void __constraints() {
+ __function_requires< _RandomAccessIteratorConcept<_Tp> >();
+ __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
+ __i[__n] = *__i; // require element access and assignment
+ }
+ _Tp __i;
+ typename std::iterator_traits<_Tp>::difference_type __n;
+ };
+
+ //===========================================================================
+ // Container Concepts
+
+ template <class _Container>
+ struct _ContainerConcept
+ {
+ typedef typename _Container::value_type _Value_type;
+ typedef typename _Container::difference_type _Difference_type;
+ typedef typename _Container::size_type _Size_type;
+ typedef typename _Container::const_reference _Const_reference;
+ typedef typename _Container::const_pointer _Const_pointer;
+ typedef typename _Container::const_iterator _Const_iterator;
+
+ void __constraints() {
+ __function_requires< _InputIteratorConcept<_Const_iterator> >();
+ __function_requires< _AssignableConcept<_Container> >();
+ const _Container __c;
+ __i = __c.begin();
+ __i = __c.end();
+ __n = __c.size();
+ __n = __c.max_size();
+ __b = __c.empty();
+ }
+ bool __b;
+ _Const_iterator __i;
+ _Size_type __n;
+ };
+
+ template <class _Container>
+ struct _Mutable_ContainerConcept
+ {
+ typedef typename _Container::value_type _Value_type;
+ typedef typename _Container::reference _Reference;
+ typedef typename _Container::iterator _Iterator;
+ typedef typename _Container::pointer _Pointer;
+
+ void __constraints() {
+ __function_requires< _ContainerConcept<_Container> >();
+ __function_requires< _AssignableConcept<_Value_type> >();
+ __function_requires< _InputIteratorConcept<_Iterator> >();
+
+ __i = __c.begin();
+ __i = __c.end();
+ __c.swap(__c2);
+ }
+ _Iterator __i;
+ _Container __c, __c2;
+ };
+
+ template <class _ForwardContainer>
+ struct _ForwardContainerConcept
+ {
+ void __constraints() {
+ __function_requires< _ContainerConcept<_ForwardContainer> >();
+ typedef typename _ForwardContainer::const_iterator _Const_iterator;
+ __function_requires< _ForwardIteratorConcept<_Const_iterator> >();
+ }
+ };
+
+ template <class _ForwardContainer>
+ struct _Mutable_ForwardContainerConcept
+ {
+ void __constraints() {
+ __function_requires< _ForwardContainerConcept<_ForwardContainer> >();
+ __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
+ typedef typename _ForwardContainer::iterator _Iterator;
+ __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
+ }
+ };
+
+ template <class _ReversibleContainer>
+ struct _ReversibleContainerConcept
+ {
+ typedef typename _ReversibleContainer::const_iterator _Const_iterator;
+ typedef typename _ReversibleContainer::const_reverse_iterator
+ _Const_reverse_iterator;
+
+ void __constraints() {
+ __function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
+ __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
+ __function_requires<
+ _BidirectionalIteratorConcept<_Const_reverse_iterator> >();
+
+ const _ReversibleContainer __c;
+ _Const_reverse_iterator __i = __c.rbegin();
+ __i = __c.rend();
+ }
+ };
+
+ template <class _ReversibleContainer>
+ struct _Mutable_ReversibleContainerConcept
+ {
+ typedef typename _ReversibleContainer::iterator _Iterator;
+ typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
+
+ void __constraints() {
+ __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
+ __function_requires<
+ _Mutable_ForwardContainerConcept<_ReversibleContainer> >();
+ __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
+ __function_requires<
+ _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
+
+ _Reverse_iterator __i = __c.rbegin();
+ __i = __c.rend();
+ }
+ _ReversibleContainer __c;
+ };
+
+ template <class _RandomAccessContainer>
+ struct _RandomAccessContainerConcept
+ {
+ typedef typename _RandomAccessContainer::size_type _Size_type;
+ typedef typename _RandomAccessContainer::const_reference _Const_reference;
+ typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
+ typedef typename _RandomAccessContainer::const_reverse_iterator
+ _Const_reverse_iterator;
+
+ void __constraints() {
+ __function_requires<
+ _ReversibleContainerConcept<_RandomAccessContainer> >();
+ __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
+ __function_requires<
+ _RandomAccessIteratorConcept<_Const_reverse_iterator> >();
+
+ const _RandomAccessContainer __c;
+ _Const_reference __r _IsUnused = __c[__n];
+ }
+ _Size_type __n;
+ };
+
+ template <class _RandomAccessContainer>
+ struct _Mutable_RandomAccessContainerConcept
+ {
+ typedef typename _RandomAccessContainer::size_type _Size_type;
+ typedef typename _RandomAccessContainer::reference _Reference;
+ typedef typename _RandomAccessContainer::iterator _Iterator;
+ typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
+
+ void __constraints() {
+ __function_requires<
+ _RandomAccessContainerConcept<_RandomAccessContainer> >();
+ __function_requires<
+ _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
+ __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
+ __function_requires<
+ _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
+
+ _Reference __r _IsUnused = __c[__i];
+ }
+ _Size_type __i;
+ _RandomAccessContainer __c;
+ };
+
+ // A Sequence is inherently mutable
+ template <class _Sequence>
+ struct _SequenceConcept
+ {
+ typedef typename _Sequence::reference _Reference;
+ typedef typename _Sequence::const_reference _Const_reference;
+
+ void __constraints() {
+ // Matt Austern's book puts DefaultConstructible here, the C++
+ // standard places it in Container
+ // function_requires< DefaultConstructible<Sequence> >();
+ __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
+ __function_requires< _DefaultConstructibleConcept<_Sequence> >();
+
+ _Sequence
+ __c(__n) _IsUnused,
+ __c2(__n, __t) _IsUnused,
+ __c3(__first, __last) _IsUnused;
+
+ __c.insert(__p, __t);
+ __c.insert(__p, __n, __t);
+ __c.insert(__p, __first, __last);
+
+ __c.erase(__p);
+ __c.erase(__p, __q);
+
+ _Reference __r _IsUnused = __c.front();
+
+ __const_constraints(__c);
+ }
+ void __const_constraints(const _Sequence& __c) {
+ _Const_reference __r _IsUnused = __c.front();
+ }
+ typename _Sequence::value_type __t;
+ typename _Sequence::size_type __n;
+ typename _Sequence::value_type *__first, *__last;
+ typename _Sequence::iterator __p, __q;
+ };
+
+ template <class _FrontInsertionSequence>
+ struct _FrontInsertionSequenceConcept
+ {
+ void __constraints() {
+ __function_requires< _SequenceConcept<_FrontInsertionSequence> >();
+
+ __c.push_front(__t);
+ __c.pop_front();
+ }
+ _FrontInsertionSequence __c;
+ typename _FrontInsertionSequence::value_type __t;
+ };
+
+ template <class _BackInsertionSequence>
+ struct _BackInsertionSequenceConcept
+ {
+ typedef typename _BackInsertionSequence::reference _Reference;
+ typedef typename _BackInsertionSequence::const_reference _Const_reference;
+
+ void __constraints() {
+ __function_requires< _SequenceConcept<_BackInsertionSequence> >();
+
+ __c.push_back(__t);
+ __c.pop_back();
+ _Reference __r _IsUnused = __c.back();
+ }
+ void __const_constraints(const _BackInsertionSequence& __c) {
+ _Const_reference __r _IsUnused = __c.back();
+ };
+ _BackInsertionSequence __c;
+ typename _BackInsertionSequence::value_type __t;
+ };
+
+ template <class _AssociativeContainer>
+ struct _AssociativeContainerConcept
+ {
+ void __constraints() {
+ __function_requires< _ForwardContainerConcept<_AssociativeContainer> >();
+ __function_requires<
+ _DefaultConstructibleConcept<_AssociativeContainer> >();
+
+ __i = __c.find(__k);
+ __r = __c.equal_range(__k);
+ __c.erase(__k);
+ __c.erase(__i);
+ __c.erase(__r.first, __r.second);
+ __const_constraints(__c);
+ }
+ void __const_constraints(const _AssociativeContainer& __c) {
+ __ci = __c.find(__k);
+ __n = __c.count(__k);
+ __cr = __c.equal_range(__k);
+ }
+ typedef typename _AssociativeContainer::iterator _Iterator;
+ typedef typename _AssociativeContainer::const_iterator _Const_iterator;
+
+ _AssociativeContainer __c;
+ _Iterator __i;
+ std::pair<_Iterator,_Iterator> __r;
+ _Const_iterator __ci;
+ std::pair<_Const_iterator,_Const_iterator> __cr;
+ typename _AssociativeContainer::key_type __k;
+ typename _AssociativeContainer::size_type __n;
+ };
+
+ template <class _UniqueAssociativeContainer>
+ struct _UniqueAssociativeContainerConcept
+ {
+ void __constraints() {
+ __function_requires<
+ _AssociativeContainerConcept<_UniqueAssociativeContainer> >();
+
+ _UniqueAssociativeContainer __c(__first, __last);
+
+ __pos_flag = __c.insert(__t);
+ __c.insert(__first, __last);
+ }
+ std::pair<typename _UniqueAssociativeContainer::iterator, bool> __pos_flag;
+ typename _UniqueAssociativeContainer::value_type __t;
+ typename _UniqueAssociativeContainer::value_type *__first, *__last;
+ };
+
+ template <class _MultipleAssociativeContainer>
+ struct _MultipleAssociativeContainerConcept
+ {
+ void __constraints() {
+ __function_requires<
+ _AssociativeContainerConcept<_MultipleAssociativeContainer> >();
+
+ _MultipleAssociativeContainer __c(__first, __last);
+
+ __pos = __c.insert(__t);
+ __c.insert(__first, __last);
+
+ }
+ typename _MultipleAssociativeContainer::iterator __pos _IsUnused;
+ typename _MultipleAssociativeContainer::value_type __t;
+ typename _MultipleAssociativeContainer::value_type *__first, *__last;
+ };
+
+ template <class _SimpleAssociativeContainer>
+ struct _SimpleAssociativeContainerConcept
+ {
+ void __constraints() {
+ __function_requires<
+ _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
+ typedef typename _SimpleAssociativeContainer::key_type _Key_type;
+ typedef typename _SimpleAssociativeContainer::value_type _Value_type;
+ typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type
+ _Requqired;
+ }
+ };
+
+ template <class _SimpleAssociativeContainer>
+ struct _PairAssociativeContainerConcept
+ {
+ void __constraints() {
+ __function_requires<
+ _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
+ typedef typename _SimpleAssociativeContainer::key_type _Key_type;
+ typedef typename _SimpleAssociativeContainer::value_type _Value_type;
+ typedef typename _SimpleAssociativeContainer::mapped_type _Mapped_type;
+ typedef std::pair<const _Key_type, _Mapped_type> _Required_value_type;
+ typedef typename _Aux_require_same<_Value_type,
+ _Required_value_type>::_Type _Required;
+ }
+ };
+
+ template <class _SortedAssociativeContainer>
+ struct _SortedAssociativeContainerConcept
+ {
+ void __constraints() {
+ __function_requires<
+ _AssociativeContainerConcept<_SortedAssociativeContainer> >();
+ __function_requires<
+ _ReversibleContainerConcept<_SortedAssociativeContainer> >();
+
+ _SortedAssociativeContainer
+ __c(__kc) _IsUnused,
+ __c2(__first, __last) _IsUnused,
+ __c3(__first, __last, __kc) _IsUnused;
+
+ __p = __c.upper_bound(__k);
+ __p = __c.lower_bound(__k);
+ __r = __c.equal_range(__k);
+
+ __c.insert(__p, __t);
+ }
+ void __const_constraints(const _SortedAssociativeContainer& __c) {
+ __kc = __c.key_comp();
+ __vc = __c.value_comp();
+
+ __cp = __c.upper_bound(__k);
+ __cp = __c.lower_bound(__k);
+ __cr = __c.equal_range(__k);
+ }
+ typename _SortedAssociativeContainer::key_compare __kc;
+ typename _SortedAssociativeContainer::value_compare __vc;
+ typename _SortedAssociativeContainer::value_type __t;
+ typename _SortedAssociativeContainer::key_type __k;
+ typedef typename _SortedAssociativeContainer::iterator _Iterator;
+ typedef typename _SortedAssociativeContainer::const_iterator
+ _Const_iterator;
+
+ _Iterator __p;
+ _Const_iterator __cp;
+ std::pair<_Iterator,_Iterator> __r;
+ std::pair<_Const_iterator,_Const_iterator> __cr;
+ typename _SortedAssociativeContainer::value_type *__first, *__last;
+ };
+
+ // HashedAssociativeContainer
+
+} // namespace __gnu_cxx
+
+#undef _IsUnused
+
+#endif // _GLIBCPP_BOOST_CONCEPT_CHECK
+
+
diff --git a/contrib/libstdc++/include/bits/c++config b/contrib/libstdc++/include/bits/c++config
new file mode 100644
index 0000000000000..d5bf45841e583
--- /dev/null
+++ b/contrib/libstdc++/include/bits/c++config
@@ -0,0 +1,77 @@
+// Predefined symbols and macros -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _CPP_CPPCONFIG
+#define _CPP_CPPCONFIG 1
+
+// Pick up any OS-specific definitions.
+#include <bits/os_defines.h>
+
+// The current version of the C++ library in compressed ISO date format.
+#define __GLIBCPP__ 20020513
+
+// This is necessary until GCC supports separate template
+// compilation.
+#define _GLIBCPP_NO_TEMPLATE_EXPORT 1
+
+// This is a hack around not having either pre-compiled headers or
+// export compilation. If defined, the io, string, and valarray
+// headers will include all the necessary bits. If not defined, the
+// implementation optimizes the headers for the most commonly-used
+// types. For the io library, this means that larger, out-of-line
+// member functions are only declared, and definitions are not parsed
+// by the compiler, but instead instantiated into the library binary.
+#define _GLIBCPP_FULLY_COMPLIANT_HEADERS 1
+
+// To enable older, ARM-style iostreams and other anachronisms use this.
+//#define _GLIBCPP_DEPRECATED 1
+
+// Use corrected code from the committee library group's issues list.
+#define _GLIBCPP_RESOLVE_LIB_DEFECTS 1
+
+// 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
+// threading models has been removed. Note: gthr.h may well map to
+// gthr-single.h which is a correct way to express no threads support
+// in gcc. Support for the undocumented _NOTHREADS has been removed.
+
+// Default to the typically high-speed, pool-based allocator (as
+// libstdc++-v2) instead of the malloc-based allocator (libstdc++-v3
+// snapshots). See libstdc++-v3/docs/html/17_intro/howto.html for
+// details on why you don't want to override this setting. Ensure
+// 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.
+
+// The remainder of the prewritten config is mostly automatic; all the
+// user hooks are listed above.
+
+// End of prewritten config; the discovered settings follow.
diff --git a/contrib/libstdc++/include/bits/char_traits.h b/contrib/libstdc++/include/bits/char_traits.h
new file mode 100644
index 0000000000000..7d14838ab2687
--- /dev/null
+++ b/contrib/libstdc++/include/bits/char_traits.h
@@ -0,0 +1,280 @@
+// Character Traits for use by standard string and iostream -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 21 Strings library
+//
+
+/** @file char_traits.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_CHAR_TRAITS_H
+#define _CPP_BITS_CHAR_TRAITS_H 1
+
+#pragma GCC system_header
+
+#include <cstring> // For memmove, memset, memchr
+#include <bits/fpos.h> // For streampos
+
+namespace std
+{
+ /// 21.1.2 Basis for explicit _Traits specialization
+ /// NB: That for any given actual character type this definition is
+ /// probably wrong.
+ template<class _CharT>
+ struct char_traits
+ {
+ typedef _CharT char_type;
+ // Unsigned as wint_t in 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; }
+
+ static bool
+ eq(const char_type& __c1, const char_type& __c2)
+ { return __c1 == __c2; }
+
+ static bool
+ lt(const char_type& __c1, const char_type& __c2)
+ { return __c1 < __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;
+ }
+
+ static size_t
+ length(const char_type* __s)
+ {
+ const char_type* __p = __s;
+ while (*__p) ++__p;
+ return (__p - __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;
+ }
+
+ static char_type*
+ move(char_type* __s1, const char_type* __s2, size_t __n)
+ { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); }
+
+ static char_type*
+ copy(char_type* __s1, const char_type* __s2, size_t __n)
+ { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); }
+
+ 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;
+ }
+
+ static char_type
+ to_char_type(const int_type& __c)
+ { return char_type(__c); }
+
+ static int_type
+ to_int_type(const char_type& __c) { return int_type(__c); }
+
+ static bool
+ eq_int_type(const int_type& __c1, const int_type& __c2)
+ { return __c1 == __c2; }
+
+ static int_type
+ eof() { return static_cast<int_type>(-1); }
+
+ static int_type
+ not_eof(const int_type& __c)
+ { return eq_int_type(__c, eof()) ? int_type(0) : __c; }
+ };
+
+
+ /// 21.1.4 char_traits specializations
+ template<>
+ struct char_traits<char>
+ {
+ typedef char char_type;
+ typedef int 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; }
+
+ static bool
+ eq(const char_type& __c1, const char_type& __c2)
+ { return __c1 == __c2; }
+
+ static bool
+ lt(const char_type& __c1, const char_type& __c2)
+ { return __c1 < __c2; }
+
+ static int
+ compare(const char_type* __s1, const char_type* __s2, size_t __n)
+ { return memcmp(__s1, __s2, __n); }
+
+ static size_t
+ length(const char_type* __s)
+ { return strlen(__s); }
+
+ static const char_type*
+ find(const char_type* __s, size_t __n, const char_type& __a)
+ { return static_cast<const char_type*>(memchr(__s, __a, __n)); }
+
+ static char_type*
+ move(char_type* __s1, const char_type* __s2, size_t __n)
+ { return static_cast<char_type*>(memmove(__s1, __s2, __n)); }
+
+ static char_type*
+ copy(char_type* __s1, const char_type* __s2, size_t __n)
+ { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); }
+
+ static char_type*
+ assign(char_type* __s, size_t __n, char_type __a)
+ { return static_cast<char_type*>(memset(__s, __a, __n)); }
+
+ static char_type
+ to_char_type(const int_type& __c)
+ { return static_cast<char_type>(__c); }
+
+ // To keep both the byte 0xff and the eof symbol 0xffffffff
+ // from ending up as 0xffffffff.
+ static int_type
+ to_int_type(const char_type& __c)
+ { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
+
+ static bool
+ eq_int_type(const int_type& __c1, const int_type& __c2)
+ { return __c1 == __c2; }
+
+ static int_type
+ eof() { return static_cast<int_type>(EOF); }
+
+ static int_type
+ not_eof(const int_type& __c)
+ { return (__c == eof()) ? 0 : __c; }
+ };
+
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ struct char_traits<wchar_t>
+ {
+ typedef wchar_t char_type;
+ typedef wint_t int_type;
+ typedef streamoff off_type;
+ typedef wstreampos pos_type;
+ typedef mbstate_t state_type;
+
+ static void
+ assign(char_type& __c1, const char_type& __c2)
+ { __c1 = __c2; }
+
+ static bool
+ eq(const char_type& __c1, const char_type& __c2)
+ { return __c1 == __c2; }
+
+ static bool
+ lt(const char_type& __c1, const char_type& __c2)
+ { return __c1 < __c2; }
+
+ static int
+ compare(const char_type* __s1, const char_type* __s2, size_t __n)
+ { return wmemcmp(__s1, __s2, __n); }
+
+ static size_t
+ length(const char_type* __s)
+ { return wcslen(__s); }
+
+ static const char_type*
+ find(const char_type* __s, size_t __n, const char_type& __a)
+ { return wmemchr(__s, __a, __n); }
+
+ static char_type*
+ move(char_type* __s1, const char_type* __s2, int_type __n)
+ { return wmemmove(__s1, __s2, __n); }
+
+ static char_type*
+ copy(char_type* __s1, const char_type* __s2, size_t __n)
+ { return wmemcpy(__s1, __s2, __n); }
+
+ static char_type*
+ assign(char_type* __s, size_t __n, char_type __a)
+ { return wmemset(__s, __a, __n); }
+
+ static char_type
+ to_char_type(const int_type& __c) { return char_type(__c); }
+
+ static int_type
+ to_int_type(const char_type& __c) { return int_type(__c); }
+
+ static bool
+ eq_int_type(const int_type& __c1, const int_type& __c2)
+ { return __c1 == __c2; }
+
+ static int_type
+ eof() { return static_cast<int_type>(WEOF); }
+
+ static int_type
+ not_eof(const int_type& __c)
+ { return eq_int_type(__c, eof()) ? 0 : __c; }
+ };
+#endif //_GLIBCPP_USE_WCHAR_T
+
+ template<typename _CharT, typename _Traits>
+ struct _Char_traits_match
+ {
+ _CharT _M_c;
+ _Char_traits_match(_CharT const& __c) : _M_c(__c) { }
+
+ bool
+ operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); }
+ };
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/codecvt.h b/contrib/libstdc++/include/bits/codecvt.h
new file mode 100644
index 0000000000000..506752f3432c1
--- /dev/null
+++ b/contrib/libstdc++/include/bits/codecvt.h
@@ -0,0 +1,336 @@
+// Locale support (codecvt) -*- C++ -*-
+
+// Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 22.2.1.5 Template class codecvt
+//
+
+// Written by Benjamin Kosnik <bkoz@cygnus.com>
+
+/** @file codecvt.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_CODECVT_H
+#define _CPP_BITS_CODECVT_H 1
+
+#pragma GCC system_header
+
+ // 22.2.1.5 Template class codecvt
+ class codecvt_base
+ {
+ public:
+ enum result
+ {
+ ok,
+ partial,
+ error,
+ noconv
+ };
+ };
+
+ // Template class __codecvt_abstract_base
+ // NB: An abstract base class that fills in the public inlines, so
+ // that the specializations don't have to re-copy the public
+ // interface.
+ template<typename _InternT, typename _ExternT, typename _StateT>
+ class __codecvt_abstract_base
+ : public locale::facet, public codecvt_base
+ {
+ public:
+ // Types:
+ 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
+ out(state_type& __state, const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const
+ {
+ return this->do_out(__state, __from, __from_end, __from_next,
+ __to, __to_end, __to_next);
+ }
+
+ result
+ unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const
+ { return this->do_unshift(__state, __to,__to_end,__to_next); }
+
+ result
+ in(state_type& __state, const extern_type* __from,
+ const extern_type* __from_end, const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const
+ {
+ return this->do_in(__state, __from, __from_end, __from_next,
+ __to, __to_end, __to_next);
+ }
+
+ int
+ encoding() const throw()
+ { return this->do_encoding(); }
+
+ bool
+ always_noconv() const throw()
+ { return this->do_always_noconv(); }
+
+ int
+ length(const state_type& __state, const extern_type* __from,
+ const extern_type* __end, size_t __max) const
+ { return this->do_length(__state, __from, __end, __max); }
+
+ int
+ max_length() const throw()
+ { return this->do_max_length(); }
+
+ protected:
+ explicit
+ __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
+
+ virtual
+ ~__codecvt_abstract_base() { }
+
+ virtual result
+ do_out(state_type& __state, const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const = 0;
+
+ virtual result
+ do_unshift(state_type& __state, extern_type* __to,
+ extern_type* __to_end, extern_type*& __to_next) const = 0;
+
+ virtual result
+ do_in(state_type& __state, const extern_type* __from,
+ const extern_type* __from_end, const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const = 0;
+
+ virtual int
+ do_encoding() const throw() = 0;
+
+ virtual bool
+ do_always_noconv() const throw() = 0;
+
+ virtual int
+ do_length(const state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const = 0;
+
+ virtual int
+ do_max_length() const throw() = 0;
+ };
+
+ // 22.2.1.5 Template class codecvt
+ // NB: Generic, mostly useless implementation.
+ template<typename _InternT, typename _ExternT, typename _StateT>
+ class codecvt
+ : public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
+ {
+ public:
+ // Types:
+ typedef codecvt_base::result result;
+ typedef _InternT intern_type;
+ typedef _ExternT extern_type;
+ typedef _StateT state_type;
+
+ // Data Members:
+ static locale::id id;
+
+ explicit
+ codecvt(size_t __refs = 0)
+ : __codecvt_abstract_base<_InternT,_ExternT,_StateT> (__refs) { }
+
+ protected:
+ virtual
+ ~codecvt() { }
+
+ virtual result
+ do_out(state_type& __state, const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_unshift(state_type& __state, extern_type* __to,
+ extern_type* __to_end, extern_type*& __to_next) const;
+
+ virtual result
+ do_in(state_type& __state, const extern_type* __from,
+ const extern_type* __from_end, const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const;
+
+ virtual int
+ do_encoding() const throw();
+
+ virtual bool
+ do_always_noconv() const throw();
+
+ virtual int
+ do_length(const state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const;
+
+ virtual int
+ do_max_length() const throw();
+ };
+
+ template<typename _InternT, typename _ExternT, typename _StateT>
+ locale::id codecvt<_InternT, _ExternT, _StateT>::id;
+
+ // codecvt<char, char, mbstate_t> required specialization
+ template<>
+ class codecvt<char, char, mbstate_t>
+ : public __codecvt_abstract_base<char, char, mbstate_t>
+ {
+ public:
+ // Types:
+ typedef char intern_type;
+ typedef char extern_type;
+ typedef mbstate_t state_type;
+
+ // Data Members:
+ static locale::id id;
+
+ explicit
+ codecvt(size_t __refs = 0);
+
+ protected:
+ virtual
+ ~codecvt();
+
+ virtual result
+ do_out(state_type& __state, const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_unshift(state_type& __state, extern_type* __to,
+ extern_type* __to_end, extern_type*& __to_next) const;
+
+ virtual result
+ do_in(state_type& __state, const extern_type* __from,
+ const extern_type* __from_end, const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const;
+
+ virtual int
+ do_encoding() const throw();
+
+ virtual bool
+ do_always_noconv() const throw();
+
+ virtual int
+ do_length(const state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const;
+
+ virtual int
+ do_max_length() const throw();
+ };
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ // codecvt<wchar_t, char, mbstate_t> required specialization
+ template<>
+ class codecvt<wchar_t, char, mbstate_t>
+ : public __codecvt_abstract_base<wchar_t, char, mbstate_t>
+ {
+ public:
+ // Types:
+ typedef wchar_t intern_type;
+ typedef char extern_type;
+ typedef mbstate_t state_type;
+
+ // Data Members:
+ static locale::id id;
+
+ explicit
+ codecvt(size_t __refs = 0);
+
+ protected:
+ virtual
+ ~codecvt();
+
+ virtual result
+ do_out(state_type& __state, const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_unshift(state_type& __state,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_in(state_type& __state,
+ const extern_type* __from, const extern_type* __from_end,
+ const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const;
+
+ virtual
+ int do_encoding() const throw();
+
+ virtual
+ bool do_always_noconv() const throw();
+
+ virtual
+ int do_length(const state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const;
+
+ virtual int
+ do_max_length() const throw();
+ };
+#endif //_GLIBCPP_USE_WCHAR_T
+
+ // 22.2.1.6 Template class codecvt_byname
+ template<typename _InternT, typename _ExternT, typename _StateT>
+ class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
+ {
+ public:
+ explicit
+ codecvt_byname(const char*, size_t __refs = 0)
+ : codecvt<_InternT, _ExternT, _StateT>(__refs) { }
+ protected:
+ virtual
+ ~codecvt_byname() { }
+ };
+
+ // Include host and configuration specific partial specializations
+ // with additional functionality, if possible.
+#ifdef _GLIBCPP_USE_WCHAR_T
+ #include <bits/codecvt_specializations.h>
+#endif
+
+#endif // _CPP_BITS_CODECVT_H
diff --git a/contrib/libstdc++/include/bits/concept_check.h b/contrib/libstdc++/include/bits/concept_check.h
new file mode 100644
index 0000000000000..92ceefbd685e0
--- /dev/null
+++ b/contrib/libstdc++/include/bits/concept_check.h
@@ -0,0 +1,86 @@
+// Concept-checking control -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file concept_check.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCPP_CONCEPT_CHECK
+#define _GLIBCPP_CONCEPT_CHECK 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+
+// All places in libstdc++-v3 where these are used, or /might/ be used, or
+// don't need to be used, or perhaps /should/ be used, are commented with
+// "concept requirements" (and maybe some more text). So grep like crazy
+// if you're looking for additional places to use these.
+
+// Concept-checking code is off by default unless users turn it on via
+// configure options or editing c++config.h.
+
+#ifndef _GLIBCPP_CONCEPT_CHECKS
+
+#define __glibcpp_function_requires(...)
+#define __glibcpp_class_requires(_a,_b)
+#define __glibcpp_class_requires2(_a,_b,_c)
+#define __glibcpp_class_requires3(_a,_b,_c,_d)
+#define __glibcpp_class_requires4(_a,_b,_c,_d,_e)
+
+#else // the checks are on
+
+#include <bits/boost_concept_check.h>
+
+// Note that the obvious and elegant approach of
+//
+//#define glibcpp_function_requires(C) \
+// boost::function_requires< boost::C >()
+//
+// won't work due to concept templates with more than one parameter, e.g.,
+// BinaryPredicateConcept. The preprocessor tries to split things up on
+// the commas in the template argument list. We can't use an inner pair of
+// parenthesis to hide the commas, because "boost::(Temp<Foo,Bar>)" isn't
+// a valid instantiation pattern. Thus, we steal a feature from C99.
+
+#define __glibcpp_function_requires(...) \
+ __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();
+#define __glibcpp_class_requires(_a,_C) \
+ _GLIBCPP_CLASS_REQUIRES(_a, __gnu_cxx, _C);
+#define __glibcpp_class_requires2(_a,_b,_C) \
+ _GLIBCPP_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C);
+#define __glibcpp_class_requires3(_a,_b,_c,_C) \
+ _GLIBCPP_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C);
+#define __glibcpp_class_requires4(_a,_b,_c,_d,_C) \
+ _GLIBCPP_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C);
+
+#endif // enable/disable
+
+#endif // _GLIBCPP_CONCEPT_CHECK
diff --git a/contrib/libstdc++/include/bits/cpp_type_traits.h b/contrib/libstdc++/include/bits/cpp_type_traits.h
new file mode 100644
index 0000000000000..d66fe7638410f
--- /dev/null
+++ b/contrib/libstdc++/include/bits/cpp_type_traits.h
@@ -0,0 +1,300 @@
+// The -*- C++ -*- type traits classes for internal use in libstdc++
+
+// Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
+
+/** @file cpp_type_traits.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_CPP_TYPE_TRAITS_H
+#define _CPP_BITS_CPP_TYPE_TRAITS_H 1
+
+#pragma GCC system_header
+
+//
+// This file provides some compile-time information about various types.
+// These representations were designed, on purpose, to be constant-expressions
+// and not types as found in <stl/bits/type_traits.h>. In particular, they
+// can be used in control structures and the optimizer hopefully will do
+// the obvious thing.
+//
+// Why integral expressions, and not functions nor types?
+// Firstly, these compile-time entities are used as template-arguments
+// so function return values won't work: We need compile-time entities.
+// We're left with types and constant integral expressions.
+// Secondly, from the point of view of ease of use, type-based compile-time
+// information is -not- *that* convenient. On has to write lots of
+// overloaded functions and to hope that the compiler will select the right
+// one. As a net effect, the overall structure isn't very clear at first
+// glance.
+// Thirdly, partial ordering and overload resolution (of function templates)
+// is highly costly in terms of compiler-resource. It is a Good Thing to
+// keep these resource consumption as least as possible.
+//
+// See valarray_array.h for a case use.
+//
+// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
+//
+
+namespace std
+{
+ template<typename _Tp>
+ struct __is_void
+ {
+ enum
+ {
+ _M_type = 0
+ };
+ };
+
+ template<>
+ struct __is_void<void>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ //
+ // Integer types
+ //
+ template<typename _Tp>
+ struct __is_integer
+ {
+ enum
+ {
+ _M_type = 0
+ };
+ };
+
+ // Thirteen specializations (yes there are eleven standard integer
+ // types; 'long long' and 'unsigned long long' are supported as
+ // extensions)
+ template<>
+ struct __is_integer<bool>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<char>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<signed char>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<unsigned char>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+# ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ struct __is_integer<wchar_t>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+# endif
+
+ template<>
+ struct __is_integer<short>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<unsigned short>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<int>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<unsigned int>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<long>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<unsigned long>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<long long>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_integer<unsigned long long>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ //
+ // Floating point types
+ //
+ template<typename _Tp>
+ struct __is_floating
+ {
+ enum
+ {
+ _M_type = 0
+ };
+ };
+
+ // three specializations (float, double and 'long double')
+ template<>
+ struct __is_floating<float>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_floating<double>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ template<>
+ struct __is_floating<long double>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
+ //
+ // An arithmetic type is an integer type or a floating point type
+ //
+ template<typename _Tp>
+ struct __is_arithmetic
+ {
+ enum
+ {
+ _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type
+ };
+ };
+
+ //
+ // A fundamental type is `void' or and arithmetic type
+ //
+ template<typename _Tp>
+ struct __is_fundamental
+ {
+ enum
+ {
+ _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type
+ };
+ };
+
+ //
+ // For the immediate use, the following is a good approximation
+ //
+ template<typename _Tp>
+ struct __is_pod
+ {
+ enum
+ {
+ _M_type = __is_fundamental<_Tp>::_M_type
+ };
+ };
+
+} // namespace std
+
+
+#endif //_CPP_BITS_CPP_TYPE_TRAITS_H
diff --git a/contrib/libstdc++/include/bits/fpos.h b/contrib/libstdc++/include/bits/fpos.h
new file mode 100644
index 0000000000000..3cb3e4b51a261
--- /dev/null
+++ b/contrib/libstdc++/include/bits/fpos.h
@@ -0,0 +1,123 @@
+// File position object and stream types
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27 Input/output library
+//
+
+/** @file fpos.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_FPOS_H
+#define _CPP_BITS_FPOS_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++io.h>
+#include <cwchar> // For mbstate_t.
+
+namespace std
+{
+ // 27.4.1 Types
+
+ // 27.4.3 Template class fpos
+ template<typename _StateT>
+ class fpos
+ {
+ public:
+ // Types:
+ typedef _StateT __state_type;
+
+ private:
+ streamoff _M_off;
+ __state_type _M_st;
+
+ public:
+ __state_type
+ state() const { return _M_st; }
+
+ void
+ state(__state_type __st) { _M_st = __st; }
+
+ // NB: The standard defines only the implicit copy ctor and the
+ // previous two members. The rest is a "conforming extension".
+ fpos(): _M_off(streamoff()), _M_st(__state_type()) { }
+
+ fpos(streamoff __off, __state_type __st = __state_type())
+ : _M_off(__off), _M_st(__st) { }
+
+ operator streamoff() const { return _M_off; }
+
+ fpos&
+ operator+=(streamoff __off) { _M_off += __off; return *this; }
+
+ fpos&
+ operator-=(streamoff __off) { _M_off -= __off; return *this; }
+
+ fpos
+ operator+(streamoff __off)
+ {
+ fpos __t(*this);
+ __t += __off;
+ return __t;
+ }
+
+ fpos
+ operator-(streamoff __off)
+ {
+ fpos __t(*this);
+ __t -= __off;
+ return __t;
+ }
+
+ bool
+ operator==(const fpos& __pos) const
+ { return _M_off == __pos._M_off; }
+
+ bool
+ operator!=(const fpos& __pos) const
+ { return _M_off != __pos._M_off; }
+
+ streamoff
+ _M_position() const { return _M_off; }
+
+ void
+ _M_position(streamoff __off) { _M_off = __off; }
+ };
+
+ // 27.2, paragraph 10 about fpos/char_traits circularity
+ typedef fpos<mbstate_t> streampos;
+# ifdef _GLIBCPP_USE_WCHAR_T
+ typedef fpos<mbstate_t> wstreampos;
+# endif
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/fstream.tcc b/contrib/libstdc++/include/bits/fstream.tcc
new file mode 100644
index 0000000000000..90850f54f0d70
--- /dev/null
+++ b/contrib/libstdc++/include/bits/fstream.tcc
@@ -0,0 +1,589 @@
+// File based streams -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.8 File-based streams
+//
+
+#ifndef _CPP_BITS_FSTREAM_TCC
+#define _CPP_BITS_FSTREAM_TCC 1
+
+#pragma GCC system_header
+
+namespace std
+{
+ template<typename _CharT, typename _Traits>
+ void
+ basic_filebuf<_CharT, _Traits>::
+ _M_allocate_internal_buffer()
+ {
+ if (!_M_buf && _M_buf_size_opt)
+ {
+ _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_allocated = true;
+ }
+ }
+
+ // Both close and setbuf need to deallocate internal buffers, if it exists.
+ template<typename _CharT, typename _Traits>
+ void
+ basic_filebuf<_CharT, _Traits>::
+ _M_destroy_internal_buffer()
+ {
+ if (_M_buf_allocated)
+ {
+ delete [] _M_buf;
+ _M_buf = NULL;
+ _M_buf_allocated = false;
+ this->setg(NULL, NULL, NULL);
+ this->setp(NULL, NULL);
+ }
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_filebuf<_CharT, _Traits>::
+ 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*
+ basic_filebuf<_CharT, _Traits>::
+ open(const char* __s, ios_base::openmode __mode)
+ {
+ __filebuf_type *__ret = NULL;
+ if (!this->is_open())
+ {
+ _M_file.open(__s, __mode);
+ if (this->is_open())
+ {
+ _M_allocate_internal_buffer();
+ _M_mode = __mode;
+
+ // For time being, set both (in/out) sets of pointers.
+ _M_set_indeterminate();
+ if ((__mode & ios_base::ate)
+ && this->seekoff(0, ios_base::end, __mode) < 0)
+ this->close();
+ __ret = this;
+ }
+ }
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
+ basic_filebuf<_CharT, _Traits>::
+ close()
+ {
+ __filebuf_type *__ret = NULL;
+ if (this->is_open())
+ {
+ 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)
+ 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 0
+ // XXX not done
+ if (_M_last_overflowed)
+ {
+ _M_output_unshift();
+ _M_really_overflow(__eof);
+ }
+#endif
+
+ if (_M_file.close())
+ __ret = this;
+ }
+
+ _M_last_overflowed = false;
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ streamsize
+ basic_filebuf<_CharT, _Traits>::
+ showmanyc()
+ {
+ streamsize __ret = -1;
+ 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>::
+ _M_underflow_common(bool __bump)
+ {
+ 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();
+ else if (_M_in_cur != _M_filepos)
+ _M_file.seekoff(_M_in_cur - _M_filepos,
+ 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 (__bump)
+ _M_in_cur_move(1);
+ else if (_M_buf_size == 1)
+ {
+ // If we are synced with stdio, we have to unget the
+ // character we just read so that the file pointer
+ // doesn't move.
+ _M_file.sys_ungetc(*_M_in_cur);
+ _M_set_indeterminate();
+ }
+ }
+ }
+ }
+ _M_last_overflowed = false;
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_filebuf<_CharT, _Traits>::int_type
+ basic_filebuf<_CharT, _Traits>::
+ pbackfail(int_type __i)
+ {
+ int_type __ret = traits_type::eof();
+ bool __testin = _M_mode & ios_base::in;
+
+ if (__testin)
+ {
+ bool __testpb = _M_in_beg < _M_in_cur;
+ char_type __c = traits_type::to_char_type(__i);
+ bool __testeof = traits_type::eq_int_type(__i, __ret);
+
+ if (__testpb)
+ {
+ bool __testout = _M_mode & ios_base::out;
+ bool __testeq = traits_type::eq(__c, this->gptr()[-1]);
+
+ // Try to put back __c into input sequence in one of three ways.
+ // Order these tests done in is unspecified by the standard.
+ if (!__testeof && __testeq)
+ {
+ --_M_in_cur;
+ if (__testout)
+ --_M_out_cur;
+ __ret = __i;
+ }
+ else if (__testeof)
+ {
+ --_M_in_cur;
+ if (__testout)
+ --_M_out_cur;
+ __ret = traits_type::not_eof(__i);
+ }
+ else if (!__testeof)
+ {
+ --_M_in_cur;
+ if (__testout)
+ --_M_out_cur;
+ _M_pback_create();
+ *_M_in_cur = __c;
+ __ret = __i;
+ }
+ }
+ else
+ {
+ // At the beginning of the buffer, need to make a
+ // putback position available.
+ this->seekoff(-1, ios_base::cur);
+ this->underflow();
+ if (!__testeof)
+ {
+ if (!traits_type::eq(__c, *_M_in_cur))
+ {
+ _M_pback_create();
+ *_M_in_cur = __c;
+ }
+ __ret = __i;
+ }
+ else
+ __ret = traits_type::not_eof(__i);
+ }
+ }
+ _M_last_overflowed = false;
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_filebuf<_CharT, _Traits>::int_type
+ basic_filebuf<_CharT, _Traits>::
+ overflow(int_type __c)
+ {
+ int_type __ret = traits_type::eof();
+ bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size;
+ bool __testout = _M_mode & ios_base::out;
+
+ if (__testout)
+ {
+ if (__testput)
+ {
+ *_M_out_cur = traits_type::to_char_type(__c);
+ _M_out_cur_move(1);
+ __ret = traits_type::not_eof(__c);
+ }
+ else
+ __ret = this->_M_really_overflow(__c);
+ }
+
+ _M_last_overflowed = false; // Set in _M_really_overflow, below.
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ void
+ basic_filebuf<_CharT, _Traits>::
+ _M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
+ streamsize& __elen, streamsize& __plen)
+ {
+ const locale __loc = this->getloc();
+ const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
+
+ if (__cvt.always_noconv() && __ilen)
+ {
+ __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
+ __plen += __ilen;
+ }
+ else
+ {
+ // Worst-case number of external bytes needed.
+ int __ext_multiplier = __cvt.encoding();
+ if (__ext_multiplier == -1 || __ext_multiplier == 0)
+ __ext_multiplier = sizeof(char_type);
+ streamsize __blen = __ilen * __ext_multiplier;
+ char* __buf = static_cast<char*>(__builtin_alloca(__blen));
+ char* __bend;
+ const char_type* __iend;
+ __res_type __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
+ __iend, __buf, __buf + __blen, __bend);
+ // Result == ok, partial, noconv
+ if (__r != codecvt_base::error)
+ __blen = __bend - __buf;
+ // Result == error
+ else
+ __blen = 0;
+
+ if (__blen)
+ {
+ __elen += _M_file.xsputn(__buf, __blen);
+ __plen += __blen;
+ }
+
+ // Try once more for partial conversions.
+ if (__r == codecvt_base::partial)
+ {
+ const char_type* __iresume = __iend;
+ streamsize __rlen = _M_out_end - __iend;
+ __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,
+ __iend, __buf, __buf + __blen, __bend);
+ if (__r != codecvt_base::error)
+ __rlen = __bend - __buf;
+ else
+ __rlen = 0;
+ if (__rlen)
+ {
+ __elen += _M_file.xsputn(__buf, __rlen);
+ __plen += __rlen;
+ }
+ }
+ }
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_filebuf<_CharT, _Traits>::int_type
+ basic_filebuf<_CharT, _Traits>::
+ _M_really_overflow(int_type __c)
+ {
+ int_type __ret = traits_type::eof();
+ bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
+ bool __testunbuffered = _M_file.is_open() && !_M_buf_size;
+
+ if (__testput || __testunbuffered)
+ {
+ // Sizes of external and pending output.
+ 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)
+ _M_convert_to_external(_M_out_beg, _M_out_end - _M_out_beg,
+ __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);
+
+ // 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);
+ }
+ }
+ _M_last_overflowed = true;
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
+ basic_filebuf<_CharT, _Traits>::
+ setbuf(char_type* __s, streamsize __n)
+ {
+ if (!this->is_open() && __s == 0 && __n == 0)
+ _M_buf_size_opt = 0;
+ else if (__s && __n)
+ {
+ // This is implementation-defined behavior, and assumes
+ // that an external char_type array of length (__s + __n)
+ // exists and has been pre-allocated. If this is not the
+ // case, things will quickly blow up.
+ // Step 1: Destroy the current internal array.
+ _M_destroy_internal_buffer();
+
+ // Step 2: Use the external array.
+ _M_buf = __s;
+ _M_buf_size_opt = _M_buf_size = __n;
+ _M_set_indeterminate();
+ }
+ _M_last_overflowed = false;
+ return this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_filebuf<_CharT, _Traits>::pos_type
+ basic_filebuf<_CharT, _Traits>::
+ seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
+ {
+ pos_type __ret = pos_type(off_type(-1));
+ 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;
+
+ if (this->is_open() && !__testfail && (__testin || __testout))
+ {
+ // Ditch any pback buffers to avoid confusion.
+ _M_pback_destroy();
+
+ if (__way != ios_base::cur || __off != 0)
+ {
+ off_type __computed_off = __width * __off;
+
+ bool __testget = _M_in_cur && _M_in_beg < _M_in_end;
+ bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
+ // Sync the internal and external streams.
+ // out
+ if (__testput || _M_last_overflowed)
+ {
+ // Part one: update the output sequence.
+ this->sync();
+ // Part two: output unshift sequence.
+ _M_output_unshift();
+ }
+ //in
+ else if (__testget && __way == ios_base::cur)
+ __computed_off += _M_in_cur - _M_filepos;
+
+ __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
+ else
+ {
+ __ret = _M_file.seekoff(__off, ios_base::cur, __mode);
+ __ret += max(_M_out_cur, _M_in_cur) - _M_filepos;
+ }
+ }
+ _M_last_overflowed = false;
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_filebuf<_CharT, _Traits>::pos_type
+ basic_filebuf<_CharT, _Traits>::
+ seekpos(pos_type __pos, ios_base::openmode __mode)
+ {
+#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>
+ void
+ basic_filebuf<_CharT, _Traits>::
+ _M_output_unshift()
+ { }
+
+ template<typename _CharT, typename _Traits>
+ void
+ basic_filebuf<_CharT, _Traits>::
+ imbue(const locale& __loc)
+ {
+ bool __testbeg = gptr() == eback() && pptr() == pbase();
+
+ if (__testbeg && _M_buf_locale != __loc)
+ {
+ _M_buf_locale = __loc;
+ _M_buf_locale_init = true;
+ }
+
+ // NB this may require the reconversion of previously
+ // converted chars. This in turn may cause the reconstruction
+ // of the original file. YIKES!!
+ // XXX The part in the above comment is not done.
+ _M_last_overflowed = false;
+ }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // 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>;
+ extern template class basic_fstream<wchar_t>;
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/functexcept.h b/contrib/libstdc++/include/bits/functexcept.h
new file mode 100644
index 0000000000000..eac2c95b4327a
--- /dev/null
+++ b/contrib/libstdc++/include/bits/functexcept.h
@@ -0,0 +1,85 @@
+// Function-Based Exception Support -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 19.1 Exception classes
+//
+
+#include <exception_defines.h>
+
+namespace std
+{
+ // Helper for exception objects in <except>
+ void
+ __throw_bad_exception(void);
+
+ // Helper for exception objects in <new>
+ void
+ __throw_bad_alloc(void);
+
+ // Helper for exception objects in <typeinfo>
+ void
+ __throw_bad_cast(void);
+
+ void
+ __throw_bad_typeid(void);
+
+ // Helpers for exception objects in <stdexcept>
+ void
+ __throw_logic_error(const char* __s);
+
+ void
+ __throw_domain_error(const char* __s);
+
+ void
+ __throw_invalid_argument(const char* __s);
+
+ void
+ __throw_length_error(const char* __s);
+
+ void
+ __throw_out_of_range(const char* __s);
+
+ void
+ __throw_runtime_error(const char* __s);
+
+ void
+ __throw_range_error(const char* __s);
+
+ void
+ __throw_overflow_error(const char* __s);
+
+ void
+ __throw_underflow_error(const char* __s);
+
+ // Helpers for exception objects in basic_ios
+ void
+ __throw_ios_failure(const char* __s);
+} // namespace std
+
diff --git a/contrib/libstdc++/include/bits/generic_shadow.h b/contrib/libstdc++/include/bits/generic_shadow.h
new file mode 100644
index 0000000000000..b87e71702e86b
--- /dev/null
+++ b/contrib/libstdc++/include/bits/generic_shadow.h
@@ -0,0 +1,59 @@
+// generic C header shadow file -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This file is included by all the standard C <foo.h> headers
+// after defining _SHADOW_NAME.
+
+#ifdef _IN_C_LEGACY_ /* sub-included by a C header */
+
+ // Get out of the "swamp."
+ } // Close extern "C"
+ } // Close namespace _C_legacy::
+
+# undef _IN_C_LEGACY_
+# include _SHADOW_NAME
+
+ // Dive back into the "swamp."
+ namespace _C_legacy {
+ extern "C" {
+# define _IN_C_LEGACY_
+
+#else /* not _IN_C_LEGACY_: directly included by user program */
+
+# include _SHADOW_NAME
+
+ // Expose global C names, including non-standard ones, but shadow
+ // some names and types with the std:: C++ version.
+
+ using namespace ::_C_legacy::_C_shadow;
+
+#endif /* _IN_C_LEGACY_ */
+
+
+
diff --git a/contrib/libstdc++/include/bits/gslice.h b/contrib/libstdc++/include/bits/gslice.h
new file mode 100644
index 0000000000000..95781f9bbcc24
--- /dev/null
+++ b/contrib/libstdc++/include/bits/gslice.h
@@ -0,0 +1,124 @@
+// The template and inlines for the -*- C++ -*- gslice class.
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+/** @file gslice.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_GSLICE_H
+#define _CPP_BITS_GSLICE_H 1
+
+#pragma GCC system_header
+
+namespace std {
+
+ class gslice
+ {
+ public:
+ gslice ();
+ gslice (size_t, const valarray<size_t>&, const valarray<size_t>&);
+ // XXX: the IS says the copy-ctor and copy-assignment operators are
+ // synthetized by the compiler but they are just unsuitable
+ // for a ref-counted semantic
+ gslice(const gslice&);
+ ~gslice();
+
+ // XXX: See the note above.
+ gslice& operator= (const gslice&);
+
+ size_t start () const;
+ valarray<size_t> size () const;
+ valarray<size_t> stride () const;
+
+ private:
+ struct _Indexer {
+ size_t _M_count;
+ size_t _M_start;
+ valarray<size_t> _M_size;
+ valarray<size_t> _M_stride;
+ valarray<size_t> _M_index;
+ _Indexer(size_t, const valarray<size_t>&,
+ const valarray<size_t>&);
+ void _M_increment_use() { ++_M_count; }
+ size_t _M_decrement_use() { return --_M_count; }
+ };
+
+ _Indexer* _M_index;
+
+ template<typename _Tp> friend class valarray;
+ };
+
+ inline size_t
+ gslice::start () const
+ { return _M_index ? _M_index->_M_start : 0; }
+
+ inline valarray<size_t>
+ gslice::size () const
+ { return _M_index ? _M_index->_M_size : valarray<size_t>(); }
+
+ inline valarray<size_t>
+ gslice::stride () const
+ { return _M_index ? _M_index->_M_stride : valarray<size_t>(); }
+
+ inline gslice::gslice () : _M_index(0) {}
+
+ inline
+ gslice::gslice(size_t __o, const valarray<size_t>& __l,
+ const valarray<size_t>& __s)
+ : _M_index(new gslice::_Indexer(__o, __l, __s)) {}
+
+ inline
+ gslice::gslice(const gslice& __g) : _M_index(__g._M_index)
+ { if (_M_index) _M_index->_M_increment_use(); }
+
+ inline
+ gslice::~gslice()
+ { if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; }
+
+ inline gslice&
+ gslice::operator= (const gslice& __g)
+ {
+ if (__g._M_index) __g._M_index->_M_increment_use();
+ if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index;
+ _M_index = __g._M_index;
+ return *this;
+ }
+
+
+} // std::
+
+
+#endif /* _CPP_BITS_GSLICE_H */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/gslice_array.h b/contrib/libstdc++/include/bits/gslice_array.h
new file mode 100644
index 0000000000000..8989ac5200efb
--- /dev/null
+++ b/contrib/libstdc++/include/bits/gslice_array.h
@@ -0,0 +1,176 @@
+// The template and inlines for the -*- C++ -*- gslice_array class.
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+/** @file gslice_array.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_GSLICE_ARRAY
+#define _CPP_BITS_GSLICE_ARRAY 1
+
+#pragma GCC system_header
+
+namespace std {
+
+ template<typename _Tp> class gslice_array
+ {
+ public:
+ typedef _Tp value_type;
+
+ void operator= (const valarray<_Tp>&) const;
+ void operator*= (const valarray<_Tp>&) const;
+ void operator/= (const valarray<_Tp>&) const;
+ void operator%= (const valarray<_Tp>&) const;
+ void operator+= (const valarray<_Tp>&) const;
+ void operator-= (const valarray<_Tp>&) const;
+ void operator^= (const valarray<_Tp>&) const;
+ void operator&= (const valarray<_Tp>&) const;
+ void operator|= (const valarray<_Tp>&) const;
+ void operator<<=(const valarray<_Tp>&) const;
+ void operator>>=(const valarray<_Tp>&) const;
+ void operator=(const _Tp&);
+
+ template<class _Dom>
+ void operator= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator*= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator/= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator%= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator+= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator-= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator^= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator&= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator|= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator<<= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator>>= (const _Expr<_Dom,_Tp>&) const;
+
+ private:
+ _Array<_Tp> _M_array;
+ const valarray<size_t>& _M_index;
+
+ friend class valarray<_Tp>;
+
+ gslice_array (_Array<_Tp>, const valarray<size_t>&);
+
+ // this constructor needs to be implemented.
+ gslice_array (const gslice_array&);
+
+ // not implemented
+ gslice_array();
+ gslice_array& operator= (const gslice_array&);
+ };
+
+ template<typename _Tp>
+ inline
+ gslice_array<_Tp>::gslice_array (_Array<_Tp> __a,
+ const valarray<size_t>& __i)
+ : _M_array (__a), _M_index (__i) {}
+
+
+ template<typename _Tp>
+ inline
+ gslice_array<_Tp>::gslice_array (const gslice_array<_Tp>& __a)
+ : _M_array (__a._M_array), _M_index (__a._M_index) {}
+
+
+ template<typename _Tp>
+ inline void
+ gslice_array<_Tp>::operator= (const _Tp& __t)
+ {
+ __valarray_fill (_M_array, _Array<size_t>(_M_index),
+ _M_index.size(), __t);
+ }
+
+ template<typename _Tp>
+ inline void
+ gslice_array<_Tp>::operator= (const valarray<_Tp>& __v) const
+ {
+ __valarray_copy (_Array<_Tp> (__v), __v.size (),
+ _M_array, _Array<size_t>(_M_index));
+ }
+
+ template<typename _Tp>
+ template<class E>
+ inline void
+ gslice_array<_Tp>::operator= (const _Expr<E, _Tp>& __e) const
+ {
+ __valarray_copy (__e, _M_index.size(), _M_array,
+ _Array<size_t>(_M_index));
+ }
+
+#undef _DEFINE_VALARRAY_OPERATOR
+#define _DEFINE_VALARRAY_OPERATOR(op, name) \
+template<typename _Tp> \
+inline void \
+gslice_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \
+{ \
+ _Array_augmented_##name (_M_array, _Array<size_t>(_M_index), \
+ _Array<_Tp> (__v), __v.size ()); \
+} \
+ \
+template<typename _Tp> template<class E> \
+inline void \
+gslice_array<_Tp>::operator op##= (const _Expr<E, _Tp>& __e) const \
+{ \
+ _Array_augmented_##name (_M_array, _Array<size_t>(_M_index), __e, \
+ _M_index.size()); \
+}
+
+_DEFINE_VALARRAY_OPERATOR(*, multiplies)
+_DEFINE_VALARRAY_OPERATOR(/, divides)
+_DEFINE_VALARRAY_OPERATOR(%, modulus)
+_DEFINE_VALARRAY_OPERATOR(+, plus)
+_DEFINE_VALARRAY_OPERATOR(-, minus)
+_DEFINE_VALARRAY_OPERATOR(^, xor)
+_DEFINE_VALARRAY_OPERATOR(&, and)
+_DEFINE_VALARRAY_OPERATOR(|, or)
+_DEFINE_VALARRAY_OPERATOR(<<, shift_left)
+_DEFINE_VALARRAY_OPERATOR(>>, shift_right)
+
+#undef _DEFINE_VALARRAY_OPERATOR
+
+} // std::
+
+#endif /* _CPP_BITS_GSLICE_ARRAY */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/indirect_array.h b/contrib/libstdc++/include/bits/indirect_array.h
new file mode 100644
index 0000000000000..a5737e9eb04d8
--- /dev/null
+++ b/contrib/libstdc++/include/bits/indirect_array.h
@@ -0,0 +1,176 @@
+// The template and inlines for the -*- C++ -*- indirect_array class.
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+/** @file indirect_array.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_INDIRECT_ARRAY_H
+#define _CPP_BITS_INDIRECT_ARRAY_H 1
+
+#pragma GCC system_header
+
+namespace std
+{
+ template <class _Tp>
+ class indirect_array
+ {
+ public:
+ typedef _Tp value_type;
+
+ // XXX: This is a proposed resolution for DR-253.
+ indirect_array& operator= (const indirect_array&);
+
+ void operator= (const valarray<_Tp>&) const;
+ void operator*= (const valarray<_Tp>&) const;
+ void operator/= (const valarray<_Tp>&) const;
+ void operator%= (const valarray<_Tp>&) const;
+ void operator+= (const valarray<_Tp>&) const;
+ void operator-= (const valarray<_Tp>&) const;
+ void operator^= (const valarray<_Tp>&) const;
+ void operator&= (const valarray<_Tp>&) const;
+ void operator|= (const valarray<_Tp>&) const;
+ void operator<<= (const valarray<_Tp>&) const;
+ void operator>>= (const valarray<_Tp>&) const;
+ void operator= (const _Tp&);
+ // ~indirect_array();
+
+ template<class _Dom>
+ void operator= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator*= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator/= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator%= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator+= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator-= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator^= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator&= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator|= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator<<= (const _Expr<_Dom, _Tp>&) const;
+ template<class _Dom>
+ void operator>>= (const _Expr<_Dom, _Tp>&) const;
+
+ private:
+ indirect_array (const indirect_array&);
+ indirect_array (_Array<_Tp>, size_t, _Array<size_t>);
+
+ friend class valarray<_Tp>;
+ friend class gslice_array<_Tp>;
+
+ const size_t _M_sz;
+ const _Array<size_t> _M_index;
+ const _Array<_Tp> _M_array;
+
+ // not implemented
+ indirect_array ();
+ };
+
+ template<typename _Tp>
+ inline indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a)
+ : _M_sz (__a._M_sz), _M_index (__a._M_index),
+ _M_array (__a._M_array) {}
+
+ template<typename _Tp>
+ inline
+ indirect_array<_Tp>::indirect_array (_Array<_Tp> __a, size_t __s,
+ _Array<size_t> __i)
+ : _M_sz (__s), _M_index (__i), _M_array (__a) {}
+
+ template<typename _Tp>
+ inline indirect_array<_Tp>&
+ indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a)
+ {
+ __valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array, _M_index);
+ return *this;
+ }
+
+
+ template<typename _Tp>
+ inline void
+ indirect_array<_Tp>::operator= (const _Tp& __t)
+ { __valarray_fill(_M_array, _M_index, _M_sz, __t); }
+
+ template<typename _Tp>
+ inline void
+ indirect_array<_Tp>::operator= (const valarray<_Tp>& __v) const
+ { __valarray_copy (_Array<_Tp> (__v), _M_sz, _M_array, _M_index); }
+
+ template<typename _Tp>
+ template<class _Dom>
+ inline void
+ indirect_array<_Tp>::operator= (const _Expr<_Dom,_Tp>& __e) const
+ { __valarray_copy (__e, _M_sz, _M_array, _M_index); }
+
+#undef _DEFINE_VALARRAY_OPERATOR
+#define _DEFINE_VALARRAY_OPERATOR(op, name) \
+template<typename _Tp> \
+inline void \
+indirect_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \
+{ \
+ _Array_augmented_##name (_M_array, _M_index, _Array<_Tp> (__v), _M_sz); \
+} \
+ \
+template<typename _Tp> template<class _Dom> \
+inline void \
+indirect_array<_Tp>::operator op##= (const _Expr<_Dom,_Tp>& __e) const \
+{ \
+ _Array_augmented_##name (_M_array, _M_index, __e, _M_sz); \
+}
+
+_DEFINE_VALARRAY_OPERATOR(*, multiplies)
+_DEFINE_VALARRAY_OPERATOR(/, divides)
+_DEFINE_VALARRAY_OPERATOR(%, modulus)
+_DEFINE_VALARRAY_OPERATOR(+, plus)
+_DEFINE_VALARRAY_OPERATOR(-, minus)
+_DEFINE_VALARRAY_OPERATOR(^, xor)
+_DEFINE_VALARRAY_OPERATOR(&, and)
+_DEFINE_VALARRAY_OPERATOR(|, or)
+_DEFINE_VALARRAY_OPERATOR(<<, shift_left)
+_DEFINE_VALARRAY_OPERATOR(>>, shift_right)
+
+#undef _DEFINE_VALARRAY_OPERATOR
+
+} // std::
+
+#endif /* _CPP_BITS_INDIRECT_ARRAY_H */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/ios_base.h b/contrib/libstdc++/include/bits/ios_base.h
new file mode 100644
index 0000000000000..f5b026900f606
--- /dev/null
+++ b/contrib/libstdc++/include/bits/ios_base.h
@@ -0,0 +1,589 @@
+// Iostreams base classes -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.8 File-based streams
+//
+
+/** @file ios_base.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_IOSBASE_H
+#define _CPP_BITS_IOSBASE_H 1
+
+#pragma GCC system_header
+
+#include <bits/atomicity.h>
+
+namespace std
+{
+ // The following definitions of bitmask types are enums, not ints,
+ // as permitted (but not required) in the standard, in order to provide
+ // better type safety in iostream calls. A side effect is that
+ // expressions involving them are no longer compile-time constants.
+ enum _Ios_Fmtflags { _M_ios_fmtflags_end = 1L << 16 };
+
+ inline _Ios_Fmtflags
+ operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
+ { return _Ios_Fmtflags(static_cast<int>(__a) & static_cast<int>(__b)); }
+
+ inline _Ios_Fmtflags
+ operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
+ { return _Ios_Fmtflags(static_cast<int>(__a) | static_cast<int>(__b)); }
+
+ inline _Ios_Fmtflags
+ operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
+ { return _Ios_Fmtflags(static_cast<int>(__a) ^ static_cast<int>(__b)); }
+
+ inline _Ios_Fmtflags
+ operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b)
+ { return __a = __a | __b; }
+
+ inline _Ios_Fmtflags
+ operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b)
+ { return __a = __a & __b; }
+
+ inline _Ios_Fmtflags
+ operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b)
+ { return __a = __a ^ __b; }
+
+ inline _Ios_Fmtflags
+ operator~(_Ios_Fmtflags __a)
+ { return _Ios_Fmtflags(~static_cast<int>(__a)); }
+
+
+ enum _Ios_Openmode { _M_ios_openmode_end = 1L << 16 };
+
+ inline _Ios_Openmode
+ operator&(_Ios_Openmode __a, _Ios_Openmode __b)
+ { return _Ios_Openmode(static_cast<int>(__a) & static_cast<int>(__b)); }
+
+ inline _Ios_Openmode
+ operator|(_Ios_Openmode __a, _Ios_Openmode __b)
+ { return _Ios_Openmode(static_cast<int>(__a) | static_cast<int>(__b)); }
+
+ inline _Ios_Openmode
+ operator^(_Ios_Openmode __a, _Ios_Openmode __b)
+ { return _Ios_Openmode(static_cast<int>(__a) ^ static_cast<int>(__b)); }
+
+ inline _Ios_Openmode
+ operator|=(_Ios_Openmode& __a, _Ios_Openmode __b)
+ { return __a = __a | __b; }
+
+ inline _Ios_Openmode
+ operator&=(_Ios_Openmode& __a, _Ios_Openmode __b)
+ { return __a = __a & __b; }
+
+ inline _Ios_Openmode
+ operator^=(_Ios_Openmode& __a, _Ios_Openmode __b)
+ { return __a = __a ^ __b; }
+
+ inline _Ios_Openmode
+ operator~(_Ios_Openmode __a)
+ { return _Ios_Openmode(~static_cast<int>(__a)); }
+
+
+ enum _Ios_Iostate { _M_ios_iostate_end = 1L << 16 };
+
+ inline _Ios_Iostate
+ operator&(_Ios_Iostate __a, _Ios_Iostate __b)
+ { return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); }
+
+ inline _Ios_Iostate
+ operator|(_Ios_Iostate __a, _Ios_Iostate __b)
+ { return _Ios_Iostate(static_cast<int>(__a) | static_cast<int>(__b)); }
+
+ inline _Ios_Iostate
+ operator^(_Ios_Iostate __a, _Ios_Iostate __b)
+ { return _Ios_Iostate(static_cast<int>(__a) ^ static_cast<int>(__b)); }
+
+ inline _Ios_Iostate
+ operator|=(_Ios_Iostate& __a, _Ios_Iostate __b)
+ { return __a = __a | __b; }
+
+ inline _Ios_Iostate
+ operator&=(_Ios_Iostate& __a, _Ios_Iostate __b)
+ { return __a = __a & __b; }
+
+ inline _Ios_Iostate
+ operator^=(_Ios_Iostate& __a, _Ios_Iostate __b)
+ { return __a = __a ^ __b; }
+
+ inline _Ios_Iostate
+ operator~(_Ios_Iostate __a)
+ { return _Ios_Iostate(~static_cast<int>(__a)); }
+
+ enum _Ios_Seekdir { _M_ios_seekdir_end = 1L << 16 };
+
+ // 27.4.2 Class ios_base
+ class ios_base
+ {
+ public:
+
+ // 27.4.2.1.1 Class ios_base::failure
+ class failure : public exception
+ {
+ public:
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ //48. Use of non-existent exception constructor
+ 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();
+
+ virtual const char*
+ what() const throw();
+
+ private:
+ enum { _M_bufsize = 256 };
+ char _M_name[_M_bufsize];
+#endif
+ };
+
+ // 27.4.2.1.2 Type ios_base::fmtflags
+ typedef _Ios_Fmtflags fmtflags;
+ // 27.4.2.1.2 Type fmtflags
+ static const fmtflags boolalpha = fmtflags(__ios_flags::_S_boolalpha);
+ static const fmtflags dec = fmtflags(__ios_flags::_S_dec);
+ static const fmtflags fixed = fmtflags(__ios_flags::_S_fixed);
+ static const fmtflags hex = fmtflags(__ios_flags::_S_hex);
+ static const fmtflags internal = fmtflags(__ios_flags::_S_internal);
+ static const fmtflags left = fmtflags(__ios_flags::_S_left);
+ static const fmtflags oct = fmtflags(__ios_flags::_S_oct);
+ static const fmtflags right = fmtflags(__ios_flags::_S_right);
+ static const fmtflags scientific = fmtflags(__ios_flags::_S_scientific);
+ static const fmtflags showbase = fmtflags(__ios_flags::_S_showbase);
+ static const fmtflags showpoint = fmtflags(__ios_flags::_S_showpoint);
+ static const fmtflags showpos = fmtflags(__ios_flags::_S_showpos);
+ static const fmtflags skipws = fmtflags(__ios_flags::_S_skipws);
+ static const fmtflags unitbuf = fmtflags(__ios_flags::_S_unitbuf);
+ static const fmtflags uppercase = fmtflags(__ios_flags::_S_uppercase);
+ static const fmtflags adjustfield = fmtflags(__ios_flags::_S_adjustfield);
+ static const fmtflags basefield = fmtflags(__ios_flags::_S_basefield);
+ static const fmtflags floatfield = fmtflags(__ios_flags::_S_floatfield);
+
+ // 27.4.2.1.3 Type ios_base::iostate
+ typedef _Ios_Iostate iostate;
+ static const iostate badbit = iostate(__ios_flags::_S_badbit);
+ static const iostate eofbit = iostate(__ios_flags::_S_eofbit);
+ static const iostate failbit = iostate(__ios_flags::_S_failbit);
+ static const iostate goodbit = iostate(0);
+
+ // 27.4.2.1.4 Type openmode
+ typedef _Ios_Openmode openmode;
+ static const openmode app = openmode(__ios_flags::_S_app);
+ static const openmode ate = openmode(__ios_flags::_S_ate);
+ static const openmode binary = openmode(__ios_flags::_S_bin);
+ static const openmode in = openmode(__ios_flags::_S_in);
+ static const openmode out = openmode(__ios_flags::_S_out);
+ static const openmode trunc = openmode(__ios_flags::_S_trunc);
+
+ // 27.4.2.1.5 Type seekdir
+ typedef _Ios_Seekdir seekdir;
+ static const seekdir beg = seekdir(0);
+ static const seekdir cur = seekdir(SEEK_CUR);
+ static const seekdir end = seekdir(SEEK_END);
+
+#ifdef _GLIBCPP_DEPRECATED
+ typedef int io_state;
+ typedef int open_mode;
+ typedef int seek_dir;
+#endif
+
+ // Callbacks;
+ enum event
+ {
+ erase_event,
+ imbue_event,
+ copyfmt_event
+ };
+
+ typedef void (*event_callback) (event, ios_base&, int);
+
+ void
+ register_callback(event_callback __fn, int __index);
+
+ protected:
+ // Data Members
+ 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
+ struct _Callback_list
+ {
+ // Data Members
+ _Callback_list* _M_next;
+ ios_base::event_callback _M_fn;
+ int _M_index;
+ _Atomic_word _M_refcount; // 0 means one reference.
+
+ _Callback_list(ios_base::event_callback __fn, int __index,
+ _Callback_list* __cb)
+ : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { }
+
+ void
+ _M_add_reference() { __atomic_add(&_M_refcount, 1); }
+
+ // 0 => OK to delete.
+ int
+ _M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); }
+ };
+
+ _Callback_list* _M_callbacks;
+
+ void
+ _M_call_callbacks(event __ev) throw();
+
+ void
+ _M_dispose_callbacks(void);
+
+ // 27.4.2.5 Members for iword/pword storage
+ struct _Words
+ {
+ void* _M_pword;
+ long _M_iword;
+ _Words() : _M_pword(0), _M_iword(0) { }
+ };
+
+ // 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);
+
+ // Members for locale and locale caching.
+ locale _M_ios_locale;
+
+ void
+ _M_init();
+
+ public:
+
+ // 27.4.2.1.6 Class ios_base::Init
+ // Used to initialize standard streams. In theory, g++ could use
+ // -finit-priority to order this stuff correctly without going
+ // through these machinations.
+ class Init
+ {
+ friend class ios_base;
+ public:
+ Init();
+ ~Init();
+
+ static void
+ _S_ios_create(bool __sync);
+
+ static void
+ _S_ios_destroy();
+
+ private:
+ static int _S_ios_base_init;
+ static bool _S_synced_with_stdio;
+ };
+
+ // Fmtflags state:
+ inline fmtflags
+ flags() const { return _M_flags; }
+
+ inline fmtflags
+ flags(fmtflags __fmtfl)
+ {
+ fmtflags __old = _M_flags;
+ _M_flags = __fmtfl;
+ return __old;
+ }
+
+ inline fmtflags
+ setf(fmtflags __fmtfl)
+ {
+ fmtflags __old = _M_flags;
+ _M_flags |= __fmtfl;
+ return __old;
+ }
+
+ inline fmtflags
+ setf(fmtflags __fmtfl, fmtflags __mask)
+ {
+ fmtflags __old = _M_flags;
+ _M_flags &= ~__mask;
+ _M_flags |= (__fmtfl & __mask);
+ return __old;
+ }
+
+ inline void
+ unsetf(fmtflags __mask) { _M_flags &= ~__mask; }
+
+ inline streamsize
+ precision() const { return _M_precision; }
+
+ inline streamsize
+ precision(streamsize __prec)
+ {
+ streamsize __old = _M_precision;
+ _M_precision = __prec;
+ return __old;
+ }
+
+ inline streamsize
+ width() const { return _M_width; }
+
+ inline streamsize
+ width(streamsize __wide)
+ {
+ streamsize __old = _M_width;
+ _M_width = __wide;
+ return __old;
+ }
+
+ static bool
+ sync_with_stdio(bool __sync = true);
+
+ // Locales:
+ locale
+ imbue(const locale& __loc);
+
+ inline locale
+ getloc() const { return _M_ios_locale; }
+
+ // Storage:
+ static int
+ xalloc() throw();
+
+ inline long&
+ iword(int __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_size)
+ ? _M_word[__ix] : _M_grow_words(__ix);
+ return __word._M_pword;
+ }
+
+ // Destructor
+ ~ios_base();
+
+ protected:
+ ios_base();
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ //50. Copy constructor and assignment operator of ios_base
+ private:
+ ios_base(const ios_base&);
+
+ ios_base&
+ operator=(const ios_base&);
+#endif
+ };
+
+ // 27.4.5.1 fmtflags manipulators:
+ inline ios_base&
+ boolalpha(ios_base& __base)
+ {
+ __base.setf(ios_base::boolalpha);
+ return __base;
+ }
+
+ inline ios_base&
+ noboolalpha(ios_base& __base)
+ {
+ __base.unsetf(ios_base::boolalpha);
+ return __base;
+ }
+
+ inline ios_base&
+ showbase(ios_base& __base)
+ {
+ __base.setf(ios_base::showbase);
+ return __base;
+ }
+
+ inline ios_base&
+ noshowbase(ios_base& __base)
+ {
+ __base.unsetf(ios_base::showbase);
+ return __base;
+ }
+
+ inline ios_base&
+ showpoint(ios_base& __base)
+ {
+ __base.setf(ios_base::showpoint);
+ return __base;
+ }
+
+ inline ios_base&
+ noshowpoint(ios_base& __base)
+ {
+ __base.unsetf(ios_base::showpoint);
+ return __base;
+ }
+
+ inline ios_base&
+ showpos(ios_base& __base)
+ {
+ __base.setf(ios_base::showpos);
+ return __base;
+ }
+
+ inline ios_base&
+ noshowpos(ios_base& __base)
+ {
+ __base.unsetf(ios_base::showpos);
+ return __base;
+ }
+
+ inline ios_base&
+ skipws(ios_base& __base)
+ {
+ __base.setf(ios_base::skipws);
+ return __base;
+ }
+
+ inline ios_base&
+ noskipws(ios_base& __base)
+ {
+ __base.unsetf(ios_base::skipws);
+ return __base;
+ }
+
+ inline ios_base&
+ uppercase(ios_base& __base)
+ {
+ __base.setf(ios_base::uppercase);
+ return __base;
+ }
+
+ inline ios_base&
+ nouppercase(ios_base& __base)
+ {
+ __base.unsetf(ios_base::uppercase);
+ return __base;
+ }
+
+ inline ios_base&
+ unitbuf(ios_base& __base)
+ {
+ __base.setf(ios_base::unitbuf);
+ return __base;
+ }
+
+ inline ios_base&
+ nounitbuf(ios_base& __base)
+ {
+ __base.unsetf(ios_base::unitbuf);
+ return __base;
+ }
+
+ // 27.4.5.2 adjustfield anipulators:
+ inline ios_base&
+ internal(ios_base& __base)
+ {
+ __base.setf(ios_base::internal, ios_base::adjustfield);
+ return __base;
+ }
+
+ inline ios_base&
+ left(ios_base& __base)
+ {
+ __base.setf(ios_base::left, ios_base::adjustfield);
+ return __base;
+ }
+
+ inline ios_base&
+ right(ios_base& __base)
+ {
+ __base.setf(ios_base::right, ios_base::adjustfield);
+ return __base;
+ }
+
+ // 27.4.5.3 basefield anipulators:
+ inline ios_base&
+ dec(ios_base& __base)
+ {
+ __base.setf(ios_base::dec, ios_base::basefield);
+ return __base;
+ }
+
+ inline ios_base&
+ hex(ios_base& __base)
+ {
+ __base.setf(ios_base::hex, ios_base::basefield);
+ return __base;
+ }
+
+ inline ios_base&
+ oct(ios_base& __base)
+ {
+ __base.setf(ios_base::oct, ios_base::basefield);
+ return __base;
+ }
+
+ // 27.4.5.4 floatfield anipulators:
+ inline ios_base&
+ fixed(ios_base& __base)
+ {
+ __base.setf(ios_base::fixed, ios_base::floatfield);
+ return __base;
+ }
+
+ inline ios_base&
+ scientific(ios_base& __base)
+ {
+ __base.setf(ios_base::scientific, ios_base::floatfield);
+ return __base;
+ }
+
+} // namespace std
+
+#endif /* _CPP_BITS_IOSBASE_H */
+
diff --git a/contrib/libstdc++/include/bits/istream.tcc b/contrib/libstdc++/include/bits/istream.tcc
new file mode 100644
index 0000000000000..636a73863598d
--- /dev/null
+++ b/contrib/libstdc++/include/bits/istream.tcc
@@ -0,0 +1,1228 @@
+// istream classes -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.6.2 Output streams
+//
+
+#pragma GCC system_header
+
+#include <locale>
+#include <ostream> // For flush()
+
+namespace std
+{
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>::sentry::
+ sentry(basic_istream<_CharT, _Traits>& __in, bool __noskipws)
+ {
+ if (__in.good())
+ {
+ if (__in.tie())
+ __in.tie()->flush();
+ if (!__noskipws && (__in.flags() & ios_base::skipws))
+ {
+ const __int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = __in.rdbuf();
+ __int_type __c = __sb->sgetc();
+
+ if (__in._M_check_facet(__in._M_fctype))
+ while (__c != __eof
+ && __in._M_fctype->is(ctype_base::space, __c))
+ __c = __sb->snextc();
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//195. Should basic_istream::sentry's constructor ever set eofbit?
+ if (__c == __eof)
+ __in.setstate(ios_base::eofbit);
+#endif
+ }
+ }
+
+ if (__in.good())
+ _M_ok = true;
+ else
+ {
+ _M_ok = false;
+ __in.setstate(ios_base::failbit);
+ }
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(__istream_type& (*__pf)(__istream_type&))
+ {
+ __pf(*this);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(__ios_type& (*__pf)(__ios_type&))
+ {
+ __pf(*this);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(ios_base& (*__pf)(ios_base&))
+ {
+ __pf(*this);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(bool& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(short& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ long __l;
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __l);
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // 118. basic_istream uses nonexistent num_get member functions.
+ if (!(__err & ios_base::failbit)
+ && (numeric_limits<short>::min() <= __l
+ && __l <= numeric_limits<short>::max()))
+ __n = __l;
+ else
+ __err |= ios_base::failbit;
+#endif
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(unsigned short& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(int& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ long __l;
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __l);
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // 118. basic_istream uses nonexistent num_get member functions.
+ if (!(__err & ios_base::failbit)
+ && (numeric_limits<int>::min() <= __l
+ && __l <= numeric_limits<int>::max()))
+ __n = __l;
+ else
+ __err |= ios_base::failbit;
+#endif
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(unsigned int& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(long& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(unsigned long& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(long long& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(unsigned long long& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+#endif
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(float& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(double& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(long double& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(void*& __n)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ if (_M_check_facet(_M_fnumget))
+ _M_fnumget->get(*this, 0, *this, __err, __n);
+ this->setstate(__err);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ operator>>(__streambuf_type* __sbout)
+ {
+ sentry __cerb(*this, false);
+ if (__cerb)
+ {
+ try
+ {
+ streamsize __xtrct = 0;
+ if (__sbout)
+ {
+ __streambuf_type* __sbin = this->rdbuf();
+ __xtrct = __copy_streambufs(*this, __sbin, __sbout);
+ }
+ if (!__sbout || !__xtrct)
+ this->setstate(ios_base::failbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.2.5.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_istream<_CharT, _Traits>::int_type
+ basic_istream<_CharT, _Traits>::
+ get(void)
+ {
+ const int_type __eof = traits_type::eof();
+ int_type __c = __eof;
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ __c = this->rdbuf()->sbumpc();
+ // 27.6.1.1 paragraph 3
+ if (__c != __eof)
+ _M_gcount = 1;
+ else
+ 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;
+ }
+ }
+ return __c;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ get(char_type& __c)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ int_type __bufval = this->rdbuf()->sbumpc();
+ // 27.6.1.1 paragraph 3
+ if (__bufval != __eof)
+ {
+ _M_gcount = 1;
+ __c = traits_type::to_char_type(__bufval);
+ }
+ else
+ 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;
+ }
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ get(char_type* __s, streamsize __n, char_type __delim)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ 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->sgetc();
+
+ while (_M_gcount + 1 < __n && __c != __eof && __c != __idelim)
+ {
+ *__s++ = traits_type::to_char_type(__c);
+ __c = __sb->snextc();
+ ++_M_gcount;
+ }
+ if (__c == __eof)
+ 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;
+ }
+ }
+ *__s = char_type();
+ if (!_M_gcount)
+ this->setstate(ios_base::failbit);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ get(__streambuf_type& __sb, char_type __delim)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __idelim = traits_type::to_int_type(__delim);
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __this_sb = this->rdbuf();
+ int_type __c = __this_sb->sgetc();
+
+ while (__c != __eof && __c != __idelim
+ && (__sb.sputc(traits_type::to_char_type(__c)) != __eof))
+ {
+ ++_M_gcount;
+ __c = __this_sb->snextc();
+ }
+ if (__c == __eof)
+ 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;
+ }
+ }
+ if (!_M_gcount)
+ this->setstate(ios_base::failbit);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ getline(char_type* __s, streamsize __n, char_type __delim)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ 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->sgetc();
+
+ while (_M_gcount + 1 < __n && __c != __eof && __c != __idelim)
+ {
+ *__s++ = traits_type::to_char_type(__c);
+ __c = __sb->snextc();
+ ++_M_gcount;
+ }
+ if (__c == __eof)
+ this->setstate(ios_base::eofbit);
+ else
+ {
+ if (__c == __idelim)
+ {
+ __sb->snextc();
+ ++_M_gcount;
+ }
+ else
+ this->setstate(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;
+ }
+ }
+ *__s = char_type();
+ if (!_M_gcount)
+ this->setstate(ios_base::failbit);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ ignore(streamsize __n, int_type __delim)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
+
+ __n = min(__n, numeric_limits<streamsize>::max());
+ while (_M_gcount < __n && __c !=__eof && __c != __delim)
+ {
+ __c = __sb->snextc();
+ ++_M_gcount;
+ }
+ if (__c == __eof)
+ this->setstate(ios_base::eofbit);
+ else if (__c == __delim)
+ {
+ __sb->snextc();
+ ++_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;
+ }
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_istream<_CharT, _Traits>::int_type
+ basic_istream<_CharT, _Traits>::
+ peek(void)
+ {
+ int_type __c = traits_type::eof();
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ { __c = this->rdbuf()->sgetc(); }
+ 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 __c;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ read(char_type* __s, streamsize __n)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ _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
+ this->setstate(ios_base::failbit);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ streamsize
+ basic_istream<_CharT, _Traits>::
+ readsome(char_type* __s, streamsize __n)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ streamsize __num = this->rdbuf()->in_avail();
+ if (__num != static_cast<streamsize>(__eof))
+ {
+ __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
+ this->setstate(ios_base::failbit);
+ return _M_gcount;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ putback(char_type __c)
+ {
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ if (!__sb || __sb->sputbackc(__c) == __eof)
+ this->setstate(ios_base::badbit);
+ }
+ 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
+ this->setstate(ios_base::failbit);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ unget(void)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ if (!__sb || __eof == __sb->sungetc())
+ this->setstate(ios_base::badbit);
+ }
+ 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
+ this->setstate(ios_base::failbit);
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ int
+ basic_istream<_CharT, _Traits>::
+ sync(void)
+ {
+ int __ret = traits_type::eof();
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ __streambuf_type* __sb = this->rdbuf();
+ if (!__sb || __ret == __sb->pubsync())
+ this->setstate(ios_base::badbit);
+ else
+ __ret = 0;
+ }
+ 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 __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_istream<_CharT, _Traits>::pos_type
+ basic_istream<_CharT, _Traits>::
+ 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;
+ }
+ }
+ return __ret;
+ }
+
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ seekg(pos_type __pos)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 136. seekp, seekg setting wrong streams?
+ 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);
+#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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ seekg(off_type __off, ios_base::seekdir __dir)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 136. seekp, seekg setting wrong streams?
+ 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);
+#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;
+ }
+
+ // 27.6.1.2.3 Character extraction templates
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
+ {
+ typedef basic_istream<_CharT, _Traits> __istream_type;
+ typename __istream_type::sentry __cerb(__in, false);
+ if (__cerb)
+ {
+ try
+ { __in.get(__c); }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __in.setstate(ios_base::badbit);
+ if ((__in.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
+ }
+ }
+ else
+ __in.setstate(ios_base::failbit);
+ return __in;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
+ {
+ typedef basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::__streambuf_type __streambuf_type;
+ typedef typename _Traits::int_type int_type;
+ typedef _CharT char_type;
+ typedef ctype<_CharT> __ctype_type;
+ streamsize __extracted = 0;
+
+ typename __istream_type::sentry __cerb(__in, false);
+ if (__cerb)
+ {
+ try
+ {
+ // Figure out how many characters to extract.
+ streamsize __num = __in.width();
+ if (__num == 0)
+ __num = numeric_limits<streamsize>::max();
+
+ const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc());
+ const int_type __eof = _Traits::eof();
+ __streambuf_type* __sb = __in.rdbuf();
+ int_type __c = __sb->sgetc();
+
+ while (__extracted < __num - 1
+ && __c != __eof && !__ctype.is(ctype_base::space, __c))
+ {
+ *__s++ = __c;
+ ++__extracted;
+ __c = __sb->snextc();
+ }
+ if (__c == __eof)
+ __in.setstate(ios_base::eofbit);
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//68. Extractors for char* should store null at end
+ *__s = char_type();
+#endif
+ __in.width(0);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __in.setstate(ios_base::badbit);
+ if ((__in.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
+ }
+ }
+ if (!__extracted)
+ __in.setstate(ios_base::failbit);
+ return __in;
+ }
+
+ // 27.6.1.4 Standard basic_istream manipulators
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT,_Traits>&
+ ws(basic_istream<_CharT,_Traits>& __in)
+ {
+ typedef basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::__streambuf_type __streambuf_type;
+ typedef typename __istream_type::__ctype_type __ctype_type;
+ typedef typename __istream_type::int_type __int_type;
+
+ const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc());
+ const __int_type __eof = _Traits::eof();
+ __streambuf_type* __sb = __in.rdbuf();
+ __int_type __c = __sb->sgetc();
+
+ while (__c != __eof && __ctype.is(ctype_base::space, __c))
+ __c = __sb->snextc();
+ if (__c == __eof)
+ __in.setstate(ios_base::eofbit);
+
+ return __in;
+ }
+
+ // 21.3.7.9 basic_string::getline and operators
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>& __in,
+ basic_string<_CharT, _Traits, _Alloc>& __str)
+ {
+ typedef basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::int_type __int_type;
+ typedef typename __istream_type::__streambuf_type __streambuf_type;
+ typedef typename __istream_type::__ctype_type __ctype_type;
+ typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
+ typedef typename __string_type::size_type __size_type;
+ __size_type __extracted = 0;
+
+ typename __istream_type::sentry __cerb(__in, false);
+ if (__cerb)
+ {
+ __str.erase();
+ streamsize __w = __in.width();
+ __size_type __n;
+ __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
+
+ const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc());
+ const __int_type __eof = _Traits::eof();
+ __streambuf_type* __sb = __in.rdbuf();
+ __int_type __c = __sb->sgetc();
+
+ while (__extracted < __n
+ && __c != __eof && !__ctype.is(ctype_base::space, __c))
+ {
+ __str += _Traits::to_char_type(__c);
+ ++__extracted;
+ __c = __sb->snextc();
+ }
+ if (__c == __eof)
+ __in.setstate(ios_base::eofbit);
+ __in.width(0);
+ }
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//211. operator>>(istream&, string&) doesn't set failbit
+ if (!__extracted)
+ __in.setstate (ios_base::failbit);
+#endif
+ return __in;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_istream<_CharT, _Traits>&
+ getline(basic_istream<_CharT, _Traits>& __in,
+ basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
+ {
+ typedef basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::int_type __int_type;
+ typedef typename __istream_type::__streambuf_type __streambuf_type;
+ typedef typename __istream_type::__ctype_type __ctype_type;
+ typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
+ typedef typename __string_type::size_type __size_type;
+
+ __size_type __extracted = 0;
+ bool __testdelim = false;
+ typename __istream_type::sentry __cerb(__in, true);
+ if (__cerb)
+ {
+ __str.erase();
+ __size_type __n = __str.max_size();
+
+ __int_type __idelim = _Traits::to_int_type(__delim);
+ __streambuf_type* __sb = __in.rdbuf();
+ __int_type __c = __sb->sbumpc();
+ const __int_type __eof = _Traits::eof();
+ __testdelim = __c == __idelim;
+
+ while (__extracted <= __n && __c != __eof && !__testdelim)
+ {
+ __str += _Traits::to_char_type(__c);
+ ++__extracted;
+ __c = __sb->sbumpc();
+ __testdelim = __c == __idelim;
+ }
+ if (__c == __eof)
+ __in.setstate(ios_base::eofbit);
+ }
+ if (!__extracted && !__testdelim)
+ __in.setstate(ios_base::failbit);
+ return __in;
+ }
+
+ template<class _CharT, class _Traits, class _Alloc>
+ inline basic_istream<_CharT,_Traits>&
+ getline(basic_istream<_CharT, _Traits>& __in,
+ basic_string<_CharT,_Traits,_Alloc>& __str)
+ { return getline(__in, __str, __in.widen('\n')); }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+ extern template class basic_istream<char>;
+ extern template istream& ws(istream&);
+ extern template istream& operator>>(istream&, char&);
+ extern template istream& operator>>(istream&, char*);
+ extern template istream& operator>>(istream&, unsigned char&);
+ extern template istream& operator>>(istream&, signed char&);
+ extern template istream& operator>>(istream&, unsigned char*);
+ extern template istream& operator>>(istream&, signed char*);
+
+ 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*);
+} // namespace std
diff --git a/contrib/libstdc++/include/bits/locale_facets.h b/contrib/libstdc++/include/bits/locale_facets.h
new file mode 100644
index 0000000000000..d63eb5dd2d5f8
--- /dev/null
+++ b/contrib/libstdc++/include/bits/locale_facets.h
@@ -0,0 +1,1813 @@
+// Locale support -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 22.1 Locales
+//
+
+/** @file locale_facets.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_LOCFACETS_H
+#define _CPP_BITS_LOCFACETS_H 1
+
+#pragma GCC system_header
+
+#include <ctime> // For struct tm
+#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
+
+ // 22.2.1.1 Template class ctype
+ // Include host and configuration specific ctype enums for ctype_base.
+ #include <bits/ctype_base.h>
+
+ // Common base for ctype<_CharT>.
+ template<typename _CharT>
+ class __ctype_abstract_base : public locale::facet, public ctype_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+
+ bool
+ is(mask __m, char_type __c) const
+ { return this->do_is(__m, __c); }
+
+ const char_type*
+ is(const char_type *__lo, const char_type *__hi, mask *__vec) const
+ { return this->do_is(__lo, __hi, __vec); }
+
+ const char_type*
+ scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
+ { return this->do_scan_is(__m, __lo, __hi); }
+
+ const char_type*
+ scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
+ { return this->do_scan_not(__m, __lo, __hi); }
+
+ char_type
+ toupper(char_type __c) const
+ { return this->do_toupper(__c); }
+
+ const char_type*
+ toupper(char_type *__lo, const char_type* __hi) const
+ { return this->do_toupper(__lo, __hi); }
+
+ char_type
+ tolower(char_type __c) const
+ { return this->do_tolower(__c); }
+
+ const char_type*
+ tolower(char_type* __lo, const char_type* __hi) const
+ { return this->do_tolower(__lo, __hi); }
+
+ char_type
+ widen(char __c) const
+ { return this->do_widen(__c); }
+
+ const char*
+ widen(const char* __lo, const char* __hi, char_type* __to) const
+ { return this->do_widen(__lo, __hi, __to); }
+
+ char
+ narrow(char_type __c, char __dfault) const
+ { return this->do_narrow(__c, __dfault); }
+
+ const char_type*
+ narrow(const char_type* __lo, const char_type* __hi,
+ char __dfault, char *__to) const
+ { return this->do_narrow(__lo, __hi, __dfault, __to); }
+
+ protected:
+ explicit
+ __ctype_abstract_base(size_t __refs = 0): locale::facet(__refs) { }
+
+ virtual
+ ~__ctype_abstract_base() { }
+
+ virtual bool
+ do_is(mask __m, char_type __c) const = 0;
+
+ virtual const char_type*
+ do_is(const char_type* __lo, const char_type* __hi,
+ mask* __vec) const = 0;
+
+ virtual const char_type*
+ do_scan_is(mask __m, const char_type* __lo,
+ const char_type* __hi) const = 0;
+
+ virtual const char_type*
+ do_scan_not(mask __m, const char_type* __lo,
+ const char_type* __hi) const = 0;
+
+ virtual char_type
+ do_toupper(char_type) const = 0;
+
+ virtual const char_type*
+ do_toupper(char_type* __lo, const char_type* __hi) const = 0;
+
+ virtual char_type
+ do_tolower(char_type) const = 0;
+
+ virtual const char_type*
+ do_tolower(char_type* __lo, const char_type* __hi) const = 0;
+
+ virtual char_type
+ do_widen(char) const = 0;
+
+ virtual const char*
+ do_widen(const char* __lo, const char* __hi,
+ char_type* __dest) const = 0;
+
+ virtual char
+ do_narrow(char_type, char __dfault) const = 0;
+
+ virtual const char_type*
+ do_narrow(const char_type* __lo, const char_type* __hi,
+ char __dfault, char* __dest) const = 0;
+ };
+
+ // NB: Generic, mostly useless implementation.
+ template<typename _CharT>
+ class ctype : public __ctype_abstract_base<_CharT>
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef typename ctype::mask mask;
+
+ static locale::id id;
+
+ explicit
+ ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
+
+ protected:
+ virtual
+ ~ctype();
+
+ virtual bool
+ do_is(mask __m, char_type __c) const;
+
+ virtual const char_type*
+ do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
+
+ virtual const char_type*
+ do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
+
+ virtual const char_type*
+ do_scan_not(mask __m, const char_type* __lo,
+ const char_type* __hi) const;
+
+ virtual char_type
+ do_toupper(char_type __c) const;
+
+ virtual const char_type*
+ do_toupper(char_type* __lo, const char_type* __hi) const;
+
+ virtual char_type
+ do_tolower(char_type __c) const;
+
+ virtual const char_type*
+ do_tolower(char_type* __lo, const char_type* __hi) const;
+
+ virtual char_type
+ do_widen(char __c) const;
+
+ virtual const char*
+ do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
+
+ virtual char
+ do_narrow(char_type, char __dfault) const;
+
+ virtual const char_type*
+ do_narrow(const char_type* __lo, const char_type* __hi,
+ char __dfault, char* __dest) const;
+ };
+
+ template<typename _CharT>
+ locale::id ctype<_CharT>::id;
+
+ // 22.2.1.3 ctype<char> specialization.
+ template<>
+ class ctype<char> : public __ctype_abstract_base<char>
+ {
+ public:
+ // Types:
+ typedef char char_type;
+
+ protected:
+ // Data Members:
+ __c_locale _M_c_locale_ctype;
+ bool _M_del;
+ __to_type _M_toupper;
+ __to_type _M_tolower;
+ const mask* _M_table;
+
+ public:
+ static locale::id id;
+ static const size_t table_size = 1 + static_cast<unsigned char>(-1);
+
+ explicit
+ ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
+
+ explicit
+ ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
+ size_t __refs = 0);
+
+ inline bool
+ is(mask __m, char __c) const;
+
+ inline const char*
+ is(const char* __lo, const char* __hi, mask* __vec) const;
+
+ inline const char*
+ scan_is(mask __m, const char* __lo, const char* __hi) const;
+
+ inline const char*
+ scan_not(mask __m, const char* __lo, const char* __hi) const;
+
+ protected:
+ const mask*
+ table() const throw()
+ { return _M_table; }
+
+ static const mask*
+ classic_table() throw();
+
+ virtual
+ ~ctype();
+
+ virtual bool
+ do_is(mask __m, char_type __c) const;
+
+ virtual const char_type*
+ do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
+
+ virtual const char_type*
+ do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
+
+ virtual const char_type*
+ do_scan_not(mask __m, const char_type* __lo,
+ const char_type* __hi) const;
+
+ virtual char_type
+ do_toupper(char_type) const;
+
+ virtual const char_type*
+ do_toupper(char_type* __lo, const char_type* __hi) const;
+
+ virtual char_type
+ do_tolower(char_type) const;
+
+ virtual const char_type*
+ do_tolower(char_type* __lo, const char_type* __hi) const;
+
+ virtual char_type
+ do_widen(char) const;
+
+ virtual const char*
+ do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
+
+ virtual char
+ do_narrow(char_type, char __dfault) const;
+
+ virtual const char_type*
+ do_narrow(const char_type* __lo, const char_type* __hi,
+ char __dfault, char* __dest) const;
+ };
+
+ template<>
+ const ctype<char>&
+ use_facet<ctype<char> >(const locale& __loc);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ // 22.2.1.3 ctype<wchar_t> specialization
+ template<>
+ class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
+ {
+ public:
+ // Types:
+ typedef wchar_t char_type;
+ typedef wctype_t __wmask_type;
+
+ protected:
+ __c_locale _M_c_locale_ctype;
+
+ public:
+ // Data Members:
+ static locale::id id;
+
+ explicit
+ ctype(size_t __refs = 0);
+
+ explicit
+ ctype(__c_locale __cloc, size_t __refs = 0);
+
+ protected:
+ __wmask_type
+ _M_convert_to_wmask(const mask __m) const;
+
+ virtual
+ ~ctype();
+
+ virtual bool
+ do_is(mask __m, char_type __c) const;
+
+ virtual const char_type*
+ do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
+
+ virtual const char_type*
+ do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
+
+ virtual const char_type*
+ do_scan_not(mask __m, const char_type* __lo,
+ const char_type* __hi) const;
+
+ virtual char_type
+ do_toupper(char_type) const;
+
+ virtual const char_type*
+ do_toupper(char_type* __lo, const char_type* __hi) const;
+
+ virtual char_type
+ do_tolower(char_type) const;
+
+ virtual const char_type*
+ do_tolower(char_type* __lo, const char_type* __hi) const;
+
+ virtual char_type
+ do_widen(char) const;
+
+ virtual const char*
+ do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
+
+ virtual char
+ do_narrow(char_type, char __dfault) const;
+
+ virtual const char_type*
+ do_narrow(const char_type* __lo, const char_type* __hi,
+ char __dfault, char* __dest) const;
+
+ };
+
+ template<>
+ const ctype<wchar_t>&
+ use_facet<ctype<wchar_t> >(const locale& __loc);
+#endif //_GLIBCPP_USE_WCHAR_T
+
+ // Include host and configuration specific ctype inlines.
+ #include <bits/ctype_inline.h>
+
+ // 22.2.1.2 Template class ctype_byname
+ template<typename _CharT>
+ class ctype_byname : public ctype<_CharT>
+ {
+ public:
+ typedef _CharT char_type;
+
+ explicit
+ ctype_byname(const char* __s, size_t __refs = 0);
+
+ protected:
+ virtual
+ ~ctype_byname() { };
+ };
+
+ // 22.2.1.4 Class ctype_byname specializations.
+ template<>
+ ctype_byname<char>::ctype_byname(const char*, size_t refs);
+
+ template<>
+ ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
+
+ // 22.2.1.5 Template class codecvt
+ #include <bits/codecvt.h>
+
+
+ // 22.2.2 The numeric category.
+ class __num_base
+ {
+ protected:
+ // String literal of acceptable (narrow) input, for num_get.
+ // "0123456789eEabcdfABCDF"
+ static const char _S_atoms[];
+
+ enum
+ {
+ _M_zero,
+ _M_e = _M_zero + 10,
+ _M_E = _M_zero + 11,
+ _M_size = 21 + 1
+ };
+
+ // num_put
+ // Construct and return valid scanf format for floating point types.
+ static bool
+ _S_format_float(const ios_base& __io, char* __fptr, char __mod,
+ streamsize __prec);
+
+ // Construct and return valid scanf format for integer types.
+ static void
+ _S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl);
+ };
+
+
+ template<typename _CharT>
+ class numpunct : public locale::facet
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ static locale::id id;
+
+ private:
+ char_type _M_decimal_point;
+ char_type _M_thousands_sep;
+ const char* _M_grouping;
+ const char_type* _M_truename;
+ const char_type* _M_falsename;
+
+ public:
+ explicit
+ numpunct(size_t __refs = 0) : locale::facet(__refs)
+ { _M_initialize_numpunct(); }
+
+ explicit
+ numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
+ { _M_initialize_numpunct(__cloc); }
+
+ char_type
+ decimal_point() const
+ { return this->do_decimal_point(); }
+
+ char_type
+ thousands_sep() const
+ { return this->do_thousands_sep(); }
+
+ string
+ grouping() const
+ { return this->do_grouping(); }
+
+ string_type
+ truename() const
+ { return this->do_truename(); }
+
+ string_type
+ falsename() const
+ { return this->do_falsename(); }
+
+ protected:
+ virtual
+ ~numpunct();
+
+ virtual char_type
+ do_decimal_point() const
+ { return _M_decimal_point; }
+
+ virtual char_type
+ do_thousands_sep() const
+ { return _M_thousands_sep; }
+
+ virtual string
+ do_grouping() const
+ { return _M_grouping; }
+
+ virtual string_type
+ do_truename() const
+ { return _M_truename; }
+
+ virtual string_type
+ do_falsename() const
+ { return _M_falsename; }
+
+ // For use at construction time only.
+ void
+ _M_initialize_numpunct(__c_locale __cloc = _S_c_locale);
+ };
+
+ template<typename _CharT>
+ 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
+
+ template<typename _CharT>
+ class numpunct_byname : public numpunct<_CharT>
+ {
+ // Data Member.
+ __c_locale _M_c_locale_numpunct;
+
+ public:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ explicit
+ numpunct_byname(const char* __s, size_t __refs = 0)
+ : numpunct<_CharT>(__refs)
+ {
+ _S_create_c_locale(_M_c_locale_numpunct, __s);
+ _M_initialize_numpunct(_M_c_locale_numpunct);
+ }
+
+ protected:
+ virtual
+ ~numpunct_byname()
+ { _S_destroy_c_locale(_M_c_locale_numpunct); }
+ };
+
+ template<typename _CharT, typename _InIter>
+ class num_get : public locale::facet, public __num_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _InIter iter_type;
+
+ static locale::id id;
+
+ explicit
+ num_get(size_t __refs = 0) : locale::facet(__refs) { }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, bool& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, long& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned short& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned int& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned long& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, long long& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned long long& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+#endif
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, float& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, double& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, long double& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, void*& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
+ protected:
+ virtual ~num_get() { }
+
+ 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;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ unsigned short&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ unsigned int&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ unsigned long&) const;
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ long long&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ unsigned long long&) const;
+#endif
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ float&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ double&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ long double&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ void*&) const;
+ };
+
+ template<typename _CharT, typename _InIter>
+ locale::id num_get<_CharT, _InIter>::id;
+
+ template<typename _CharT, typename _OutIter>
+ class num_put : public locale::facet, public __num_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _OutIter iter_type;
+
+ static locale::id id;
+
+ explicit
+ num_put(size_t __refs = 0) : locale::facet(__refs) { }
+
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill,
+ unsigned long __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill,
+ unsigned long long __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+#endif
+
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill,
+ long double __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+
+ iter_type
+ put(iter_type __s, ios_base& __f, char_type __fill,
+ const void* __v) const
+ { return this->do_put(__s, __f, __fill, __v); }
+
+ protected:
+ template<typename _ValueT>
+ iter_type
+ _M_convert_float(iter_type, ios_base& __io, char_type __fill,
+ char __mod, _ValueT __v) const;
+
+ template<typename _ValueT>
+ iter_type
+ _M_convert_int(iter_type, ios_base& __io, char_type __fill,
+ char __mod, char __modl, _ValueT __v) const;
+
+ iter_type
+ _M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs,
+ int __len) const;
+
+ iter_type
+ _M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs,
+ int __len) const;
+
+ iter_type
+ _M_insert(iter_type, ios_base& __io, char_type __fill,
+ const char_type* __ws, int __len) const;
+
+ virtual
+ ~num_put() { };
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, long __v) const;
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
+#endif
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, double __v) const;
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
+ };
+
+ template <typename _CharT, typename _OutIter>
+ locale::id num_put<_CharT, _OutIter>::id;
+
+
+ template<typename _CharT>
+ class collate : public locale::facet
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ protected:
+ // Underlying "C" library locale information saved from
+ // initialization, needed by collate_byname as well.
+ __c_locale _M_c_locale_collate;
+
+ public:
+ static locale::id id;
+
+ explicit
+ collate(size_t __refs = 0)
+ : locale::facet(__refs)
+ { _M_c_locale_collate = _S_c_locale; }
+
+ // Non-standard.
+ explicit
+ collate(__c_locale __cloc, size_t __refs = 0)
+ : locale::facet(__refs)
+ { _M_c_locale_collate = _S_clone_c_locale(__cloc); }
+
+ int
+ compare(const _CharT* __lo1, const _CharT* __hi1,
+ const _CharT* __lo2, const _CharT* __hi2) const
+ { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
+
+ string_type
+ transform(const _CharT* __lo, const _CharT* __hi) const
+ { return this->do_transform(__lo, __hi); }
+
+ long
+ hash(const _CharT* __lo, const _CharT* __hi) const
+ { return this->do_hash(__lo, __hi); }
+
+ // Used to abstract out _CharT bits in virtual member functions, below.
+ int
+ _M_compare(const _CharT*, const _CharT*) const;
+
+ size_t
+ _M_transform(_CharT*, const _CharT*, size_t) const;
+
+ protected:
+ virtual
+ ~collate()
+ {
+ if (_M_c_locale_collate != _S_c_locale)
+ _S_destroy_c_locale(_M_c_locale_collate);
+ }
+
+ virtual int
+ do_compare(const _CharT* __lo1, const _CharT* __hi1,
+ const _CharT* __lo2, const _CharT* __hi2) const;
+
+ virtual string_type
+ do_transform(const _CharT* __lo, const _CharT* __hi) const;
+
+ virtual long
+ do_hash(const _CharT* __lo, const _CharT* __hi) const;
+ };
+
+ template<typename _CharT>
+ locale::id collate<_CharT>::id;
+
+ // Specializations.
+ template<>
+ int
+ collate<char>::_M_compare(const char*, const char*) const;
+
+ template<>
+ size_t
+ collate<char>::_M_transform(char*, const char*, size_t) const;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ int
+ collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
+
+ template<>
+ size_t
+ collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
+#endif
+
+ template<typename _CharT>
+ class collate_byname : public collate<_CharT>
+ {
+ public:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ explicit
+ collate_byname(const char* __s, size_t __refs = 0)
+ : collate<_CharT>(__refs)
+ {
+ if (_M_c_locale_collate != _S_c_locale)
+ _S_destroy_c_locale(_M_c_locale_collate);
+ _S_create_c_locale(_M_c_locale_collate, __s);
+ }
+
+ protected:
+ virtual
+ ~collate_byname() { }
+ };
+
+
+ class time_base
+ {
+ public:
+ enum dateorder { no_order, dmy, mdy, ymd, ydm };
+ };
+
+ template<typename _CharT>
+ class __timepunct : public locale::facet
+ {
+ public:
+ // Types:
+ typedef _CharT __char_type;
+ typedef basic_string<_CharT> __string_type;
+
+ static locale::id id;
+
+ // List of all known timezones, with GMT first.
+ static const _CharT* _S_timezones[14];
+
+ protected:
+ __c_locale _M_c_locale_timepunct;
+ const char* _M_name_timepunct;
+ const _CharT* _M_date_format;
+ const _CharT* _M_date_era_format;
+ const _CharT* _M_time_format;
+ const _CharT* _M_time_era_format;
+ const _CharT* _M_date_time_format;
+ const _CharT* _M_date_time_era_format;
+ const _CharT* _M_am;
+ const _CharT* _M_pm;
+ const _CharT* _M_am_pm_format;
+
+ // Day names, starting with "C"'s Sunday.
+ const _CharT* _M_day1;
+ const _CharT* _M_day2;
+ const _CharT* _M_day3;
+ const _CharT* _M_day4;
+ const _CharT* _M_day5;
+ const _CharT* _M_day6;
+ const _CharT* _M_day7;
+
+ // Abbreviated day names, starting with "C"'s Sun.
+ const _CharT* _M_day_a1;
+ const _CharT* _M_day_a2;
+ const _CharT* _M_day_a3;
+ const _CharT* _M_day_a4;
+ const _CharT* _M_day_a5;
+ const _CharT* _M_day_a6;
+ const _CharT* _M_day_a7;
+
+ // Month names, starting with "C"'s January.
+ const _CharT* _M_month01;
+ const _CharT* _M_month02;
+ const _CharT* _M_month03;
+ const _CharT* _M_month04;
+ const _CharT* _M_month05;
+ const _CharT* _M_month06;
+ const _CharT* _M_month07;
+ const _CharT* _M_month08;
+ const _CharT* _M_month09;
+ const _CharT* _M_month10;
+ const _CharT* _M_month11;
+ const _CharT* _M_month12;
+
+ // Abbreviated month names, starting with "C"'s Jan.
+ const _CharT* _M_month_a01;
+ const _CharT* _M_month_a02;
+ const _CharT* _M_month_a03;
+ const _CharT* _M_month_a04;
+ const _CharT* _M_month_a05;
+ const _CharT* _M_month_a06;
+ const _CharT* _M_month_a07;
+ const _CharT* _M_month_a08;
+ const _CharT* _M_month_a09;
+ const _CharT* _M_month_a10;
+ const _CharT* _M_month_a11;
+ const _CharT* _M_month_a12;
+
+ public:
+ explicit
+ __timepunct(size_t __refs = 0)
+ : locale::facet(__refs), _M_name_timepunct("C")
+ { _M_initialize_timepunct(); }
+
+ explicit
+ __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
+ : locale::facet(__refs), _M_name_timepunct(__s)
+ { _M_initialize_timepunct(__cloc); }
+
+ void
+ _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
+ const tm* __tm) const;
+
+ void
+ _M_date_formats(const _CharT** __date) const
+ {
+ // Always have default first.
+ __date[0] = _M_date_format;
+ __date[1] = _M_date_era_format;
+ }
+
+ void
+ _M_time_formats(const _CharT** __time) const
+ {
+ // Always have default first.
+ __time[0] = _M_time_format;
+ __time[1] = _M_time_era_format;
+ }
+
+ void
+ _M_ampm(const _CharT** __ampm) const
+ {
+ __ampm[0] = _M_am;
+ __ampm[1] = _M_pm;
+ }
+
+ void
+ _M_date_time_formats(const _CharT** __dt) const
+ {
+ // Always have default first.
+ __dt[0] = _M_date_time_format;
+ __dt[1] = _M_date_time_era_format;
+ }
+
+ void
+ _M_days(const _CharT** __days) const
+ {
+ __days[0] = _M_day1;
+ __days[1] = _M_day2;
+ __days[2] = _M_day3;
+ __days[3] = _M_day4;
+ __days[4] = _M_day5;
+ __days[5] = _M_day6;
+ __days[6] = _M_day7;
+ }
+
+ void
+ _M_days_abbreviated(const _CharT** __days) const
+ {
+ __days[0] = _M_day_a1;
+ __days[1] = _M_day_a2;
+ __days[2] = _M_day_a3;
+ __days[3] = _M_day_a4;
+ __days[4] = _M_day_a5;
+ __days[5] = _M_day_a6;
+ __days[6] = _M_day_a7;
+ }
+
+ void
+ _M_months(const _CharT** __months) const
+ {
+ __months[0] = _M_month01;
+ __months[1] = _M_month02;
+ __months[2] = _M_month03;
+ __months[3] = _M_month04;
+ __months[4] = _M_month05;
+ __months[5] = _M_month06;
+ __months[6] = _M_month07;
+ __months[7] = _M_month08;
+ __months[8] = _M_month09;
+ __months[9] = _M_month10;
+ __months[10] = _M_month11;
+ __months[11] = _M_month12;
+ }
+
+ void
+ _M_months_abbreviated(const _CharT** __months) const
+ {
+ __months[0] = _M_month_a01;
+ __months[1] = _M_month_a02;
+ __months[2] = _M_month_a03;
+ __months[3] = _M_month_a04;
+ __months[4] = _M_month_a05;
+ __months[5] = _M_month_a06;
+ __months[6] = _M_month_a07;
+ __months[7] = _M_month_a08;
+ __months[8] = _M_month_a09;
+ __months[9] = _M_month_a10;
+ __months[10] = _M_month_a11;
+ __months[11] = _M_month_a12;
+ }
+
+ protected:
+ virtual
+ ~__timepunct();
+
+ // For use at construction time only.
+ void
+ _M_initialize_timepunct(__c_locale __cloc = _S_c_locale);
+ };
+
+ template<typename _CharT>
+ locale::id __timepunct<_CharT>::id;
+
+ // Specializations.
+ template<>
+ __timepunct<char>::~__timepunct();
+
+ template<>
+ const char*
+ __timepunct<char>::_S_timezones[14];
+
+ template<>
+ void
+ __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
+
+ template<>
+ void
+ __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ __timepunct<wchar_t>::~__timepunct();
+
+ template<>
+ const wchar_t*
+ __timepunct<wchar_t>::_S_timezones[14];
+
+ template<>
+ void
+ __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
+
+ template<>
+ void
+ __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];
+
+
+ template<typename _CharT, typename _InIter>
+ class time_get : public locale::facet, public time_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _InIter iter_type;
+ typedef basic_string<_CharT> __string_type;
+
+ static locale::id id;
+
+ explicit
+ time_get(size_t __refs = 0)
+ : locale::facet (__refs) { }
+
+ dateorder
+ date_order() const
+ { return this->do_date_order(); }
+
+ iter_type
+ get_time(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ { return this->do_get_time(__beg, __end, __io, __err, __tm); }
+
+ iter_type
+ get_date(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ { return this->do_get_date(__beg, __end, __io, __err, __tm); }
+
+ iter_type
+ get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
+
+ iter_type
+ get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
+
+ iter_type
+ get_year(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ { return this->do_get_year(__beg, __end, __io, __err, __tm); }
+
+ protected:
+ virtual
+ ~time_get() { }
+
+ virtual dateorder
+ do_date_order() const;
+
+ virtual iter_type
+ do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const;
+
+ virtual iter_type
+ do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const;
+
+ virtual iter_type
+ do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
+ ios_base::iostate& __err, tm* __tm) const;
+
+ virtual iter_type
+ do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
+ ios_base::iostate& __err, tm* __tm) const;
+
+ virtual iter_type
+ do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const;
+
+ // Extract numeric component of length __len.
+ void
+ _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
+ int __min, int __max, size_t __len,
+ const ctype<_CharT>& __ctype,
+ ios_base::iostate& __err) const;
+
+ // Extract day or month name, or any unique array of string
+ // literals in a const _CharT* array.
+ void
+ _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
+ const _CharT** __names, size_t __indexlen,
+ ios_base::iostate& __err) const;
+
+ // Extract on a component-by-component basis, via __format argument.
+ void
+ _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm,
+ const _CharT* __format) const;
+ };
+
+ template<typename _CharT, typename _InIter>
+ locale::id time_get<_CharT, _InIter>::id;
+
+ template<typename _CharT, typename _InIter>
+ class time_get_byname : public time_get<_CharT, _InIter>
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _InIter iter_type;
+
+ explicit
+ time_get_byname(const char*, size_t __refs = 0)
+ : time_get<_CharT, _InIter>(__refs) { }
+
+ protected:
+ virtual
+ ~time_get_byname() { }
+ };
+
+ template<typename _CharT, typename _OutIter>
+ class time_put : public locale::facet, public time_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _OutIter iter_type;
+
+ static locale::id id;
+
+ explicit
+ time_put(size_t __refs = 0)
+ : locale::facet(__refs) { }
+
+ iter_type
+ put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
+ const _CharT* __beg, const _CharT* __end) const;
+
+ iter_type
+ put(iter_type __s, ios_base& __io, char_type __fill,
+ const tm* __tm, char __format, char __mod = 0) const
+ { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
+
+ protected:
+ virtual
+ ~time_put()
+ { }
+
+ virtual iter_type
+ do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
+ char __format, char __mod) const;
+ };
+
+ template<typename _CharT, typename _OutIter>
+ locale::id time_put<_CharT, _OutIter>::id;
+
+ template<typename _CharT, typename _OutIter>
+ class time_put_byname : public time_put<_CharT, _OutIter>
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _OutIter iter_type;
+
+ explicit
+ time_put_byname(const char* /*__s*/, size_t __refs = 0)
+ : time_put<_CharT, _OutIter>(__refs)
+ { };
+
+ protected:
+ virtual
+ ~time_put_byname() { }
+ };
+
+
+ class money_base
+ {
+ public:
+ enum part { none, space, symbol, sign, value };
+ struct pattern { char field[4]; };
+
+ static const pattern _S_default_pattern;
+
+ // Construct and return valid pattern consisting of some combination of:
+ // space none symbol sign value
+ static pattern
+ _S_construct_pattern(char __precedes, char __space, char __posn);
+ };
+
+ template<typename _CharT, bool _Intl>
+ class moneypunct : public locale::facet, public money_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ static const bool intl = _Intl;
+ static locale::id id;
+
+ private:
+ 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
+ moneypunct(size_t __refs = 0) : locale::facet(__refs)
+ { _M_initialize_moneypunct(); }
+
+ explicit
+ moneypunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
+ { _M_initialize_moneypunct(__cloc); }
+
+ char_type
+ decimal_point() const
+ { return this->do_decimal_point(); }
+
+ char_type
+ thousands_sep() const
+ { return this->do_thousands_sep(); }
+
+ string
+ grouping() const
+ { return this->do_grouping(); }
+
+ string_type
+ curr_symbol() const
+ { return this->do_curr_symbol(); }
+
+ string_type
+ positive_sign() const
+ { return this->do_positive_sign(); }
+
+ string_type
+ negative_sign() const
+ { return this->do_negative_sign(); }
+
+ int
+ frac_digits() const
+ { return this->do_frac_digits(); }
+
+ pattern
+ pos_format() const
+ { return this->do_pos_format(); }
+
+ pattern
+ neg_format() const
+ { return this->do_neg_format(); }
+
+ protected:
+ virtual
+ ~moneypunct();
+
+ virtual char_type
+ do_decimal_point() const
+ { return _M_decimal_point; }
+
+ virtual char_type
+ do_thousands_sep() const
+ { return _M_thousands_sep; }
+
+ virtual string
+ do_grouping() const
+ { return _M_grouping; }
+
+ virtual string_type
+ do_curr_symbol() const
+ { return _M_curr_symbol; }
+
+ virtual string_type
+ do_positive_sign() const
+ { return _M_positive_sign; }
+
+ virtual string_type
+ do_negative_sign() const
+ { return _M_negative_sign; }
+
+ virtual int
+ do_frac_digits() const
+ { return _M_frac_digits; }
+
+ virtual pattern
+ do_pos_format() const
+ { return _M_pos_format; }
+
+ virtual pattern
+ do_neg_format() const
+ { return _M_neg_format; }
+
+ // For use at construction time only.
+ void
+ _M_initialize_moneypunct(__c_locale __cloc = _S_c_locale);
+ };
+
+ template<typename _CharT, bool _Intl>
+ locale::id moneypunct<_CharT, _Intl>::id;
+
+ 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);
+
+ template<>
+ void
+ moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc);
+
+#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);
+
+ template<>
+ void
+ moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc);
+#endif
+
+ template<typename _CharT, bool _Intl>
+ class moneypunct_byname : public moneypunct<_CharT, _Intl>
+ {
+ __c_locale _M_c_locale_moneypunct;
+
+ public:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ static const bool intl = _Intl;
+
+ explicit
+ moneypunct_byname(const char* __s, size_t __refs = 0)
+ : moneypunct<_CharT, _Intl>(__refs)
+ {
+ _S_create_c_locale(_M_c_locale_moneypunct, __s);
+ _M_initialize_moneypunct(_M_c_locale_moneypunct);
+ }
+
+ protected:
+ virtual
+ ~moneypunct_byname()
+ { _S_destroy_c_locale(_M_c_locale_moneypunct); }
+ };
+
+ template<typename _CharT, bool _Intl>
+ const bool moneypunct_byname<_CharT, _Intl>::intl;
+
+ template<typename _CharT, typename _InIter>
+ class money_get : public locale::facet
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _InIter iter_type;
+ typedef basic_string<_CharT> string_type;
+
+ static locale::id id;
+
+ explicit
+ money_get(size_t __refs = 0) : locale::facet(__refs) { }
+
+ iter_type
+ get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, long double& __units) const
+ { return this->do_get(__s, __end, __intl, __io, __err, __units); }
+
+ iter_type
+ get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, string_type& __digits) const
+ { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
+
+ protected:
+ virtual
+ ~money_get() { }
+
+ virtual iter_type
+ do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, long double& __units) const;
+
+ virtual iter_type
+ do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, string_type& __digits) const;
+ };
+
+ template<typename _CharT, typename _InIter>
+ locale::id money_get<_CharT, _InIter>::id;
+
+ template<typename _CharT, typename _OutIter>
+ class money_put : public locale::facet
+ {
+ public:
+ typedef _CharT char_type;
+ typedef _OutIter iter_type;
+ typedef basic_string<_CharT> string_type;
+
+ static locale::id id;
+
+ explicit
+ money_put(size_t __refs = 0) : locale::facet(__refs) { }
+
+ iter_type
+ put(iter_type __s, bool __intl, ios_base& __io,
+ char_type __fill, long double __units) const
+ { return this->do_put(__s, __intl, __io, __fill, __units); }
+
+ iter_type
+ put(iter_type __s, bool __intl, ios_base& __io,
+ char_type __fill, const string_type& __digits) const
+ { return this->do_put(__s, __intl, __io, __fill, __digits); }
+
+ protected:
+ virtual
+ ~money_put() { }
+
+ virtual iter_type
+ do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ long double __units) const;
+
+ virtual iter_type
+ do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ const string_type& __digits) const;
+ };
+
+ template<typename _CharT, typename _OutIter>
+ locale::id money_put<_CharT, _OutIter>::id;
+
+
+ struct messages_base
+ {
+ typedef int catalog;
+ };
+
+ template<typename _CharT>
+ class messages : public locale::facet, public messages_base
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ protected:
+ // 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
+
+ public:
+ static locale::id id;
+
+ explicit
+ messages(size_t __refs = 0)
+ : locale::facet(__refs), _M_name_messages("C")
+ { _M_c_locale_messages = _S_c_locale; }
+
+ // 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);
+ }
+
+ catalog
+ open(const basic_string<char>& __s, const locale& __loc) const
+ { return this->do_open(__s, __loc); }
+
+ // Non-standard and unorthodox, yet effective.
+ catalog
+ open(const basic_string<char>&, const locale&, const char*) const;
+
+ string_type
+ get(catalog __c, int __set, int __msgid, const string_type& __s) const
+ { return this->do_get(__c, __set, __msgid, __s); }
+
+ void
+ close(catalog __c) const
+ { return this->do_close(__c); }
+
+ protected:
+ virtual
+ ~messages()
+ {
+ if (_M_c_locale_messages != _S_c_locale)
+ _S_destroy_c_locale(_M_c_locale_messages);
+ }
+
+ virtual catalog
+ do_open(const basic_string<char>&, const locale&) const;
+
+ virtual string_type
+ do_get(catalog, int, int, const string_type& __dfault) const;
+
+ virtual void
+ do_close(catalog) const;
+
+ // Returns a locale and codeset-converted string, given a char* message.
+ char*
+ _M_convert_to_char(const string_type& __msg) const
+ {
+ // XXX
+ return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
+ }
+
+ // Returns a locale and codeset-converted string, given a char* message.
+ string_type
+ _M_convert_from_char(char* __msg) const
+ {
+ // Length of message string without terminating null.
+ size_t __len = char_traits<char>::length(__msg) - 1;
+
+ // "everybody can easily convert the string using
+ // mbsrtowcs/wcsrtombs or with iconv()"
+#if 0
+ // Convert char* to _CharT in locale used to open catalog.
+ // XXX need additional template parameter on messages class for this..
+ // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
+ typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
+
+ __codecvt_type::state_type __state;
+ // XXX may need to initialize state.
+ //initialize_state(__state._M_init());
+
+ char* __from_next;
+ // XXX what size for this string?
+ _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
+ const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
+ __cvt.out(__state, __msg, __msg + __len, __from_next,
+ __to, __to + __len + 1, __to_next);
+ return string_type(__to);
+#endif
+#if 0
+ typedef ctype<_CharT> __ctype_type;
+ // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
+ const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
+ // XXX Again, proper length of converted string an issue here.
+ // For now, assume the converted length is not larger.
+ _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
+ __cvt.widen(__msg, __msg + __len, __dest);
+ return basic_string<_CharT>(__dest);
+#endif
+ return string_type();
+ }
+ };
+
+ template<typename _CharT>
+ locale::id messages<_CharT>::id;
+
+ // Specializations for required instantiations.
+ template<>
+ string
+ messages<char>::do_get(catalog, int, int, const string&) const;
+
+ // Include host and configuration specific messages virtual functions.
+ #include <bits/messages_members.h>
+
+ template<typename _CharT>
+ class messages_byname : public messages<_CharT>
+ {
+ public:
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
+
+ explicit
+ messages_byname(const char* __s, size_t __refs = 0)
+ : messages<_CharT>(__refs)
+ {
+ _M_name_messages = __s;
+ if (_M_c_locale_messages != _S_c_locale)
+ _S_destroy_c_locale(_M_c_locale_messages);
+ _S_create_c_locale(_M_c_locale_messages, __s);
+ }
+
+ protected:
+ virtual
+ ~messages_byname()
+ { }
+ };
+
+
+ // Subclause convenience interfaces, inlines.
+ // NB: These are inline because, when used in a loop, some compilers
+ // can hoist the body out of the loop; then it's just as fast as the
+ // C is*() function.
+ template<typename _CharT>
+ inline bool
+ isspace(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
+
+ template<typename _CharT>
+ inline bool
+ isprint(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
+
+ template<typename _CharT>
+ inline bool
+ iscntrl(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
+
+ template<typename _CharT>
+ inline bool
+ isupper(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
+
+ template<typename _CharT>
+ inline bool islower(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
+
+ template<typename _CharT>
+ inline bool
+ isalpha(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
+
+ template<typename _CharT>
+ inline bool
+ isdigit(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
+
+ template<typename _CharT>
+ inline bool
+ ispunct(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
+
+ template<typename _CharT>
+ inline bool
+ isxdigit(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
+
+ template<typename _CharT>
+ inline bool
+ isalnum(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
+
+ template<typename _CharT>
+ inline bool
+ isgraph(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
+
+ template<typename _CharT>
+ inline _CharT
+ toupper(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
+
+ template<typename _CharT>
+ inline _CharT
+ tolower(_CharT __c, const locale& __loc)
+ { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/locale_facets.tcc b/contrib/libstdc++/include/bits/locale_facets.tcc
new file mode 100644
index 0000000000000..d362c33f87fbc
--- /dev/null
+++ b/contrib/libstdc++/include/bits/locale_facets.tcc
@@ -0,0 +1,2401 @@
+// Locale support -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Warning: this file is not meant for user inclusion. Use <locale>.
+
+#ifndef _CPP_BITS_LOCFACETS_TCC
+#define _CPP_BITS_LOCFACETS_TCC 1
+
+#pragma GCC system_header
+
+#include <cerrno>
+#include <clocale> // For localeconv
+#include <cstdlib> // For strof, strtold
+#include <cmath> // For ceil
+#include <cctype> // For isspace
+#include <limits> // For numeric_limits
+#include <bits/streambuf_iterator.h>
+#include <typeinfo> // For bad_cast.
+
+namespace std
+{
+ template<typename _Facet>
+ locale
+ locale::combine(const locale& __other) const
+ {
+ _Impl* __tmp = new _Impl(*_M_impl, 1);
+ __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
+ return locale(__tmp);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ bool
+ locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
+ const basic_string<_CharT, _Traits, _Alloc>& __s2) const
+ {
+ typedef std::collate<_CharT> __collate_type;
+ const __collate_type& __collate = use_facet<__collate_type>(*this);
+ return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
+ __s2.data(), __s2.data() + __s2.length()) < 0);
+ }
+
+ template<typename _Facet>
+ const _Facet&
+ use_facet(const locale& __loc)
+ {
+ 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&>(*__facets[__i]);
+ }
+
+ template<typename _Facet>
+ bool
+ has_facet(const locale& __loc) throw()
+ {
+ 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]);
+ }
+
+
+ // Stage 1: Determine a conversion specifier.
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
+ ios_base::iostate& __err, string& __xtrc) const
+ {
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+
+ // First check for sign.
+ const char_type __plus = __ctype.widen('+');
+ const char_type __minus = __ctype.widen('-');
+ int __pos = 0;
+ char_type __c = *__beg;
+ if ((__c == __plus || __c == __minus) && __beg != __end)
+ {
+ __xtrc += __ctype.narrow(__c, char());
+ ++__pos;
+ __c = *(++__beg);
+ }
+
+ // Next, strip leading zeros.
+ const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
+ bool __found_zero = false;
+ while (__c == __zero && __beg != __end)
+ {
+ __c = *(++__beg);
+ __found_zero = true;
+ }
+ if (__found_zero)
+ {
+ __xtrc += _S_atoms[_M_zero];
+ ++__pos;
+ }
+
+ // Only need acceptable digits for floating point numbers.
+ const size_t __len = _M_E - _M_zero + 1;
+ char_type __watoms[__len];
+ __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
+ bool __found_dec = false;
+ bool __found_sci = false;
+ const char_type __dec = __np.decimal_point();
+
+ string __found_grouping;
+ const string __grouping = __np.grouping();
+ bool __check_grouping = __grouping.size();
+ int __sep_pos = 0;
+ const char_type __sep = __np.thousands_sep();
+
+ 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)
+ {
+ // Try first for acceptable digit; record it if found.
+ ++__pos;
+ __xtrc += _S_atoms[__p - __watoms];
+ ++__sep_pos;
+ __c = *(++__beg);
+ }
+ else if (__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.
+ if (__sep_pos)
+ {
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ __c = *(++__beg);
+ }
+ else
+ {
+ __err |= ios_base::failbit;
+ break;
+ }
+ }
+ else if (__c == __dec && !__found_dec)
+ {
+ // 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])
+ && !__found_sci && __pos)
+ {
+ // Scientific notation.
+ ++__pos;
+ __xtrc += __ctype.narrow(__c, char());
+ __c = *(++__beg);
+
+ // Remove optional plus or minus sign, if they exist.
+ if (__c == __plus || __c == __minus)
+ {
+ ++__pos;
+ __xtrc += __ctype.narrow(__c, char());
+ __c = *(++__beg);
+ }
+ __found_sci = true;
+ }
+ else
+ // Not a valid input item.
+ break;
+ }
+
+ // Digit grouping is checked. If grouping and found_grouping don't
+ // match, then get very very upset, and set failbit.
+ if (__check_grouping && __found_grouping.size())
+ {
+ // Add the ending grouping if a decimal wasn't found.
+ if (!__found_dec)
+ __found_grouping += static_cast<char>(__sep_pos);
+ if (!__verify_grouping(__grouping, __found_grouping))
+ __err |= ios_base::failbit;
+ }
+
+ // Finish up
+ __xtrc += char();
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return __beg;
+ }
+
+ // Stage 1: Determine a conversion specifier.
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
+ ios_base::iostate& __err, string& __xtrc, int& __base) const
+ {
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+
+ // NB: Iff __basefield == 0, this can change based on contents.
+ ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+ if (__basefield == ios_base::oct)
+ __base = 8;
+ else if (__basefield == ios_base::hex)
+ __base = 16;
+ else
+ __base = 10;
+
+ // First check for sign.
+ int __pos = 0;
+ char_type __c = *__beg;
+ if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
+ && __beg != __end)
+ {
+ __xtrc += __ctype.narrow(__c, char());
+ ++__pos;
+ __c = *(++__beg);
+ }
+
+ // Next, strip leading zeros and check required digits for base formats.
+ const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
+ const char_type __x = __ctype.widen('x');
+ const char_type __X = __ctype.widen('X');
+ if (__base == 10)
+ {
+ bool __found_zero = false;
+ while (__c == __zero && __beg != __end)
+ {
+ __c = *(++__beg);
+ __found_zero = true;
+ }
+ if (__found_zero)
+ {
+ __xtrc += _S_atoms[_M_zero];
+ ++__pos;
+ if (__basefield == 0)
+ {
+ if ((__c == __x || __c == __X) && __beg != __end)
+ {
+ __xtrc += __ctype.narrow(__c, char());
+ ++__pos;
+ __c = *(++__beg);
+ __base = 16;
+ }
+ else
+ __base = 8;
+ }
+ }
+ }
+ else if (__base == 16)
+ {
+ if (__c == __zero && __beg != __end)
+ {
+ __xtrc += _S_atoms[_M_zero];
+ ++__pos;
+ __c = *(++__beg);
+ if ((__c == __x || __c == __X) && __beg != __end)
+ {
+ __xtrc += __ctype.narrow(__c, char());
+ ++__pos;
+ __c = *(++__beg);
+ }
+ }
+ }
+
+ // At this point, base is determined. If not hex, only allow
+ // base digits as valid input.
+ size_t __len;
+ if (__base == 16)
+ __len = _M_size;
+ else
+ __len = __base;
+
+ // Extract.
+ char_type __watoms[_M_size];
+ __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
+ string __found_grouping;
+ const string __grouping = __np.grouping();
+ 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)
+ {
+ // Try first for acceptable digit; record it if found.
+ __xtrc += _S_atoms[__p - __watoms];
+ ++__pos;
+ ++__sep_pos;
+ __c = *(++__beg);
+ }
+ else if (__c == __sep && __check_grouping)
+ {
+ // NB: Thousands separator at the beginning of a string
+ // is a no-no, as is two consecutive thousands separators.
+ if (__sep_pos)
+ {
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ __c = *(++__beg);
+ }
+ else
+ {
+ __err |= ios_base::failbit;
+ break;
+ }
+ }
+ else
+ // Not a valid input item.
+ break;
+ }
+
+ // Digit grouping is checked. If grouping and found_grouping don't
+ // match, then get very very upset, and set failbit.
+ if (__check_grouping && __found_grouping.size())
+ {
+ // Add the ending grouping.
+ __found_grouping += static_cast<char>(__sep_pos);
+ if (!__verify_grouping(__grouping, __found_grouping))
+ __err |= ios_base::failbit;
+ }
+
+ // Finish up.
+ __xtrc += char();
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return __beg;
+ }
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ //17. Bad bool parsing
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, bool& __v) const
+ {
+ // Parse bool values as unsigned long
+ if (!(__io.flags() & ios_base::boolalpha))
+ {
+ // NB: We can't just call do_get(long) here, as it might
+ // refer to a derived class.
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+
+ unsigned long __ul;
+ __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
+ if (!(__err & ios_base::failbit) && __ul <= 1)
+ __v = __ul;
+ else
+ __err |= ios_base::failbit;
+ }
+
+ // Parse bool values as alphanumeric
+ else
+ {
+ typedef basic_string<_CharT> __string_type;
+ locale __loc = __io.getloc();
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ 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 == __falses[__n] : false;
+ bool __testt = __n <= __truen ? __c == __trues[__n] : false;
+ if (!(__testf || __testt))
+ {
+ __err |= ios_base::failbit;
+ break;
+ }
+ else if (__testf && __n == __falsen)
+ {
+ __v = 0;
+ break;
+ }
+ else if (__testt && __n == __truen)
+ {
+ __v = 1;
+ break;
+ }
+ }
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ }
+ return __beg;
+ }
+#endif
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, long& __v) const
+ {
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+ __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned short& __v) const
+ {
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+ unsigned long __ul;
+ __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
+ if (!(__err & ios_base::failbit)
+ && __ul <= numeric_limits<unsigned short>::max())
+ __v = static_cast<unsigned short>(__ul);
+ else
+ __err |= ios_base::failbit;
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned int& __v) const
+ {
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+ unsigned long __ul;
+ __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
+ if (!(__err & ios_base::failbit)
+ && __ul <= numeric_limits<unsigned int>::max())
+ __v = static_cast<unsigned int>(__ul);
+ else
+ __err |= ios_base::failbit;
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned long& __v) const
+ {
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+ __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+ return __beg;
+ }
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, long long& __v) const
+ {
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+ __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, unsigned long long& __v) const
+ {
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+ __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+ return __beg;
+ }
+#endif
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, float& __v) const
+ {
+ string __xtrc;
+ __xtrc.reserve(32);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, double& __v) const
+ {
+ string __xtrc;
+ __xtrc.reserve(32);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, long double& __v) const
+ {
+ string __xtrc;
+ __xtrc.reserve(32);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ num_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, void*& __v) const
+ {
+ // Prepare for hex formatted input
+ typedef ios_base::fmtflags fmtflags;
+ fmtflags __fmt = __io.flags();
+ fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
+ | ios_base::uppercase | ios_base::internal);
+ __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
+
+ string __xtrc;
+ int __base;
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+
+ // Reset from hex formatted input
+ __io.flags(__fmt);
+
+ unsigned long __ul;
+ __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
+ if (!(__err & ios_base::failbit))
+ __v = reinterpret_cast<void*>(__ul);
+ else
+ __err |= ios_base::failbit;
+ return __beg;
+ }
+
+ // 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
+ num_put<_CharT, _OutIter>::
+ _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
+ _ValueT __v) const
+ {
+ // Note: digits10 is rounded down. We need to add 1 to ensure
+ // we get the full available precision.
+ const int __max_digits = numeric_limits<_ValueT>::digits10 + 1;
+ streamsize __prec = __io.precision();
+
+ 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;
+ // ios_base::fixed outputs may need up to __max_exp+1 chars
+ // for the integer part + up to __max_digits chars for the
+ // fractional part + 3 chars for sign, decimal point, '\0'. On
+ // the other hand, for non-fixed outputs __max_digits*3 chars
+ // are largely sufficient.
+ const int __cs_size = __fixed ? __max_exp + __max_digits + 4
+ : __max_digits * 3;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+
+ if (_S_format_float(__io, __fbuf, __mod, __prec))
+ __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
+ else
+ __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
+#endif
+ return _M_widen_float(__s, __io, __fill, __cs, __len);
+ }
+
+ template<typename _CharT, typename _OutIter>
+ template<typename _ValueT>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
+ char __modl, _ValueT __v) const
+ {
+ // [22.2.2.2.2] Stage 1, numeric conversion to character.
+
+ // Long enough for the max format spec.
+ char __fbuf[16];
+ _S_format_int(__io, __fbuf, __mod, __modl);
+#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);
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
+ int __len) const
+ {
+ // [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();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ * __len));
+ // Grouping can add (almost) as many separators as the number of
+ // digits, but no more.
+ _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ * __len * 2));
+ __ctype.widen(__cs, __cs + __len, __ws);
+
+ // 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('.')))
+ __ws[__p - __ws] = __np.decimal_point();
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//282. What types does numpunct grouping refer to?
+ // Add grouping, if necessary.
+ const string __grouping = __np.grouping();
+ ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+ if (__grouping.size())
+ {
+ _CharT* __p2;
+ int __declen = __p ? __p - __ws : __len;
+ __p2 = __add_grouping(__ws2, __np.thousands_sep(),
+ __grouping.c_str(),
+ __grouping.c_str() + __grouping.size(),
+ __ws, __ws + __declen);
+ int __newlen = __p2 - __ws2;
+
+ // Tack on decimal part.
+ if (__p)
+ {
+ char_traits<_CharT>::copy(__p2, __p, __len - __declen);
+ __newlen += __len - __declen;
+ }
+
+ // Switch strings, establish correct new length.
+ __ws = __ws2;
+ __len = __newlen;
+ }
+#endif
+ return _M_insert(__s, __io, __fill, __ws, __len);
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
+ int __len) const
+ {
+ // [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();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ * __len));
+ // Grouping can add (almost) as many separators as the number of
+ // digits, but no more.
+ _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ * __len * 2));
+ __ctype.widen(__cs, __cs + __len, __ws);
+
+ // Add grouping, if necessary.
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ const string __grouping = __np.grouping();
+ 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.
+ streamsize __off = 0;
+ if (__io.flags() & ios_base::showbase)
+ 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 + __off, __np.thousands_sep(),
+ __grouping.c_str(),
+ __grouping.c_str() + __grouping.size(),
+ __ws + __off, __ws + __len);
+ __len = __p - __ws2;
+ // Switch strings.
+ __ws = __ws2;
+ }
+ return _M_insert(__s, __io, __fill, __ws, __len);
+ }
+
+ // For use by integer and floating-point types after they have been
+ // converted into a char_type string.
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws,
+ int __len) const
+ {
+ // [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);
+ __len = static_cast<int>(__w);
+ // Switch strings.
+ __ws = __ws2;
+ }
+ __io.width(0);
+
+ // [22.2.2.2.2] Stage 4.
+ // Write resulting, fully-formatted string to output iterator.
+ for (int __j = 0; __j < __len; ++__j, ++__s)
+ *__s = __ws[__j];
+ return __s;
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
+ {
+ ios_base::fmtflags __flags = __io.flags();
+ if ((__flags & ios_base::boolalpha) == 0)
+ {
+ unsigned long __uv = __v;
+ __s = _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
+ }
+ else
+ {
+ typedef basic_string<_CharT> __string_type;
+ locale __loc = __io.getloc();
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ __string_type __name;
+ if (__v)
+ __name = __np.truename();
+ else
+ __name = __np.falsename();
+ __s = _M_insert(__s, __io, __fill, __name.c_str(), __name.size());
+ }
+ return __s;
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _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); }
+
+ 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); }
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
+ { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ do_put(iter_type __s, ios_base& __io, char_type __fill,
+ unsigned long long __v) const
+ { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
+#endif
+
+ template<typename _CharT, typename _OutIter>
+ _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); }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ do_put(iter_type __s, ios_base& __io, char_type __fill,
+ long double __v) const
+ { return _M_convert_float(__s, __io, __fill, 'L', __v); }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ do_put(iter_type __s, ios_base& __io, char_type __fill,
+ const void* __v) const
+ {
+ ios_base::fmtflags __flags = __io.flags();
+ ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
+ | ios_base::uppercase | ios_base::internal);
+ __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
+ try
+ {
+ __s = _M_convert_int(__s, __io, __fill, 'u', char_type(),
+ reinterpret_cast<unsigned long>(__v));
+ __io.flags(__flags);
+ }
+ catch (...)
+ {
+ __io.flags(__flags);
+ __throw_exception_again;
+ }
+ return __s;
+ }
+
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ money_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, long double& __units) const
+ {
+ string_type __str;
+ __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(__n));
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ const _CharT* __wcs = __str.c_str();
+ __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);
+ __convert_to_v(__cs, __units, __err, _S_c_locale);
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ money_get<_CharT, _InIter>::
+ do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
+ ios_base::iostate& __err, string_type& __units) const
+ {
+ // These contortions are quite unfortunate.
+ typedef moneypunct<_CharT, true> __money_true;
+ typedef moneypunct<_CharT, false> __money_false;
+ typedef money_base::part part;
+ typedef typename string_type::size_type size_type;
+
+ const locale __loc = __io.getloc();
+ const __money_true& __mpt = use_facet<__money_true>(__loc);
+ const __money_false& __mpf = use_facet<__money_false>(__loc);
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+
+ const money_base::pattern __p = __intl ? __mpt.neg_format()
+ : __mpf.neg_format();
+
+ const string_type __pos_sign =__intl ? __mpt.positive_sign()
+ : __mpf.positive_sign();
+ const string_type __neg_sign =__intl ? __mpt.negative_sign()
+ : __mpf.negative_sign();
+ const char_type __d = __intl ? __mpt.decimal_point()
+ : __mpf.decimal_point();
+ const char_type __sep = __intl ? __mpt.thousands_sep()
+ : __mpf.thousands_sep();
+
+ const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
+
+ // Set to deduced positive or negative sign, depending.
+ string_type __sign;
+ // String of grouping info from thousands_sep plucked from __units.
+ string __grouping_tmp;
+ // Marker for thousands_sep position.
+ int __sep_pos = 0;
+ // If input iterator is in a valid state.
+ bool __testvalid = true;
+ // Flag marking when a decimal point is found.
+ bool __testdecfound = false;
+
+ // The tentative returned string is stored here.
+ string_type __temp_units;
+
+ char_type __c = *__beg;
+ char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
+ for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
+ {
+ part __which = static_cast<part>(__p.field[__i]);
+ switch (__which)
+ {
+ case money_base::symbol:
+ 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.
+ const string_type __symbol = __intl ? __mpt.curr_symbol()
+ : __mpf.curr_symbol();
+ size_type __len = __symbol.size();
+ size_type __j = 0;
+ while (__beg != __end
+ && __j < __len && __symbol[__j] == __c)
+ {
+ __c = *(++__beg);
+ ++__j;
+ }
+ // When (__io.flags() & ios_base::showbase)
+ // symbol is required.
+ if (__j != __len && (__io.flags() & ios_base::showbase))
+ __testvalid = false;
+ }
+ break;
+ case money_base::sign:
+ // Sign might not exist, or be more than one character long.
+ if (__pos_sign.size() && __neg_sign.size())
+ {
+ // Sign is mandatory.
+ if (__c == __pos_sign[0])
+ {
+ __sign = __pos_sign;
+ __c = *(++__beg);
+ }
+ else if (__c == __neg_sign[0])
+ {
+ __sign = __neg_sign;
+ __c = *(++__beg);
+ }
+ else
+ __testvalid = false;
+ }
+ else if (__pos_sign.size() && __c == __pos_sign[0])
+ {
+ __sign = __pos_sign;
+ __c = *(++__beg);
+ }
+ else if (__neg_sign.size() && __c == __neg_sign[0])
+ {
+ __sign = __neg_sign;
+ __c = *(++__beg);
+ }
+ break;
+ case money_base::value:
+ // Extract digits, remove and stash away the
+ // grouping of found thousands separators.
+ while (__beg != __end
+ && (__ctype.is(ctype_base::digit, __c)
+ || (__c == __d && !__testdecfound)
+ || __c == __sep))
+ {
+ if (__c == __d)
+ {
+ __grouping_tmp += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ __testdecfound = true;
+ }
+ else if (__c == __sep)
+ {
+ if (__grouping.size())
+ {
+ // Mark position for later analysis.
+ __grouping_tmp += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ }
+ else
+ {
+ __testvalid = false;
+ break;
+ }
+ }
+ else
+ {
+ __temp_units += __c;
+ ++__sep_pos;
+ }
+ __c = *(++__beg);
+ }
+ break;
+ case money_base::space:
+ case money_base::none:
+ // Only if not at the end of the pattern.
+ if (__i != 3)
+ while (__beg != __end
+ && __ctype.is(ctype_base::space, __c))
+ __c = *(++__beg);
+ break;
+ }
+ }
+
+ // Need to get the rest of the sign characters, if they exist.
+ if (__sign.size() > 1)
+ {
+ size_type __len = __sign.size();
+ size_type __i = 1;
+ for (; __c != __eof && __i < __len; ++__i)
+ while (__beg != __end && __c != __sign[__i])
+ __c = *(++__beg);
+
+ if (__i != __len)
+ __testvalid = false;
+ }
+
+ // Strip leading zeros.
+ while (__temp_units[0] == __ctype.widen('0'))
+ __temp_units.erase(__temp_units.begin());
+
+ if (__sign.size() && __sign == __neg_sign)
+ __temp_units.insert(__temp_units.begin(), __ctype.widen('-'));
+
+ // Test for grouping fidelity.
+ if (__grouping.size() && __grouping_tmp.size())
+ {
+ if (!__verify_grouping(__grouping, __grouping_tmp))
+ __testvalid = false;
+ }
+
+ // Iff no more characters are available.
+ if (__c == __eof)
+ __err |= ios_base::eofbit;
+
+ // Iff valid sequence is not recognized.
+ if (!__testvalid || !__temp_units.size())
+ __err |= ios_base::failbit;
+ else
+ // Use the "swap trick" to copy __temp_units into __units.
+ __temp_units.swap(__units);
+
+ return __beg;
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ money_put<_CharT, _OutIter>::
+ do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ long double __units) const
+ {
+ const locale __loc = __io.getloc();
+ 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);
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ money_put<_CharT, _OutIter>::
+ do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
+ const string_type& __digits) const
+ {
+ typedef typename string_type::size_type size_type;
+ typedef money_base::part part;
+
+ const locale __loc = __io.getloc();
+ const size_type __width = static_cast<size_type>(__io.width());
+
+ // These contortions are quite unfortunate.
+ typedef moneypunct<_CharT, true> __money_true;
+ typedef moneypunct<_CharT, false> __money_false;
+ const __money_true& __mpt = use_facet<__money_true>(__loc);
+ const __money_false& __mpf = use_facet<__money_false>(__loc);
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+
+ // Determine if negative or positive formats are to be used, and
+ // discard leading negative_sign if it is present.
+ const char_type* __beg = __digits.data();
+ const char_type* __end = __beg + __digits.size();
+ money_base::pattern __p;
+ string_type __sign;
+ if (*__beg != __ctype.widen('-'))
+ {
+ __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
+ __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
+ }
+ else
+ {
+ __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
+ __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
+ ++__beg;
+ }
+
+ // Look for valid numbers in the current ctype facet within input digits.
+ __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
+ if (__beg != __end)
+ {
+ // Assume valid input, and attempt to format.
+ // Break down input numbers into base components, as follows:
+ // final_value = grouped units + (decimal point) + (digits)
+ string_type __res;
+ string_type __value;
+ const string_type __symbol = __intl ? __mpt.curr_symbol()
+ : __mpf.curr_symbol();
+
+ // Deal with decimal point, decimal digits.
+ const int __frac = __intl ? __mpt.frac_digits()
+ : __mpf.frac_digits();
+ if (__frac > 0)
+ {
+ const char_type __d = __intl ? __mpt.decimal_point()
+ : __mpf.decimal_point();
+ if (__end - __beg >= __frac)
+ {
+ __value = string_type(__end - __frac, __end);
+ __value.insert(__value.begin(), __d);
+ __end -= __frac;
+ }
+ else
+ {
+ // Have to pad zeros in the decimal position.
+ __value = string_type(__beg, __end);
+ int __paddec = __frac - (__end - __beg);
+ char_type __zero = __ctype.widen('0');
+ __value.insert(__value.begin(), __paddec, __zero);
+ __value.insert(__value.begin(), __d);
+ __beg = __end;
+ }
+ }
+
+ // Add thousands separators to non-decimal digits, per
+ // grouping rules.
+ if (__beg != __end)
+ {
+ const string __grouping = __intl ? __mpt.grouping()
+ : __mpf.grouping();
+ if (__grouping.size())
+ {
+ const char_type __sep = __intl ? __mpt.thousands_sep()
+ : __mpf.thousands_sep();
+ const char* __gbeg = __grouping.c_str();
+ const char* __gend = __gbeg + __grouping.size();
+ 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);
+ }
+ else
+ __value.insert(0, string_type(__beg, __end));
+ }
+
+ // Calculate length of resulting string.
+ ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
+ size_type __len = __value.size() + __sign.size();
+ __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
+ bool __testipad = __f == ios_base::internal && __len < __width;
+
+ // Fit formatted digits into the required pattern.
+ for (int __i = 0; __i < 4; ++__i)
+ {
+ part __which = static_cast<part>(__p.field[__i]);
+ switch (__which)
+ {
+ case money_base::symbol:
+ if (__io.flags() & ios_base::showbase)
+ __res += __symbol;
+ break;
+ case money_base::sign:
+ // Sign might not exist, or be more than one
+ // charater long. In that case, add in the rest
+ // below.
+ if (__sign.size())
+ __res += __sign[0];
+ break;
+ case money_base::value:
+ __res += __value;
+ break;
+ case money_base::space:
+ // At least one space is required, but if internal
+ // formatting is required, an arbitrary number of
+ // fill spaces will be necessary.
+ if (__testipad)
+ __res += string_type(__width - __len, __fill);
+ else
+ __res += __ctype.widen(__fill);
+ break;
+ case money_base::none:
+ if (__testipad)
+ __res += string_type(__width - __len, __fill);
+ break;
+ }
+ }
+
+ // Special case of multi-part sign parts.
+ if (__sign.size() > 1)
+ __res += string_type(__sign.begin() + 1, __sign.end());
+
+ // Pad, if still necessary.
+ __len = __res.size();
+ if (__width > __len)
+ {
+ if (__f == ios_base::left)
+ // After.
+ __res.append(__width - __len, __fill);
+ else
+ // Before.
+ __res.insert(0, string_type(__width - __len, __fill));
+ __len = __width;
+ }
+
+ // Write resulting, fully-formatted string to output iterator.
+ for (size_type __j = 0; __j < __len; ++__j, ++__s)
+ *__s = __res[__j];
+ }
+ __io.width(0);
+ return __s;
+ }
+
+
+ // NB: Not especially useful. Without an ios_base object or some
+ // kind of locale reference, we are left clawing at the air where
+ // the side of the mountain used to be...
+ template<typename _CharT, typename _InIter>
+ time_base::dateorder
+ time_get<_CharT, _InIter>::do_date_order() const
+ { return time_base::no_order; }
+
+ template<typename _CharT, typename _InIter>
+ void
+ time_get<_CharT, _InIter>::
+ _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm,
+ const _CharT* __format) const
+ {
+ locale __loc = __io.getloc();
+ __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ size_t __len = char_traits<_CharT>::length(__format);
+
+ for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
+ {
+ char __c = __format[__i];
+ if (__c == '%')
+ {
+ // Verify valid formatting code, attempt to extract.
+ __c = __format[++__i];
+ char __mod = 0;
+ int __mem = 0;
+ if (__c == 'E' || __c == 'O')
+ {
+ __mod = __c;
+ __c = __format[++__i];
+ }
+ switch (__c)
+ {
+ const char* __cs;
+ _CharT __wcs[10];
+ case 'a':
+ // Abbreviated weekday name [tm_wday]
+ const char_type* __days1[7];
+ __tp._M_days_abbreviated(__days1);
+ _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7,
+ __err);
+ break;
+ case 'A':
+ // Weekday name [tm_wday].
+ const char_type* __days2[7];
+ __tp._M_days(__days2);
+ _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7,
+ __err);
+ break;
+ case 'h':
+ case 'b':
+ // Abbreviated month name [tm_mon]
+ const char_type* __months1[12];
+ __tp._M_months_abbreviated(__months1);
+ _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12,
+ __err);
+ break;
+ case 'B':
+ // Month name [tm_mon].
+ const char_type* __months2[12];
+ __tp._M_months(__months2);
+ _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12,
+ __err);
+ break;
+ case 'c':
+ // Default time and date representation.
+ const char_type* __dt[2];
+ __tp._M_date_time_formats(__dt);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm,
+ __dt[0]);
+ break;
+ case 'd':
+ // Day [01, 31]. [tm_mday]
+ _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
+ __ctype, __err);
+ break;
+ case 'D':
+ // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
+ __cs = "%m/%d/%y";
+ __ctype.widen(__cs, __cs + 9, __wcs);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm,
+ __wcs);
+ break;
+ case 'H':
+ // Hour [00, 23]. [tm_hour]
+ _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
+ __ctype, __err);
+ break;
+ case 'I':
+ // Hour [01, 12]. [tm_hour]
+ _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
+ __ctype, __err);
+ break;
+ case 'm':
+ // Month [01, 12]. [tm_mon]
+ _M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype,
+ __err);
+ if (!__err)
+ __tm->tm_mon = __mem - 1;
+ break;
+ case 'M':
+ // Minute [00, 59]. [tm_min]
+ _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
+ __ctype, __err);
+ break;
+ case 'n':
+ if (__ctype.narrow(*__beg, 0) == '\n')
+ ++__beg;
+ else
+ __err |= ios_base::failbit;
+ break;
+ case 'R':
+ // Equivalent to (%H:%M).
+ __cs = "%H:%M";
+ __ctype.widen(__cs, __cs + 6, __wcs);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm,
+ __wcs);
+ break;
+ case 'S':
+ // Seconds.
+ _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
+ __ctype, __err);
+ break;
+ case 't':
+ if (__ctype.narrow(*__beg, 0) == '\t')
+ ++__beg;
+ else
+ __err |= ios_base::failbit;
+ break;
+ case 'T':
+ // Equivalent to (%H:%M:%S).
+ __cs = "%H:%M:%S";
+ __ctype.widen(__cs, __cs + 9, __wcs);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm,
+ __wcs);
+ break;
+ case 'x':
+ // Locale's date.
+ const char_type* __dates[2];
+ __tp._M_date_formats(__dates);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm,
+ __dates[0]);
+ break;
+ case 'X':
+ // Locale's time.
+ const char_type* __times[2];
+ __tp._M_time_formats(__times);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm,
+ __times[0]);
+ break;
+ case 'y':
+ // Two digit year. [tm_year]
+ _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
+ __ctype, __err);
+ break;
+ case 'Y':
+ // Year [1900). [tm_year]
+ _M_extract_num(__beg, __end, __mem, 0,
+ numeric_limits<int>::max(), 4,
+ __ctype, __err);
+ if (!__err)
+ __tm->tm_year = __mem - 1900;
+ break;
+ case 'Z':
+ // Timezone info.
+ if (__ctype.is(ctype_base::upper, *__beg))
+ {
+ int __tmp;
+ _M_extract_name(__beg, __end, __tmp,
+ __timepunct<_CharT>::_S_timezones,
+ 14, __err);
+
+ // GMT requires special effort.
+ char_type __c = *__beg;
+ if (!__err && __tmp == 0
+ && (__c == __ctype.widen('-')
+ || __c == __ctype.widen('+')))
+ {
+ _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
+ __ctype, __err);
+ _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
+ __ctype, __err);
+ }
+ }
+ else
+ __err |= ios_base::failbit;
+ break;
+ default:
+ // Not recognized.
+ __err |= ios_base::failbit;
+ }
+ }
+ else
+ {
+ // Verify format and input match, extract and discard.
+ if (__c == __ctype.narrow(*__beg, 0))
+ ++__beg;
+ else
+ __err |= ios_base::failbit;
+ }
+ }
+ }
+
+ template<typename _CharT, typename _InIter>
+ void
+ time_get<_CharT, _InIter>::
+ _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
+ int __min, int __max, size_t __len,
+ const ctype<_CharT>& __ctype,
+ ios_base::iostate& __err) const
+ {
+ size_t __i = 0;
+ string __digits;
+ bool __testvalid = true;
+ char_type __c = *__beg;
+ while (__beg != __end && __i < __len
+ && __ctype.is(ctype_base::digit, __c))
+ {
+ __digits += __ctype.narrow(__c, 0);
+ __c = *(++__beg);
+ ++__i;
+ }
+ if (__i == __len)
+ {
+ int __value = atoi(__digits.c_str());
+ if (__min <= __value && __value <= __max)
+ __member = __value;
+ else
+ __testvalid = false;
+ }
+ else
+ __testvalid = false;
+ if (!__testvalid)
+ __err |= ios_base::failbit;
+ }
+
+ // Assumptions:
+ // All elements in __names are unique.
+ template<typename _CharT, typename _InIter>
+ void
+ time_get<_CharT, _InIter>::
+ _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
+ const _CharT** __names, size_t __indexlen,
+ ios_base::iostate& __err) const
+ {
+ typedef char_traits<char_type> __traits_type;
+ int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
+ size_t __nmatches = 0;
+ size_t __pos = 0;
+ bool __testvalid = true;
+ const char_type* __name;
+
+ char_type __c = *__beg;
+ // Look for initial matches.
+ for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
+ if (__c == __names[__i1][0])
+ __matches[__nmatches++] = __i1;
+
+ while(__nmatches > 1)
+ {
+ // Find smallest matching string.
+ size_t __minlen = 10;
+ for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
+ __minlen = min(__minlen,
+ __traits_type::length(__names[__matches[__i2]]));
+
+ if (__pos < __minlen && __beg != __end)
+ {
+ ++__pos;
+ __c = *(++__beg);
+ for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
+ {
+ __name = __names[__matches[__i3]];
+ if (__name[__pos] != __c)
+ __matches[__i3] = __matches[--__nmatches];
+ }
+ }
+ else
+ break;
+ }
+
+ if (__nmatches == 1)
+ {
+ // Make sure found name is completely extracted.
+ __name = __names[__matches[0]];
+ const size_t __len = __traits_type::length(__name);
+ while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
+ ++__beg, ++__pos;
+
+ if (__len == __pos)
+ __member = __matches[0];
+ else
+ __testvalid = false;
+ }
+ else
+ __testvalid = false;
+ if (!__testvalid)
+ __err |= ios_base::failbit;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ time_get<_CharT, _InIter>::
+ do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ {
+ _CharT __wcs[3];
+ const char* __cs = "%X";
+ locale __loc = __io.getloc();
+ ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
+ __ctype.widen(__cs, __cs + 3, __wcs);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ time_get<_CharT, _InIter>::
+ do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ {
+ _CharT __wcs[3];
+ const char* __cs = "%x";
+ locale __loc = __io.getloc();
+ ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
+ __ctype.widen(__cs, __cs + 3, __wcs);
+ _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ time_get<_CharT, _InIter>::
+ 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;
+ locale __loc = __io.getloc();
+ __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
+ const char_type* __days[7];
+ __tp._M_days_abbreviated(__days);
+ int __tmpwday;
+ _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
+
+ // Check to see if non-abbreviated name exists, and extract.
+ // NB: Assumes both _M_days and _M_days_abbreviated organized in
+ // exact same order, first to last, such that the resulting
+ // __days array with the same index points to a day, and that
+ // day's abbreviated form.
+ // NB: Also assumes that an abbreviated name is a subset of the name.
+ if (!__err)
+ {
+ size_t __pos = __traits_type::length(__days[__tmpwday]);
+ __tp._M_days(__days);
+ const char_type* __name = __days[__tmpwday];
+ if (__name[__pos] == *__beg)
+ {
+ // Extract the rest of it.
+ const size_t __len = __traits_type::length(__name);
+ while (__pos < __len && __beg != __end
+ && __name[__pos] == *__beg)
+ ++__beg, ++__pos;
+ if (__len != __pos)
+ __err |= ios_base::failbit;
+ }
+ if (!__err)
+ __tm->tm_wday = __tmpwday;
+ }
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ time_get<_CharT, _InIter>::
+ 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;
+ locale __loc = __io.getloc();
+ __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
+ const char_type* __months[12];
+ __tp._M_months_abbreviated(__months);
+ int __tmpmon;
+ _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
+
+ // Check to see if non-abbreviated name exists, and extract.
+ // NB: Assumes both _M_months and _M_months_abbreviated organized in
+ // exact same order, first to last, such that the resulting
+ // __months array with the same index points to a month, and that
+ // month's abbreviated form.
+ // NB: Also assumes that an abbreviated name is a subset of the name.
+ if (!__err)
+ {
+ size_t __pos = __traits_type::length(__months[__tmpmon]);
+ __tp._M_months(__months);
+ const char_type* __name = __months[__tmpmon];
+ if (__name[__pos] == *__beg)
+ {
+ // Extract the rest of it.
+ const size_t __len = __traits_type::length(__name);
+ while (__pos < __len && __beg != __end
+ && __name[__pos] == *__beg)
+ ++__beg, ++__pos;
+ if (__len != __pos)
+ __err |= ios_base::failbit;
+ }
+ if (!__err)
+ __tm->tm_mon = __tmpmon;
+ }
+
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return __beg;
+ }
+
+ template<typename _CharT, typename _InIter>
+ _InIter
+ time_get<_CharT, _InIter>::
+ do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, tm* __tm) const
+ {
+ locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+
+ char_type __c = *__beg;
+ size_t __i = 0;
+ string __digits;
+ while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
+ {
+ __digits += __ctype.narrow(__c, 0);
+ __c = *(++__beg);
+ ++__i;
+ }
+ if (__i == 2 || __i == 4)
+ {
+ long __l;
+ __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale);
+ if (!(__err & ios_base::failbit) && __l <= INT_MAX)
+ {
+ __l = __i == 2 ? __l : __l - 1900;
+ __tm->tm_year = static_cast<int>(__l);
+ }
+ }
+ else
+ __err |= ios_base::failbit;
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return __beg;
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ time_put<_CharT, _OutIter>::
+ put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
+ const _CharT* __beg, const _CharT* __end) const
+ {
+ locale __loc = __io.getloc();
+ ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
+ while (__beg != __end)
+ {
+ char __c = __ctype.narrow(*__beg, 0);
+ ++__beg;
+ if (__c == '%')
+ {
+ char __format;
+ char __mod = 0;
+ size_t __len = 1;
+ __c = __ctype.narrow(*__beg, 0);
+ ++__beg;
+ if (__c == 'E' || __c == 'O')
+ {
+ __mod = __c;
+ __format = __ctype.narrow(*__beg, 0);
+ ++__beg;
+ }
+ else
+ __format = __c;
+ __s = this->do_put(__s, __io, char_type(), __tm, __format,
+ __mod);
+ }
+ else
+ {
+ *__s = __c;
+ ++__s;
+ }
+ }
+ return __s;
+ }
+
+ template<typename _CharT, typename _OutIter>
+ _OutIter
+ time_put<_CharT, _OutIter>::
+ do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
+ char __format, char __mod) const
+ {
+ locale __loc = __io.getloc();
+ ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
+ __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
+
+ // 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(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
+ // character. Possibilities include 'E' or 'O' followed by a
+ // format character: if __mod is not the default argument, assume
+ // it's a valid modifier.
+ char_type __fmt[4];
+ __fmt[0] = __ctype.widen('%');
+ if (!__mod)
+ {
+ __fmt[1] = __format;
+ __fmt[2] = char_type();
+ }
+ else
+ {
+ __fmt[1] = __mod;
+ __fmt[2] = __format;
+ __fmt[3] = char_type();
+ }
+
+ __tp._M_put(__res, __maxlen, __fmt, __tm);
+
+ // Write resulting, fully-formatted string to output iterator.
+ size_t __len = char_traits<char_type>::length(__res);
+ for (size_t __i = 0; __i < __len; ++__i, ++__s)
+ *__s = __res[__i];
+ return __s;
+ }
+
+
+ // Generic version does nothing.
+ template<typename _CharT>
+ int
+ collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
+ { return 0; }
+
+ // Generic version does nothing.
+ template<typename _CharT>
+ size_t
+ collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
+ { return 0; }
+
+ template<typename _CharT>
+ int
+ collate<_CharT>::
+ do_compare(const _CharT* __lo1, const _CharT* __hi1,
+ const _CharT* __lo2, const _CharT* __hi2) const
+ {
+ const string_type __one(__lo1, __hi1);
+ const string_type __two(__lo2, __hi2);
+ return _M_compare(__one.c_str(), __two.c_str());
+ }
+
+ template<typename _CharT>
+ typename collate<_CharT>::string_type
+ collate<_CharT>::
+ do_transform(const _CharT* __lo, const _CharT* __hi) const
+ {
+ 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)
+ {
+ __c =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1)));
+ _M_transform(__c, __lo, __res + 1);
+ }
+ return string_type(__c);
+ }
+
+ template<typename _CharT>
+ long
+ collate<_CharT>::
+ do_hash(const _CharT* __lo, const _CharT* __hi) const
+ {
+ unsigned long __val = 0;
+ for (; __lo < __hi; ++__lo)
+ __val = *__lo + ((__val << 7) |
+ (__val >> (numeric_limits<unsigned long>::digits - 7)));
+ return static_cast<long>(__val);
+ }
+
+ // Convert string to numeric value of type _Tv and store results.
+ // NB: This is specialized for all required types, there is no
+ // generic definition.
+ template<typename _Tv>
+ void
+ __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,
+ 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.
+#ifdef _GLIBCPP_USE_C99
+ template<typename _Tv>
+ int
+ __convert_from_v(char* __out, const int __size, const char* __fmt,
+ _Tv __v, const __c_locale&, int __prec = -1)
+ {
+ int __ret;
+ const char* __old = setlocale(LC_ALL, "C");
+ if (__prec >= 0)
+ __ret = snprintf(__out, __size, __fmt, __prec, __v);
+ else
+ __ret = snprintf(__out, __size, __fmt, __v);
+ setlocale(LC_ALL, __old);
+ return __ret;
+ }
+#else
+ template<typename _Tv>
+ int
+ __convert_from_v(char* __out, const int, 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;
+ }
+#endif
+
+ // Construct correctly padded string, as per 22.2.2.2.2
+ // Assumes
+ // __newlen > __oldlen
+ // __news is allocated for __newlen size
+ // Used by both num_put and ostream inserters: if __num,
+ // internal-adjusted objects are padded according to the rules below
+ // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
+ // ones are.
+ 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)
+ {
+ 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);
+
+ char_type* __beg;
+ char_type* __end;
+ size_t __mod = 0;
+ size_t __beglen; //either __plen or __oldlen
+ ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
+
+ if (__adjust == ios_base::left)
+ {
+ // Padding last.
+ __beg = const_cast<char_type*>(__olds);
+ __beglen = __oldlen;
+ __end = __pads;
+ }
+ else if (__adjust == ios_base::internal && __num)
+ {
+ // Pad after the sign, if there is one.
+ // Pad after 0[xX], if there is one.
+ // 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]);
+ if (__testhex)
+ {
+ __news[0] = __olds[0];
+ __news[1] = __olds[1];
+ __mod += 2;
+ __news += 2;
+ __beg = __pads;
+ __beglen = __plen;
+ __end = const_cast<char_type*>(__olds + __mod);
+ }
+ else if (__testsign)
+ {
+ __news[0] = __olds[0] == __plus ? __plus : __minus;
+ ++__mod;
+ ++__news;
+ __beg = __pads;
+ __beglen = __plen;
+ __end = const_cast<char_type*>(__olds + __mod);
+ }
+ else
+ {
+ // Padding first.
+ __beg = __pads;
+ __beglen = __plen;
+ __end = const_cast<char_type*>(__olds);
+ }
+ }
+ else
+ {
+ // Padding first.
+ __beg = __pads;
+ __beglen = __plen;
+ __end = const_cast<char_type*>(__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);
+ }
+
+ // Used by both numeric and monetary facets.
+ // Check to make sure that the __grouping_tmp string constructed in
+ // money_get or num_get matches the canonical grouping for a given
+ // locale.
+ // __grouping_tmp is parsed L to R
+ // 1,222,444 == __grouping_tmp of "/1/3/3"
+ // __grouping is parsed R to L
+ // 1,222,444 == __grouping of "/3" == "/3/3/3"
+ template<typename _CharT>
+ bool
+ __verify_grouping(const basic_string<_CharT>& __grouping,
+ basic_string<_CharT>& __grouping_tmp)
+ {
+ int __i = 0;
+ int __j = 0;
+ const int __len = __grouping.size();
+ const int __n = __grouping_tmp.size();
+ bool __test = true;
+
+ // Parsed number groupings have to match the
+ // numpunct::grouping string exactly, starting at the
+ // right-most point of the parsed sequence of elements ...
+ while (__test && __i < __n - 1)
+ for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
+ __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
+ // ... but the last parsed grouping can be <= numpunct
+ // grouping.
+ __j == __len ? __j = 0 : __j;
+ __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
+ return __test;
+ }
+
+ // Used by both numeric and monetary facets.
+ // Inserts "group separator" characters into an array of characters.
+ // It's recursive, one iteration per group. It moves the characters
+ // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
+ // only with __gbeg != __gend.
+ template<typename _CharT>
+ _CharT*
+ __add_grouping(_CharT* __s, _CharT __sep,
+ const char* __gbeg, const char* __gend,
+ const _CharT* __first, const _CharT* __last)
+ {
+ if (__last - __first > *__gbeg)
+ {
+ __s = __add_grouping(__s, __sep,
+ (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
+ __gend, __first, __last - *__gbeg);
+ __first = __last - *__gbeg;
+ *__s++ = __sep;
+ }
+ do
+ *__s++ = *__first++;
+ while (__first != __last);
+ return __s;
+ }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+ extern template class moneypunct<char, false>;
+ 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>;
+ extern template class money_put<char>;
+ 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>;
+ extern template class money_put<wchar_t>;
+ 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 numpunct<wchar_t>;
+ extern template class numpunct_byname<wchar_t>;
+ extern template class num_get<wchar_t>;
+ extern template class num_put<wchar_t>;
+ 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 __timepunct<wchar_t>;
+ 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<char>;
+ extern template class messages_byname<char>;
+ 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>;
+
+ 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
+ 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<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&);
+
+ 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&);
+} // namespace std
+
+#endif
+
+
diff --git a/contrib/libstdc++/include/bits/localefwd.h b/contrib/libstdc++/include/bits/localefwd.h
new file mode 100644
index 0000000000000..028c4126b85e1
--- /dev/null
+++ b/contrib/libstdc++/include/bits/localefwd.h
@@ -0,0 +1,476 @@
+// Locale support -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 22.1 Locales
+//
+
+/** @file localefwd.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_LOCCORE_H
+#define _CPP_BITS_LOCCORE_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#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 <bits/functexcept.h>
+#include <bits/atomicity.h>
+
+namespace std
+{
+ // 22.1.1 Locale
+ class locale;
+
+ // 22.1.3 Convenience interfaces
+ template<typename _CharT>
+ inline bool
+ isspace(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ isprint(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ iscntrl(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ isupper(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ islower(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ isalpha(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ isdigit(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ ispunct(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ isxdigit(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ isalnum(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline bool
+ isgraph(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline _CharT
+ toupper(_CharT, const locale&);
+
+ template<typename _CharT>
+ inline _CharT
+ tolower(_CharT, const locale&);
+
+
+ // 22.2.1 and 22.2.1.3 ctype
+ class ctype_base;
+ template<typename _CharT>
+ class ctype;
+ template<> class ctype<char>;
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<> class ctype<wchar_t>;
+#endif
+ template<typename _CharT>
+ class ctype_byname;
+ // NB: Specialized for char and wchar_t in locale_facets.h.
+
+ class codecvt_base;
+ class __enc_traits;
+ template<typename _InternT, typename _ExternT, typename _StateT>
+ class codecvt;
+ template<> class codecvt<char, char, mbstate_t>;
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<> class codecvt<wchar_t, char, mbstate_t>;
+#endif
+ template<typename _InternT, typename _ExternT, typename _StateT>
+ class codecvt_byname;
+
+ // 22.2.2 and 22.2.3 numeric
+ template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
+ class num_get;
+ template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
+ class num_put;
+ template<typename _CharT> class numpunct;
+ template<typename _CharT> class numpunct_byname;
+
+ // 22.2.4 collation
+ template<typename _CharT>
+ class collate;
+ template<typename _CharT> class
+ collate_byname;
+
+ // 22.2.5 date and time
+ class time_base;
+ template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
+ class time_get;
+ template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
+ class time_get_byname;
+ template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
+ class time_put;
+ template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
+ class time_put_byname;
+
+ // 22.2.6 money
+ class money_base;
+ template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
+ class money_get;
+ template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
+ class money_put;
+ template<typename _CharT, bool _Intl = false>
+ class moneypunct;
+ template<typename _CharT, bool _Intl = false>
+ class moneypunct_byname;
+
+ // 22.2.7 message retrieval
+ class messages_base;
+ template<typename _CharT>
+ class messages;
+ template<typename _CharT>
+ class messages_byname;
+
+ // 22.1.1 Class locale
+ class locale
+ {
+ public:
+ // Types:
+ typedef unsigned int category;
+
+ // Forward decls and friends:
+ class facet;
+ class id;
+ class _Impl;
+
+ friend class facet;
+ friend class _Impl;
+
+ template<typename _Facet>
+ friend const _Facet&
+ use_facet(const locale&);
+
+ template<typename _Facet>
+ friend bool
+ has_facet(const locale&) throw();
+
+ // Category values:
+ // NB: Order must match _S_facet_categories definition in locale.cc
+ static const category none = 0;
+ static const category ctype = 1L << 0;
+ static const category numeric = 1L << 1;
+ static const category collate = 1L << 2;
+ 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);
+
+ // Construct/copy/destroy:
+ locale() throw();
+
+ locale(const locale& __other) throw();
+
+ explicit
+ locale(const char* __s);
+
+ locale(const locale& __base, const char* __s, category __cat);
+
+ locale(const locale& __base, const locale& __add, category __cat);
+
+ template<typename _Facet>
+ locale(const locale& __other, _Facet* __f);
+
+ ~locale() throw();
+
+ const locale&
+ operator=(const locale& __other) throw();
+
+ template<typename _Facet>
+ locale
+ combine(const locale& __other) const;
+
+ // Locale operations:
+ string
+ name() const;
+
+ bool
+ operator==(const locale& __other) const throw ();
+
+ inline bool
+ operator!=(const locale& __other) const throw ()
+ { return !(this->operator==(__other)); }
+
+ template<typename _Char, typename _Traits, typename _Alloc>
+ bool
+ operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
+ const basic_string<_Char, _Traits, _Alloc>& __s2) const;
+
+ // Global locale objects:
+ static locale
+ global(const locale&);
+
+ static const locale&
+ classic();
+
+ private:
+ // The (shared) implementation
+ _Impl* _M_impl;
+
+ // The "C" reference locale
+ static _Impl* _S_classic;
+
+ // Current global reference locale
+ static _Impl* _S_global;
+
+ static const size_t _S_num_categories = 6;
+
+ explicit
+ locale(_Impl*) throw();
+
+ static inline void
+ _S_initialize()
+ {
+ if (!_S_classic)
+ classic();
+ }
+
+ static category
+ _S_normalize_category(category);
+
+ void
+ _M_coalesce(const locale& __base, const locale& __add, category __cat);
+ };
+
+
+ // Implementation object for locale
+ class locale::_Impl
+ {
+ public:
+ // Friends.
+ friend class locale;
+ friend class locale::facet;
+
+ template<typename _Facet>
+ friend const _Facet&
+ use_facet(const locale&);
+
+ template<typename _Facet>
+ friend bool
+ has_facet(const locale&) throw();
+
+ private:
+ // Data Members.
+ _Atomic_word _M_references;
+ facet** _M_facets;
+ size_t _M_facets_size;
+ const char* _M_names[_S_num_categories];
+ static const locale::id* const _S_id_ctype[];
+ static const locale::id* const _S_id_numeric[];
+ static const locale::id* const _S_id_collate[];
+ static const locale::id* const _S_id_time[];
+ static const locale::id* const _S_id_monetary[];
+ static const locale::id* const _S_id_messages[];
+ static const locale::id* const* const _S_facet_categories[];
+
+ inline void
+ _M_add_reference() throw()
+ { __atomic_add(&_M_references, 1); }
+
+ inline void
+ _M_remove_reference() throw()
+ {
+ if (__exchange_and_add(&_M_references, -1) == 1)
+ {
+ try
+ { delete this; }
+ catch(...)
+ { }
+ }
+ }
+
+ _Impl(const _Impl&, 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; __ret && i < _S_num_categories - 1; ++i)
+ __ret &= (strcmp(_M_names[i], _M_names[i + 1]) == 0);
+ return __ret;
+ }
+
+ void
+ _M_replace_categories(const _Impl*, category);
+
+ void
+ _M_replace_category(const _Impl*, const locale::id* const*);
+
+ void
+ _M_replace_facet(const _Impl*, const locale::id*);
+
+ void
+ _M_install_facet(const locale::id*, facet*);
+
+ template<typename _Facet>
+ inline void
+ _M_init_facet(_Facet* __facet)
+ { _M_install_facet(&_Facet::id, __facet); }
+ };
+
+ template<typename _Facet>
+ locale::locale(const locale& __other, _Facet* __f)
+ {
+ _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] = "*";
+ }
+
+ // 22.1.1.1.2 Class locale::facet
+ class locale::facet
+ {
+ private:
+ friend class locale;
+ friend class locale::_Impl;
+
+ _Atomic_word _M_references;
+
+ protected:
+ // Contains data from the underlying "C" library for default "C"
+ // or "POSIX" locale.
+ static __c_locale _S_c_locale;
+
+ explicit
+ facet(size_t __refs = 0) throw();
+
+ virtual
+ ~facet();
+
+ static void
+ _S_create_c_locale(__c_locale& __cloc, const char* __s,
+ __c_locale __old = 0);
+
+ static __c_locale
+ _S_clone_c_locale(__c_locale& __cloc);
+
+ static void
+ _S_destroy_c_locale(__c_locale& __cloc);
+
+ private:
+ void
+ _M_add_reference() throw();
+
+ void
+ _M_remove_reference() throw();
+
+ facet(const facet&); // Not defined.
+
+ void
+ operator=(const facet&); // Not defined.
+ };
+
+
+ // 22.1.1.1.3 Class locale::id
+ class locale::id
+ {
+ private:
+ friend class locale;
+ friend class locale::_Impl;
+ template<typename _Facet>
+ friend const _Facet&
+ use_facet(const locale&);
+ template<typename _Facet>
+ friend bool
+ has_facet(const locale&) throw ();
+
+ // NB: There is no accessor for _M_index because it may be used
+ // before the constructor is run; the effect of calling a member
+ // function (even an inline) would be undefined.
+ mutable size_t _M_index;
+
+ // Last id number assigned.
+ static _Atomic_word _S_highwater;
+
+ void
+ operator=(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>
+ const _Facet&
+ use_facet(const locale& __loc);
+
+ template<typename _Facet>
+ bool
+ has_facet(const locale& __loc) throw();
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/mask_array.h b/contrib/libstdc++/include/bits/mask_array.h
new file mode 100644
index 0000000000000..13c01d3cc226e
--- /dev/null
+++ b/contrib/libstdc++/include/bits/mask_array.h
@@ -0,0 +1,167 @@
+// The template and inlines for the -*- C++ -*- mask_array class.
+
+// Copyright (C) 1997-2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+/** @file mask_array.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_MASK_ARRAY_H
+#define _CPP_BITS_MASK_ARRAY_H 1
+
+#pragma GCC system_header
+
+namespace std {
+
+ template <class _Tp> class mask_array
+ {
+ public:
+ typedef _Tp value_type;
+
+ void operator= (const valarray<_Tp>&) const;
+ void operator*= (const valarray<_Tp>&) const;
+ void operator/= (const valarray<_Tp>&) const;
+ void operator%= (const valarray<_Tp>&) const;
+ void operator+= (const valarray<_Tp>&) const;
+ void operator-= (const valarray<_Tp>&) const;
+ void operator^= (const valarray<_Tp>&) const;
+ void operator&= (const valarray<_Tp>&) const;
+ void operator|= (const valarray<_Tp>&) const;
+ void operator<<=(const valarray<_Tp>&) const;
+ void operator>>=(const valarray<_Tp>&) const;
+ void operator= (const _Tp&);
+
+ // ~mask_array ();
+
+ template<class _Dom>
+ void operator= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator*= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator/= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator%= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator+= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator-= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator^= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator&= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator|= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator<<=(const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator>>=(const _Expr<_Dom,_Tp>&) const;
+
+ private:
+ mask_array (_Array<_Tp>, size_t, _Array<bool>);
+ friend class valarray<_Tp>;
+
+ const size_t _M_sz;
+ const _Array<bool> _M_mask;
+ const _Array<_Tp> _M_array;
+
+ mask_array (const mask_array&);
+
+ // not implemented
+ mask_array ();
+ mask_array& operator= (const mask_array&);
+ };
+
+
+ template<typename _Tp>
+ inline mask_array<_Tp>::mask_array (const mask_array<_Tp>& a)
+ : _M_sz (a._M_sz), _M_mask (a._M_mask), _M_array (a._M_array) {}
+
+ template<typename _Tp>
+ inline
+ mask_array<_Tp>::mask_array (_Array<_Tp> __a, size_t __s, _Array<bool> __m)
+ : _M_sz (__s), _M_mask (__m), _M_array (__a) {}
+
+ // template<typename _Tp>
+ // inline mask_array<_Tp>::~mask_array () {}
+
+ template<typename _Tp>
+ inline void
+ mask_array<_Tp>::operator= (const _Tp& __t)
+ { __valarray_fill (_M_array, _M_sz, _M_mask, __t); }
+
+ template<typename _Tp>
+ inline void
+ mask_array<_Tp>::operator= (const valarray<_Tp>& __v) const
+ { __valarray_copy (_Array<_Tp> (__v), __v.size (), _M_array, _M_mask); }
+
+ template<typename _Tp>
+ template<class E>
+ inline void
+ mask_array<_Tp>::operator= (const _Expr<E, _Tp>& __e) const
+ { __valarray_copy (__e, __e.size (), _M_array, _M_mask); }
+
+#undef _DEFINE_VALARRAY_OPERATOR
+#define _DEFINE_VALARRAY_OPERATOR(op, name) \
+template<typename _Tp> \
+inline void \
+mask_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \
+{ \
+ _Array_augmented_##name (_M_array, _M_mask, \
+ _Array<_Tp> (__v), __v.size ()); \
+} \
+ \
+template<typename _Tp> template<class E> \
+inline void \
+mask_array<_Tp>::operator op##= (const _Expr<E, _Tp>& __e) const \
+{ \
+ _Array_augmented_##name (_M_array, _M_mask, __e, __e.size ()); \
+}
+
+_DEFINE_VALARRAY_OPERATOR(*, multiplies)
+_DEFINE_VALARRAY_OPERATOR(/, divides)
+_DEFINE_VALARRAY_OPERATOR(%, modulus)
+_DEFINE_VALARRAY_OPERATOR(+, plus)
+_DEFINE_VALARRAY_OPERATOR(-, minus)
+_DEFINE_VALARRAY_OPERATOR(^, xor)
+_DEFINE_VALARRAY_OPERATOR(&, and)
+_DEFINE_VALARRAY_OPERATOR(|, or)
+_DEFINE_VALARRAY_OPERATOR(<<, shift_left)
+_DEFINE_VALARRAY_OPERATOR(>>, shift_right)
+
+#undef _DEFINE_VALARRAY_OPERATOR
+
+} // std::
+
+#endif /* _CPP_BITS_MASK_ARRAY_H */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/ostream.tcc b/contrib/libstdc++/include/bits/ostream.tcc
new file mode 100644
index 0000000000000..d15b9f2afa3c0
--- /dev/null
+++ b/contrib/libstdc++/include/bits/ostream.tcc
@@ -0,0 +1,704 @@
+// ostream classes -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.6.2 Output streams
+//
+
+#pragma GCC system_header
+
+#include <locale>
+
+namespace std
+{
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>::sentry::
+ sentry(basic_ostream<_CharT,_Traits>& __os)
+ : _M_ok(__os.good()), _M_os(__os)
+ {
+ // XXX MT
+ if (_M_ok && __os.tie())
+ __os.tie()->flush();
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::
+ operator<<(__ostream_type& (*__pf)(__ostream_type&))
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ { __pf(*this); }
+ catch(exception& __fail)
+ {
+ // 27.6.2.5.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::
+ operator<<(__ios_type& (*__pf)(__ios_type&))
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ { __pf(*this); }
+ catch(exception& __fail)
+ {
+ // 27.6.2.5.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::
+ operator<<(ios_base& (*__pf)(ios_base&))
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ { __pf(*this); }
+ catch(exception& __fail)
+ {
+ // 27.6.2.5.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ 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)
+ this->setstate(ios_base::failbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.2.5.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(bool __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ if (_M_check_facet(_M_fnumput))
+ if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
+ this->setstate(ios_base::badbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(long __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ char_type __c = this->fill();
+ ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
+ if (_M_check_facet(_M_fnumput))
+ {
+ bool __b = false;
+ 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();
+ }
+ else
+ __b = _M_fnumput->put(*this, *this, __c, __n).failed();
+ if (__b)
+ this->setstate(ios_base::badbit);
+ }
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ if (_M_check_facet(_M_fnumput))
+ if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
+ this->setstate(ios_base::badbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(long long __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ char_type __c = this->fill();
+ ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
+ if (_M_check_facet(_M_fnumput))
+ {
+ bool __b = false;
+ if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
+ {
+ unsigned long long __l;
+ __l = static_cast<unsigned long long>(__n);
+ __b = _M_fnumput->put(*this, *this, __c, __l).failed();
+ }
+ else
+ __b = _M_fnumput->put(*this, *this, __c, __n).failed();
+ if (__b)
+ this->setstate(ios_base::badbit);
+ }
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ if (_M_check_facet(_M_fnumput))
+ if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
+ this->setstate(ios_base::badbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+#endif
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(double __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ if (_M_check_facet(_M_fnumput))
+ if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
+ this->setstate(ios_base::badbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(long double __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ if (_M_check_facet(_M_fnumput))
+ if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
+ this->setstate(ios_base::badbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ try
+ {
+ if (_M_check_facet(_M_fnumput))
+ if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
+ this->setstate(ios_base::badbit);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // 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;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::put(char_type __c)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ int_type __put = rdbuf()->sputc(__c);
+ if (traits_type::eq_int_type(__put, traits_type::eof()))
+ this->setstate(ios_base::badbit);
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n)
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ streamsize __put = this->rdbuf()->sputn(__s, __n);
+ if ( __put != __n)
+ this->setstate(ios_base::badbit);
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::flush()
+ {
+ sentry __cerb(*this);
+ if (__cerb)
+ {
+ if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
+ this->setstate(ios_base::badbit);
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_ostream<_CharT, _Traits>::pos_type
+ basic_ostream<_CharT, _Traits>::tellp()
+ {
+ pos_type __ret = pos_type(-1);
+ if (!this->fail())
+ __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
+ return __ret;
+ }
+
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
+ {
+ if (!this->fail())
+ {
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 136. seekp, seekg setting wrong streams?
+ pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::out);
+
+// 129. Need error indication from seekp() and seekg()
+ if (__err == pos_type(off_type(-1)))
+ this->setstate(ios_base::failbit);
+#endif
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::
+ seekp(off_type __off, ios_base::seekdir __d)
+ {
+ if (!this->fail())
+ {
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 136. seekp, seekg setting wrong streams?
+ pos_type __err = this->rdbuf()->pubseekoff(__off, __d,
+ ios_base::out);
+
+// 129. Need error indication from seekp() and seekg()
+ if (__err == pos_type(off_type(-1)))
+ this->setstate(ios_base::failbit);
+#endif
+ }
+ return *this;
+ }
+
+ // 27.6.2.5.4 Character inserters.
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
+ {
+ typedef basic_ostream<_CharT, _Traits> __ostream_type;
+ typename __ostream_type::sentry __cerb(__out);
+ if (__cerb)
+ {
+ try
+ {
+ streamsize __w = __out.width();
+ _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);
+ __len = __w;
+ }
+ __out.write(__pads, __len);
+ __out.width(0);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __out.setstate(ios_base::badbit);
+ if ((__out.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
+ }
+ }
+ return __out;
+ }
+
+ // Specializations.
+ template <class _Traits>
+ basic_ostream<char, _Traits>&
+ operator<<(basic_ostream<char, _Traits>& __out, char __c)
+ {
+ typedef basic_ostream<char, _Traits> __ostream_type;
+ typename __ostream_type::sentry __cerb(__out);
+ if (__cerb)
+ {
+ try
+ {
+ streamsize __w = __out.width();
+ char* __pads = static_cast<char*>(__builtin_alloca(__w + 1));
+ __pads[0] = __c;
+ streamsize __len = 1;
+ if (__w > __len)
+ {
+ __pad(__out, __out.fill(), __pads, &__c, __w, __len, false);
+ __len = __w;
+ }
+ __out.write(__pads, __len);
+ __out.width(0);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __out.setstate(ios_base::badbit);
+ if ((__out.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
+ }
+ }
+ return __out;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
+ {
+ typedef basic_ostream<_CharT, _Traits> __ostream_type;
+ typename __ostream_type::sentry __cerb(__out);
+ if (__cerb)
+ {
+ try
+ {
+ streamsize __w = __out.width();
+ _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
+ streamsize __len = static_cast<streamsize>(_Traits::length(__s));
+ if (__w > __len)
+ {
+ __pad(__out, __out.fill(), __pads, __s, __w, __len, false);
+ __s = __pads;
+ __len = __w;
+ }
+ __out.write(__s, __len);
+ __out.width(0);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __out.setstate(ios_base::badbit);
+ if ((__out.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
+ }
+ }
+ return __out;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
+ {
+ typedef basic_ostream<_CharT, _Traits> __ostream_type;
+#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;
+#endif
+ typename __ostream_type::sentry __cerb(__out);
+ if (__cerb)
+ {
+ size_t __clen = __ctraits_type::length(__s);
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__clen + 1)));
+ for (size_t __i = 0; __i <= __clen; ++__i)
+ __ws[__i] = __out.widen(__s[__i]);
+ _CharT* __str = __ws;
+
+ try
+ {
+ streamsize __len = static_cast<streamsize>(__clen);
+ streamsize __w = __out.width();
+ _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
+
+ if (__w > __len)
+ {
+ __pad(__out, __out.fill(), __pads, __ws, __w, __len, false);
+ __str = __pads;
+ __len = __w;
+ }
+ __out.write(__str, __len);
+ __out.width(0);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __out.setstate(ios_base::badbit);
+ if ((__out.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
+ }
+ }
+ return __out;
+ }
+
+ // Partial specializations.
+ template<class _Traits>
+ basic_ostream<char, _Traits>&
+ operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
+ {
+ typedef basic_ostream<char, _Traits> __ostream_type;
+ typename __ostream_type::sentry __cerb(__out);
+ if (__cerb)
+ {
+ 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);
+ __s = __pads;
+ __len = __w;
+ }
+ __out.write(__s, __len);
+ __out.width(0);
+ }
+ catch(exception& __fail)
+ {
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __out.setstate(ios_base::badbit);
+ if ((__out.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
+ }
+ }
+ return __out;
+ }
+
+ // 21.3.7.9 basic_string::operator<<
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __out,
+ const basic_string<_CharT, _Traits, _Alloc>& __str)
+ {
+ typedef basic_ostream<_CharT, _Traits> __ostream_type;
+ typename __ostream_type::sentry __cerb(__out);
+ if (__cerb)
+ {
+ const _CharT* __s = __str.data();
+ streamsize __w = __out.width();
+ _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
+ streamsize __len = static_cast<streamsize>(__str.size());
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // 25. String operator<< uses width() value wrong
+#endif
+ if (__w > __len)
+ {
+ __pad(__out, __out.fill(), __pads, __s, __w, __len, false);
+ __s = __pads;
+ __len = __w;
+ }
+ streamsize __res = __out.rdbuf()->sputn(__s, __len);
+ __out.width(0);
+ if (__res != __len)
+ __out.setstate(ios_base::failbit);
+ }
+ return __out;
+ }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+ extern template class basic_ostream<char>;
+ extern template ostream& endl(ostream&);
+ extern template ostream& ends(ostream&);
+ extern template ostream& flush(ostream&);
+ extern template ostream& operator<<(ostream&, char);
+ extern template ostream& operator<<(ostream&, unsigned char);
+ extern template ostream& operator<<(ostream&, signed char);
+ extern template ostream& operator<<(ostream&, const char*);
+ extern template ostream& operator<<(ostream&, const unsigned char*);
+ extern template ostream& operator<<(ostream&, const signed char*);
+
+ extern template class basic_ostream<wchar_t>;
+ extern template wostream& endl(wostream&);
+ extern template wostream& ends(wostream&);
+ extern template wostream& flush(wostream&);
+ extern template wostream& operator<<(wostream&, wchar_t);
+ extern template wostream& operator<<(wostream&, char);
+ extern template wostream& operator<<(wostream&, const wchar_t*);
+ extern template wostream& operator<<(wostream&, const char*);
+} // namespace std
diff --git a/contrib/libstdc++/include/bits/pthread_allocimpl.h b/contrib/libstdc++/include/bits/pthread_allocimpl.h
new file mode 100644
index 0000000000000..050b2060fc459
--- /dev/null
+++ b/contrib/libstdc++/include/bits/pthread_allocimpl.h
@@ -0,0 +1,525 @@
+// POSIX thread-related memory allocation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file pthread_allocimpl.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_PTHREAD_ALLOCIMPL_H
+#define _CPP_BITS_PTHREAD_ALLOCIMPL_H 1
+
+// Pthread-specific node allocator.
+// This is similar to the default allocator, except that free-list
+// information is kept separately for each thread, avoiding locking.
+// This should be reasonably fast even in the presence of threads.
+// The down side is that storage may not be well-utilized.
+// It is not an error to allocate memory in thread A and deallocate
+// it in thread B. But this effectively transfers ownership of the memory,
+// so that it can only be reallocated by thread B. Thus this can effectively
+// result in a storage leak if it's done on a regular basis.
+// It can also result in frequent sharing of
+// cache lines among processors, with potentially serious performance
+// consequences.
+
+#include <bits/c++config.h>
+#include <cerrno>
+#include <bits/stl_alloc.h>
+#ifndef __RESTRICT
+# define __RESTRICT
+#endif
+
+#include <new>
+
+namespace std
+{
+
+#define __STL_DATA_ALIGNMENT 8
+
+union _Pthread_alloc_obj {
+ union _Pthread_alloc_obj * __free_list_link;
+ char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */
+};
+
+// Pthread allocators don't appear to the client to have meaningful
+// instances. We do in fact need to associate some state with each
+// thread. That state is represented by
+// _Pthread_alloc_per_thread_state<_Max_size>.
+
+template<size_t _Max_size>
+struct _Pthread_alloc_per_thread_state {
+ typedef _Pthread_alloc_obj __obj;
+ enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT };
+ _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS];
+ _Pthread_alloc_per_thread_state<_Max_size> * __next;
+ // Free list link for list of available per thread structures.
+ // When one of these becomes available for reuse due to thread
+ // termination, any objects in its free list remain associated
+ // with it. The whole structure may then be used by a newly
+ // created thread.
+ _Pthread_alloc_per_thread_state() : __next(0)
+ {
+ memset((void *)__free_list, 0, (size_t) _S_NFREELISTS * sizeof(__obj *));
+ }
+ // Returns an object of size __n, and possibly adds to size n free list.
+ void *_M_refill(size_t __n);
+};
+
+// Pthread-specific allocator.
+// The argument specifies the largest object size allocated from per-thread
+// free lists. Larger objects are allocated using malloc_alloc.
+// Max_size must be a power of 2.
+template <size_t _Max_size = 128>
+class _Pthread_alloc_template {
+
+public: // but only for internal use:
+
+ typedef _Pthread_alloc_obj __obj;
+
+ // Allocates a chunk for nobjs of size size. nobjs may be reduced
+ // if it is inconvenient to allocate the requested number.
+ static char *_S_chunk_alloc(size_t __size, int &__nobjs);
+
+ enum {_S_ALIGN = __STL_DATA_ALIGNMENT};
+
+ static size_t _S_round_up(size_t __bytes) {
+ return (((__bytes) + (int) _S_ALIGN-1) & ~((int) _S_ALIGN - 1));
+ }
+ static size_t _S_freelist_index(size_t __bytes) {
+ return (((__bytes) + (int) _S_ALIGN-1)/(int)_S_ALIGN - 1);
+ }
+
+private:
+ // Chunk allocation state. And other shared state.
+ // Protected by _S_chunk_allocator_lock.
+ static pthread_mutex_t _S_chunk_allocator_lock;
+ static char *_S_start_free;
+ static char *_S_end_free;
+ static size_t _S_heap_size;
+ static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states;
+ static pthread_key_t _S_key;
+ static bool _S_key_initialized;
+ // Pthread key under which per thread state is stored.
+ // Allocator instances that are currently unclaimed by any thread.
+ static void _S_destructor(void *instance);
+ // Function to be called on thread exit to reclaim per thread
+ // state.
+ static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state();
+ // Return a recycled or new per thread state.
+ static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state();
+ // ensure that the current thread has an associated
+ // per thread state.
+ class _M_lock;
+ friend class _M_lock;
+ class _M_lock {
+ public:
+ _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); }
+ ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); }
+ };
+
+public:
+
+ /* n must be > 0 */
+ static void * allocate(size_t __n)
+ {
+ __obj * volatile * __my_free_list;
+ __obj * __RESTRICT __result;
+ _Pthread_alloc_per_thread_state<_Max_size>* __a;
+
+ if (__n > _Max_size) {
+ return(malloc_alloc::allocate(__n));
+ }
+ if (!_S_key_initialized ||
+ !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*)
+ pthread_getspecific(_S_key))) {
+ __a = _S_get_per_thread_state();
+ }
+ __my_free_list = __a -> __free_list + _S_freelist_index(__n);
+ __result = *__my_free_list;
+ if (__result == 0) {
+ void *__r = __a -> _M_refill(_S_round_up(__n));
+ return __r;
+ }
+ *__my_free_list = __result -> __free_list_link;
+ return (__result);
+ };
+
+ /* p may not be 0 */
+ static void deallocate(void *__p, size_t __n)
+ {
+ __obj *__q = (__obj *)__p;
+ __obj * volatile * __my_free_list;
+ _Pthread_alloc_per_thread_state<_Max_size>* __a;
+
+ if (__n > _Max_size) {
+ malloc_alloc::deallocate(__p, __n);
+ return;
+ }
+ if (!_S_key_initialized ||
+ !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *)
+ pthread_getspecific(_S_key))) {
+ __a = _S_get_per_thread_state();
+ }
+ __my_free_list = __a->__free_list + _S_freelist_index(__n);
+ __q -> __free_list_link = *__my_free_list;
+ *__my_free_list = __q;
+ }
+
+ static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz);
+
+} ;
+
+typedef _Pthread_alloc_template<> pthread_alloc;
+
+
+template <size_t _Max_size>
+void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance)
+{
+ _M_lock __lock_instance; // Need to acquire lock here.
+ _Pthread_alloc_per_thread_state<_Max_size>* __s =
+ (_Pthread_alloc_per_thread_state<_Max_size> *)__instance;
+ __s -> __next = _S_free_per_thread_states;
+ _S_free_per_thread_states = __s;
+}
+
+template <size_t _Max_size>
+_Pthread_alloc_per_thread_state<_Max_size> *
+_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state()
+{
+ /* lock already held here. */
+ if (0 != _S_free_per_thread_states) {
+ _Pthread_alloc_per_thread_state<_Max_size> *__result =
+ _S_free_per_thread_states;
+ _S_free_per_thread_states = _S_free_per_thread_states -> __next;
+ return __result;
+ } else {
+ return new _Pthread_alloc_per_thread_state<_Max_size>;
+ }
+}
+
+template <size_t _Max_size>
+_Pthread_alloc_per_thread_state<_Max_size> *
+_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state()
+{
+ /*REFERENCED*/
+ _M_lock __lock_instance; // Need to acquire lock here.
+ int __ret_code;
+ _Pthread_alloc_per_thread_state<_Max_size> * __result;
+ if (!_S_key_initialized) {
+ if (pthread_key_create(&_S_key, _S_destructor)) {
+ std::__throw_bad_alloc(); // defined in funcexcept.h
+ }
+ _S_key_initialized = true;
+ }
+ __result = _S_new_per_thread_state();
+ __ret_code = pthread_setspecific(_S_key, __result);
+ if (__ret_code) {
+ if (__ret_code == ENOMEM) {
+ std::__throw_bad_alloc();
+ } else {
+ // EINVAL
+ abort();
+ }
+ }
+ return __result;
+}
+
+/* We allocate memory in large chunks in order to avoid fragmenting */
+/* the malloc heap too much. */
+/* We assume that size is properly aligned. */
+template <size_t _Max_size>
+char *_Pthread_alloc_template<_Max_size>
+::_S_chunk_alloc(size_t __size, int &__nobjs)
+{
+ {
+ char * __result;
+ size_t __total_bytes;
+ size_t __bytes_left;
+ /*REFERENCED*/
+ _M_lock __lock_instance; // Acquire lock for this routine
+
+ __total_bytes = __size * __nobjs;
+ __bytes_left = _S_end_free - _S_start_free;
+ if (__bytes_left >= __total_bytes) {
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return(__result);
+ } else if (__bytes_left >= __size) {
+ __nobjs = __bytes_left/__size;
+ __total_bytes = __size * __nobjs;
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return(__result);
+ } else {
+ size_t __bytes_to_get =
+ 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
+ // Try to make use of the left-over piece.
+ if (__bytes_left > 0) {
+ _Pthread_alloc_per_thread_state<_Max_size>* __a =
+ (_Pthread_alloc_per_thread_state<_Max_size>*)
+ pthread_getspecific(_S_key);
+ __obj * volatile * __my_free_list =
+ __a->__free_list + _S_freelist_index(__bytes_left);
+
+ ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list;
+ *__my_free_list = (__obj *)_S_start_free;
+ }
+# ifdef _SGI_SOURCE
+ // Try to get memory that's aligned on something like a
+ // cache line boundary, so as to avoid parceling out
+ // parts of the same line to different threads and thus
+ // possibly different processors.
+ {
+ const int __cache_line_size = 128; // probable upper bound
+ __bytes_to_get &= ~(__cache_line_size-1);
+ _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get);
+ if (0 == _S_start_free) {
+ _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
+ }
+ }
+# else /* !SGI_SOURCE */
+ _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
+# endif
+ _S_heap_size += __bytes_to_get;
+ _S_end_free = _S_start_free + __bytes_to_get;
+ }
+ }
+ // lock is released here
+ return(_S_chunk_alloc(__size, __nobjs));
+}
+
+
+/* Returns an object of size n, and optionally adds to size n free list.*/
+/* We assume that n is properly aligned. */
+/* We hold the allocation lock. */
+template <size_t _Max_size>
+void *_Pthread_alloc_per_thread_state<_Max_size>
+::_M_refill(size_t __n)
+{
+ int __nobjs = 128;
+ char * __chunk =
+ _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs);
+ __obj * volatile * __my_free_list;
+ __obj * __result;
+ __obj * __current_obj, * __next_obj;
+ int __i;
+
+ if (1 == __nobjs) {
+ return(__chunk);
+ }
+ __my_free_list = __free_list
+ + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n);
+
+ /* Build free list in chunk */
+ __result = (__obj *)__chunk;
+ *__my_free_list = __next_obj = (__obj *)(__chunk + __n);
+ for (__i = 1; ; __i++) {
+ __current_obj = __next_obj;
+ __next_obj = (__obj *)((char *)__next_obj + __n);
+ if (__nobjs - 1 == __i) {
+ __current_obj -> __free_list_link = 0;
+ break;
+ } else {
+ __current_obj -> __free_list_link = __next_obj;
+ }
+ }
+ return(__result);
+}
+
+template <size_t _Max_size>
+void *_Pthread_alloc_template<_Max_size>
+::reallocate(void *__p, size_t __old_sz, size_t __new_sz)
+{
+ void * __result;
+ size_t __copy_sz;
+
+ if (__old_sz > _Max_size
+ && __new_sz > _Max_size) {
+ return(realloc(__p, __new_sz));
+ }
+ if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
+ __result = allocate(__new_sz);
+ __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
+ memcpy(__result, __p, __copy_sz);
+ deallocate(__p, __old_sz);
+ return(__result);
+}
+
+template <size_t _Max_size>
+_Pthread_alloc_per_thread_state<_Max_size> *
+_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0;
+
+template <size_t _Max_size>
+pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key;
+
+template <size_t _Max_size>
+bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false;
+
+template <size_t _Max_size>
+pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock
+= PTHREAD_MUTEX_INITIALIZER;
+
+template <size_t _Max_size>
+char *_Pthread_alloc_template<_Max_size>
+::_S_start_free = 0;
+
+template <size_t _Max_size>
+char *_Pthread_alloc_template<_Max_size>
+::_S_end_free = 0;
+
+template <size_t _Max_size>
+size_t _Pthread_alloc_template<_Max_size>
+::_S_heap_size = 0;
+
+
+template <class _Tp>
+class pthread_allocator {
+ typedef pthread_alloc _S_Alloc; // The underlying allocator.
+public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp* pointer;
+ typedef const _Tp* const_pointer;
+ typedef _Tp& reference;
+ typedef const _Tp& const_reference;
+ typedef _Tp value_type;
+
+ template <class _NewType> struct rebind {
+ typedef pthread_allocator<_NewType> other;
+ };
+
+ pthread_allocator() throw() {}
+ pthread_allocator(const pthread_allocator& a) throw() {}
+ template <class _OtherType>
+ pthread_allocator(const pthread_allocator<_OtherType>&)
+ throw() {}
+ ~pthread_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*>(_S_Alloc::allocate(__n * sizeof(_Tp)))
+ : 0;
+ }
+
+ // p is not permitted to be a null pointer.
+ void deallocate(pointer __p, size_type __n)
+ { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); }
+
+ size_type max_size() const 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 pthread_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 _NewType> struct rebind {
+ typedef pthread_allocator<_NewType> other;
+ };
+};
+
+template <size_t _Max_size>
+inline bool operator==(const _Pthread_alloc_template<_Max_size>&,
+ const _Pthread_alloc_template<_Max_size>&)
+{
+ return true;
+}
+
+template <class _T1, class _T2>
+inline bool operator==(const pthread_allocator<_T1>&,
+ const pthread_allocator<_T2>& a2)
+{
+ return true;
+}
+
+template <class _T1, class _T2>
+inline bool operator!=(const pthread_allocator<_T1>&,
+ const pthread_allocator<_T2>&)
+{
+ return false;
+}
+
+template <class _Tp, size_t _Max_size>
+struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> >
+{
+ static const bool _S_instanceless = true;
+ typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type;
+ typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> >
+ allocator_type;
+};
+
+template <class _Tp, class _Atype, size_t _Max>
+struct _Alloc_traits<_Tp, __allocator<_Atype, _Pthread_alloc_template<_Max> > >
+{
+ static const bool _S_instanceless = true;
+ typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type;
+ typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type;
+};
+
+template <class _Tp, class _Atype>
+struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
+{
+ static const bool _S_instanceless = true;
+ typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type;
+ typedef pthread_allocator<_Tp> allocator_type;
+};
+
+
+} // namespace std
+
+#endif /* _CPP_BITS_PTHREAD_ALLOCIMPL_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/slice.h b/contrib/libstdc++/include/bits/slice.h
new file mode 100644
index 0000000000000..d3da664f8d1aa
--- /dev/null
+++ b/contrib/libstdc++/include/bits/slice.h
@@ -0,0 +1,85 @@
+// The template and inlines for the -*- C++ -*- slice class.
+
+// Copyright (C) 1997-1999, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+/** @file slice.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_SLICE_H
+#define _CPP_BITS_SLICE_H 1
+
+#pragma GCC system_header
+
+namespace std
+{
+
+class slice
+{
+public:
+ slice ();
+ slice (size_t, size_t, size_t);
+
+ size_t start () const;
+ size_t size () const;
+ size_t stride () const;
+
+private:
+ size_t _M_off; // offset
+ size_t _M_sz; // size
+ size_t _M_st; // stride unit
+};
+
+inline slice::slice () {}
+
+inline slice::slice (size_t __o, size_t __d, size_t __s)
+ : _M_off (__o), _M_sz (__d), _M_st (__s) {}
+
+inline size_t
+slice::start () const
+ { return _M_off; }
+
+inline size_t
+slice::size () const
+ { return _M_sz; }
+
+inline size_t
+slice::stride () const
+ { return _M_st; }
+
+} // std::
+
+
+#endif /* _CPP_BITS_SLICE_H */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/slice_array.h b/contrib/libstdc++/include/bits/slice_array.h
new file mode 100644
index 0000000000000..c8908f8bb53bb
--- /dev/null
+++ b/contrib/libstdc++/include/bits/slice_array.h
@@ -0,0 +1,180 @@
+// The template and inlines for the -*- C++ -*- slice_array class.
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+/** @file slice_array.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_SLICE_ARRAY_H
+#define _CPP_BITS_SLICE_ARRAY_H 1
+
+#pragma GCC system_header
+
+namespace std
+{
+
+ template<typename _Tp>
+ class slice_array
+ {
+ public:
+ typedef _Tp value_type;
+
+ // This constructor is implemented since we need to return a value.
+ slice_array (const slice_array&);
+
+ // This operator must be public. See DR-253.
+ slice_array& operator= (const slice_array&);
+
+ void operator= (const valarray<_Tp>&) const;
+ void operator*= (const valarray<_Tp>&) const;
+ void operator/= (const valarray<_Tp>&) const;
+ void operator%= (const valarray<_Tp>&) const;
+ void operator+= (const valarray<_Tp>&) const;
+ void operator-= (const valarray<_Tp>&) const;
+ void operator^= (const valarray<_Tp>&) const;
+ void operator&= (const valarray<_Tp>&) const;
+ void operator|= (const valarray<_Tp>&) const;
+ void operator<<= (const valarray<_Tp>&) const;
+ void operator>>= (const valarray<_Tp>&) const;
+ void operator= (const _Tp &);
+ // ~slice_array ();
+
+ template<class _Dom>
+ void operator= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator*= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator/= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator%= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator+= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator-= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator^= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator&= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator|= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator<<= (const _Expr<_Dom,_Tp>&) const;
+ template<class _Dom>
+ void operator>>= (const _Expr<_Dom,_Tp>&) const;
+
+ private:
+ friend class valarray<_Tp>;
+ slice_array(_Array<_Tp>, const slice&);
+
+ const size_t _M_sz;
+ const size_t _M_stride;
+ const _Array<_Tp> _M_array;
+
+ // not implemented
+ slice_array ();
+ };
+
+ template<typename _Tp>
+ inline slice_array<_Tp>::slice_array (_Array<_Tp> __a, const slice& __s)
+ : _M_sz (__s.size ()), _M_stride (__s.stride ()),
+ _M_array (__a.begin () + __s.start ()) {}
+
+
+ template<typename _Tp>
+ inline slice_array<_Tp>::slice_array(const slice_array<_Tp>& a)
+ : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {}
+
+ // template<typename _Tp>
+ // inline slice_array<_Tp>::~slice_array () {}
+
+ template<typename _Tp>
+ 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);
+ return *this;
+ }
+
+
+ template<typename _Tp>
+ inline void
+ slice_array<_Tp>::operator= (const _Tp& __t)
+ { __valarray_fill (_M_array, _M_sz, _M_stride, __t); }
+
+ template<typename _Tp>
+ inline void
+ slice_array<_Tp>::operator= (const valarray<_Tp>& __v) const
+ { __valarray_copy (_Array<_Tp> (__v), _M_array, _M_sz, _M_stride); }
+
+ template<typename _Tp>
+ template<class _Dom>
+ inline void
+ slice_array<_Tp>::operator= (const _Expr<_Dom,_Tp>& __e) const
+ { __valarray_copy (__e, _M_sz, _M_array, _M_stride); }
+
+#undef _DEFINE_VALARRAY_OPERATOR
+#define _DEFINE_VALARRAY_OPERATOR(op, name) \
+template<typename _Tp> \
+inline void \
+slice_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \
+{ \
+ _Array_augmented_##name (_M_array, _M_sz, _M_stride, _Array<_Tp> (__v));\
+} \
+ \
+template<typename _Tp> template<class _Dom> \
+inline void \
+slice_array<_Tp>::operator op##= (const _Expr<_Dom,_Tp>& __e) const \
+{ \
+ _Array_augmented_##name (_M_array, _M_stride, __e, _M_sz); \
+}
+
+
+_DEFINE_VALARRAY_OPERATOR(*, multiplies)
+_DEFINE_VALARRAY_OPERATOR(/, divides)
+_DEFINE_VALARRAY_OPERATOR(%, modulus)
+_DEFINE_VALARRAY_OPERATOR(+, plus)
+_DEFINE_VALARRAY_OPERATOR(-, minus)
+_DEFINE_VALARRAY_OPERATOR(^, xor)
+_DEFINE_VALARRAY_OPERATOR(&, and)
+_DEFINE_VALARRAY_OPERATOR(|, or)
+_DEFINE_VALARRAY_OPERATOR(<<, shift_left)
+_DEFINE_VALARRAY_OPERATOR(>>, shift_right)
+
+#undef _DEFINE_VALARRAY_OPERATOR
+
+} // std::
+
+#endif /* _CPP_BITS_SLICE_ARRAY_H */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/sstream.tcc b/contrib/libstdc++/include/bits/sstream.tcc
new file mode 100644
index 0000000000000..e7419504d3e54
--- /dev/null
+++ b/contrib/libstdc++/include/bits/sstream.tcc
@@ -0,0 +1,238 @@
+// String based streams -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.7 String-based streams
+//
+
+#ifndef _CPP_BITS_SSTREAM_TCC
+#define _CPP_BITS_SSTREAM_TCC 1
+
+#pragma GCC system_header
+
+#include <sstream>
+
+namespace std
+{
+ template <class _CharT, class _Traits, class _Alloc>
+ typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
+ basic_stringbuf<_CharT, _Traits, _Alloc>::
+ pbackfail(int_type __c)
+ {
+ int_type __ret = traits_type::eof();
+ bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
+ bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
+
+ // Try to put back __c into input sequence in one of three ways.
+ // Order these tests done in is unspecified by the standard.
+ if (__testpos)
+ {
+ if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])
+ && !__testeof)
+ {
+ --_M_in_cur;
+ __ret = __c;
+ }
+ else if (!__testeof)
+ {
+ --_M_in_cur;
+ *_M_in_cur = traits_type::to_char_type(__c);
+ __ret = __c;
+ }
+ else if (__testeof)
+ {
+ --_M_in_cur;
+ __ret = traits_type::not_eof(__c);
+ }
+ }
+ return __ret;
+ }
+
+ template <class _CharT, class _Traits, class _Alloc>
+ typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
+ basic_stringbuf<_CharT, _Traits, _Alloc>::
+ overflow(int_type __c)
+ {
+ int_type __ret = traits_type::eof();
+ bool __testeof = traits_type::eq_int_type(__c, __ret);
+ bool __testwrite = _M_out_cur < _M_buf + _M_buf_size;
+ bool __testout = _M_mode & ios_base::out;
+
+ // Try to append __c into output sequence in one of two ways.
+ // Order these tests done in is unspecified by the standard.
+ if (__testout)
+ {
+ if (!__testeof)
+ {
+ __size_type __len = max(_M_buf_size, _M_buf_size_opt);
+ __len *= 2;
+
+ if (__testwrite)
+ __ret = this->sputc(__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_really_sync(_M_in_cur - _M_in_beg,
+ _M_out_cur - _M_out_beg);
+ *_M_out_cur = traits_type::to_char_type(__c);
+ _M_out_cur_move(1);
+ __ret = __c;
+ }
+ }
+ else
+ __ret = traits_type::not_eof(__c);
+ }
+ return __ret;
+ }
+
+ template <class _CharT, class _Traits, class _Alloc>
+ typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
+ basic_stringbuf<_CharT, _Traits, _Alloc>::
+ seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
+ {
+ pos_type __ret = pos_type(off_type(-1));
+ 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;
+ __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;
+ char_type* __curo = NULL;
+ char_type* __endi = NULL;
+ char_type* __endo = NULL;
+
+ if (__testin || __testboth)
+ {
+ __curi = this->gptr();
+ __endi = this->egptr();
+ }
+ if (__testout || __testboth)
+ {
+ __curo = this->pptr();
+ __endo = this->epptr();
+ }
+
+ off_type __newoffi = 0;
+ off_type __newoffo = 0;
+ if (__way == ios_base::cur)
+ {
+ __newoffi = __curi - __beg;
+ __newoffo = __curo - __beg;
+ }
+ else if (__way == ios_base::end)
+ {
+ __newoffi = __endi - __beg;
+ __newoffo = __endo - __beg;
+ }
+
+ if ((__testin || __testboth)
+ && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off)
+ {
+ _M_in_cur = __beg + __newoffi + __off;
+ __ret = pos_type(__newoffi);
+ }
+ if ((__testout || __testboth)
+ && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off)
+ {
+ _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg));
+ __ret = pos_type(__newoffo);
+ }
+ }
+ return __ret;
+ }
+
+ template <class _CharT, class _Traits, class _Alloc>
+ typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
+ basic_stringbuf<_CharT, _Traits, _Alloc>::
+ seekpos(pos_type __sp, ios_base::openmode __mode)
+ {
+ pos_type __ret = pos_type(off_type(-1));
+
+ if (_M_buf_size)
+ {
+ off_type __pos = __sp._M_position();
+ 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;
+ }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // 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>;
+ extern template class basic_stringstream<wchar_t>;
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/stl_algo.h b/contrib/libstdc++/include/bits/stl_algo.h
new file mode 100644
index 0000000000000..009c409b6fb17
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_algo.h
@@ -0,0 +1,4351 @@
+// Algorithm implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_algo.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_ALGO_H
+#define __GLIBCPP_INTERNAL_ALGO_H
+
+#include <bits/stl_heap.h>
+#include <bits/stl_tempbuf.h> // for _Temporary_buffer
+
+// See concept_check.h for the __glibcpp_*_requires macros.
+
+namespace std
+{
+
+ /**
+ * @brief Find the median of three values.
+ * @param a A value.
+ * @param b A value.
+ * @param c A value.
+ * @return One of @p a, @p b or @p c.
+ *
+ * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n
+ * then the value returned will be @c m.
+ * This is an SGI extension.
+ * @ingroup SGIextensions
+ */
+ template<typename _Tp>
+ inline const _Tp&
+ __median(const _Tp& __a, const _Tp& __b, const _Tp& __c)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
+ if (__a < __b)
+ if (__b < __c)
+ return __b;
+ else if (__a < __c)
+ return __c;
+ else
+ return __a;
+ else if (__a < __c)
+ return __a;
+ else if (__b < __c)
+ return __c;
+ else
+ return __b;
+ }
+
+ /**
+ * @brief Find the median of three values using a predicate for comparison.
+ * @param a A value.
+ * @param b A value.
+ * @param c A value.
+ * @param comp A binary predicate.
+ * @return One of @p a, @p b or @p c.
+ *
+ * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m)
+ * and @p comp(m,n) are both true then the value returned will be @c m.
+ * This is an SGI extension.
+ * @ingroup SGIextensions
+ */
+ template<typename _Tp, typename _Compare>
+ inline const _Tp&
+ __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>)
+ if (__comp(__a, __b))
+ if (__comp(__b, __c))
+ return __b;
+ else if (__comp(__a, __c))
+ return __c;
+ else
+ return __a;
+ else if (__comp(__a, __c))
+ return __a;
+ else if (__comp(__b, __c))
+ return __c;
+ else
+ return __b;
+ }
+
+ /**
+ * @brief Apply a function to every element of a sequence.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param f A unary function object.
+ * @return @p f.
+ *
+ * Applies the function object @p f to each element in the range
+ * @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>
+ _Function
+ for_each(_InputIter __first, _InputIter __last, _Function __f)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ for ( ; __first != __last; ++__first)
+ __f(*__first);
+ return __f;
+ }
+
+ /**
+ * @if maint
+ * This is an overload used by find() for the Input Iterator case.
+ * @endif
+ */
+ template<typename _InputIter, typename _Tp>
+ inline _InputIter
+ find(_InputIter __first, _InputIter __last,
+ const _Tp& __val,
+ input_iterator_tag)
+ {
+ while (__first != __last && !(*__first == __val))
+ ++__first;
+ return __first;
+ }
+
+ /**
+ * @if maint
+ * This is an overload used by find_if() for the Input Iterator case.
+ * @endif
+ */
+ template<typename _InputIter, typename _Predicate>
+ inline _InputIter
+ find_if(_InputIter __first, _InputIter __last,
+ _Predicate __pred,
+ input_iterator_tag)
+ {
+ while (__first != __last && !__pred(*__first))
+ ++__first;
+ return __first;
+ }
+
+ /**
+ * @if maint
+ * This is an overload used by find() for the RAI case.
+ * @endif
+ */
+ template<typename _RandomAccessIter, typename _Tp>
+ _RandomAccessIter
+ find(_RandomAccessIter __first, _RandomAccessIter __last,
+ const _Tp& __val,
+ random_access_iterator_tag)
+ {
+ typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
+ = (__last - __first) >> 2;
+
+ for ( ; __trip_count > 0 ; --__trip_count) {
+ if (*__first == __val) return __first;
+ ++__first;
+
+ if (*__first == __val) return __first;
+ ++__first;
+
+ if (*__first == __val) return __first;
+ ++__first;
+
+ if (*__first == __val) return __first;
+ ++__first;
+ }
+
+ switch(__last - __first) {
+ case 3:
+ if (*__first == __val) return __first;
+ ++__first;
+ case 2:
+ if (*__first == __val) return __first;
+ ++__first;
+ case 1:
+ if (*__first == __val) return __first;
+ ++__first;
+ case 0:
+ default:
+ return __last;
+ }
+ }
+
+ /**
+ * @if maint
+ * This is an overload used by find_if() for the RAI case.
+ * @endif
+ */
+ template<typename _RandomAccessIter, typename _Predicate>
+ _RandomAccessIter
+ find_if(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Predicate __pred,
+ random_access_iterator_tag)
+ {
+ typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
+ = (__last - __first) >> 2;
+
+ for ( ; __trip_count > 0 ; --__trip_count) {
+ if (__pred(*__first)) return __first;
+ ++__first;
+
+ if (__pred(*__first)) return __first;
+ ++__first;
+
+ if (__pred(*__first)) return __first;
+ ++__first;
+
+ if (__pred(*__first)) return __first;
+ ++__first;
+ }
+
+ switch(__last - __first) {
+ case 3:
+ if (__pred(*__first)) return __first;
+ ++__first;
+ case 2:
+ if (__pred(*__first)) return __first;
+ ++__first;
+ case 1:
+ if (__pred(*__first)) return __first;
+ ++__first;
+ case 0:
+ default:
+ return __last;
+ }
+ }
+
+ /**
+ * @brief Find the first occurrence of a value in a sequence.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param val The value to find.
+ * @return The first iterator @c i in the range @p [first,last)
+ * such that @c *i == @p val, or @p last if no such iterator exists.
+ */
+ template<typename _InputIter, typename _Tp>
+ inline _InputIter
+ find(_InputIter __first, _InputIter __last,
+ const _Tp& __val)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_InputIter>::value_type, _Tp>)
+ return find(__first, __last, __val, __iterator_category(__first));
+ }
+
+ /**
+ * @brief Find the first element in a sequence for which a predicate is true.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param pred A predicate.
+ * @return The first iterator @c i in the range @p [first,last)
+ * such that @p pred(*i) is true, or @p last if no such iterator exists.
+ */
+ template<typename _InputIter, typename _Predicate>
+ inline _InputIter
+ find_if(_InputIter __first, _InputIter __last,
+ _Predicate __pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_InputIter>::value_type>)
+ return find_if(__first, __last, __pred, __iterator_category(__first));
+ }
+
+ /**
+ * @brief Find two adjacent values in a sequence that are equal.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @return The first iterator @c i such that @c i and @c i+1 are both
+ * valid iterators in @p [first,last) and such that @c *i == @c *(i+1),
+ * or @p last if no such iterator exists.
+ */
+ template<typename _ForwardIter>
+ _ForwardIter
+ adjacent_find(_ForwardIter __first, _ForwardIter __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_EqualityComparableConcept<
+ typename iterator_traits<_ForwardIter>::value_type>)
+ if (__first == __last)
+ return __last;
+ _ForwardIter __next = __first;
+ while(++__next != __last) {
+ if (*__first == *__next)
+ return __first;
+ __first = __next;
+ }
+ return __last;
+ }
+
+ /**
+ * @brief Find two adjacent values in a sequence using a predicate.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param binary_pred A binary predicate.
+ * @return The first iterator @c i such that @c i and @c i+1 are both
+ * valid iterators in @p [first,last) and such that
+ * @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator
+ * exists.
+ */
+ template<typename _ForwardIter, typename _BinaryPredicate>
+ _ForwardIter
+ adjacent_find(_ForwardIter __first, _ForwardIter __last,
+ _BinaryPredicate __binary_pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_ForwardIter>::value_type,
+ typename iterator_traits<_ForwardIter>::value_type>)
+ if (__first == __last)
+ return __last;
+ _ForwardIter __next = __first;
+ while(++__next != __last) {
+ if (__binary_pred(*__first, *__next))
+ return __first;
+ __first = __next;
+ }
+ return __last;
+ }
+
+ /**
+ * @brief Count the number of copies of a value in a sequence.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param value The value to be counted.
+ * @return The number of iterators @c i in the range @p [first,last)
+ * for which @c *i == @p value
+ */
+ template<typename _InputIter, typename _Tp>
+ typename iterator_traits<_InputIter>::difference_type
+ count(_InputIter __first, _InputIter __last, const _Tp& __value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_EqualityComparableConcept<
+ typename iterator_traits<_InputIter>::value_type >)
+ __glibcpp_function_requires(_EqualityComparableConcept<_Tp>)
+ typename iterator_traits<_InputIter>::difference_type __n = 0;
+ for ( ; __first != __last; ++__first)
+ if (*__first == __value)
+ ++__n;
+ return __n;
+ }
+
+ /**
+ * @brief Count the elements of a sequence for which a predicate is true.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param pred A predicate.
+ * @return The number of iterators @c i in the range @p [first,last)
+ * for which @p pred(*i) is true.
+ */
+ template<typename _InputIter, typename _Predicate>
+ typename iterator_traits<_InputIter>::difference_type
+ count_if(_InputIter __first, _InputIter __last, _Predicate __pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_InputIter>::value_type>)
+ typename iterator_traits<_InputIter>::difference_type __n = 0;
+ for ( ; __first != __last; ++__first)
+ if (__pred(*__first))
+ ++__n;
+ return __n;
+ }
+
+
+ /**
+ * @brief Search a sequence for a matching sub-sequence.
+ * @param first1 A forward iterator.
+ * @param last1 A forward iterator.
+ * @param first2 A forward iterator.
+ * @param last2 A forward iterator.
+ * @return The first iterator @c i in the range
+ * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N)
+ * for each @c N in the range @p [0,last2-first2), or @p last1 if no
+ * such iterator exists.
+ *
+ * Searches the range @p [first1,last1) for a sub-sequence that compares
+ * equal value-by-value with the sequence given by @p [first2,last2) and
+ * returns an iterator to the first element of the sub-sequence, or
+ * @p last1 if the sub-sequence is not found.
+ *
+ * Because the sub-sequence must lie completely within the range
+ * @p [first1,last1) it must start at a position less than
+ * @p last1-(last2-first2) where @p last2-first2 is the length of the
+ * sub-sequence.
+ * This means that the returned iterator @c i will be in the range
+ * @p [first1,last1-(last2-first2))
+ */
+ template<typename _ForwardIter1, typename _ForwardIter2>
+ _ForwardIter1
+ search(_ForwardIter1 __first1, _ForwardIter1 __last1,
+ _ForwardIter2 __first2, _ForwardIter2 __last2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>)
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_ForwardIter1>::value_type,
+ typename iterator_traits<_ForwardIter2>::value_type>)
+
+ // Test for empty ranges
+ if (__first1 == __last1 || __first2 == __last2)
+ return __first1;
+
+ // Test for a pattern of length 1.
+ _ForwardIter2 __tmp(__first2);
+ ++__tmp;
+ if (__tmp == __last2)
+ return find(__first1, __last1, *__first2);
+
+ // General case.
+
+ _ForwardIter2 __p1, __p;
+
+ __p1 = __first2; ++__p1;
+
+ _ForwardIter1 __current = __first1;
+
+ while (__first1 != __last1) {
+ __first1 = find(__first1, __last1, *__first2);
+ if (__first1 == __last1)
+ return __last1;
+
+ __p = __p1;
+ __current = __first1;
+ if (++__current == __last1)
+ return __last1;
+
+ while (*__current == *__p) {
+ if (++__p == __last2)
+ return __first1;
+ if (++__current == __last1)
+ return __last1;
+ }
+
+ ++__first1;
+ }
+ return __first1;
+ }
+
+ /**
+ * @brief Search a sequence for a matching sub-sequence using a predicate.
+ * @param first1 A forward iterator.
+ * @param last1 A forward iterator.
+ * @param first2 A forward iterator.
+ * @param last2 A forward iterator.
+ * @param predicate A binary predicate.
+ * @return The first iterator @c i in the range
+ * @p [first1,last1-(last2-first2)) such that
+ * @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range
+ * @p [0,last2-first2), or @p last1 if no such iterator exists.
+ *
+ * Searches the range @p [first1,last1) for a sub-sequence that compares
+ * equal value-by-value with the sequence given by @p [first2,last2),
+ * using @p predicate to determine equality, and returns an iterator
+ * to the first element of the sub-sequence, or @p last1 if no such
+ * iterator exists.
+ *
+ * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2)
+ */
+ template<typename _ForwardIter1, typename _ForwardIter2, typename _BinaryPred>
+ _ForwardIter1
+ search(_ForwardIter1 __first1, _ForwardIter1 __last1,
+ _ForwardIter2 __first2, _ForwardIter2 __last2,
+ _BinaryPred __predicate)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>)
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPred,
+ typename iterator_traits<_ForwardIter1>::value_type,
+ typename iterator_traits<_ForwardIter2>::value_type>)
+
+ // Test for empty ranges
+ if (__first1 == __last1 || __first2 == __last2)
+ return __first1;
+
+ // Test for a pattern of length 1.
+ _ForwardIter2 __tmp(__first2);
+ ++__tmp;
+ if (__tmp == __last2) {
+ while (__first1 != __last1 && !__predicate(*__first1, *__first2))
+ ++__first1;
+ return __first1;
+ }
+
+ // General case.
+
+ _ForwardIter2 __p1, __p;
+
+ __p1 = __first2; ++__p1;
+
+ _ForwardIter1 __current = __first1;
+
+ while (__first1 != __last1) {
+ while (__first1 != __last1) {
+ if (__predicate(*__first1, *__first2))
+ break;
+ ++__first1;
+ }
+ while (__first1 != __last1 && !__predicate(*__first1, *__first2))
+ ++__first1;
+ if (__first1 == __last1)
+ return __last1;
+
+ __p = __p1;
+ __current = __first1;
+ if (++__current == __last1) return __last1;
+
+ while (__predicate(*__current, *__p)) {
+ if (++__p == __last2)
+ return __first1;
+ if (++__current == __last1)
+ return __last1;
+ }
+
+ ++__first1;
+ }
+ return __first1;
+ }
+
+ /**
+ * @brief Search a sequence for a number of consecutive values.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param count The number of consecutive values.
+ * @param val The value to find.
+ * @return The first iterator @c i in the range @p [first,last-count)
+ * such that @c *(i+N) == @p val for each @c N in the range @p [0,count),
+ * or @p last if no such iterator exists.
+ *
+ * Searches the range @p [first,last) for @p count consecutive elements
+ * equal to @p val.
+ */
+ template<typename _ForwardIter, typename _Integer, typename _Tp>
+ _ForwardIter
+ search_n(_ForwardIter __first, _ForwardIter __last,
+ _Integer __count, const _Tp& __val)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_EqualityComparableConcept<
+ typename iterator_traits<_ForwardIter>::value_type>)
+ __glibcpp_function_requires(_EqualityComparableConcept<_Tp>)
+
+ if (__count <= 0)
+ return __first;
+ else {
+ __first = find(__first, __last, __val);
+ while (__first != __last) {
+ _Integer __n = __count - 1;
+ _ForwardIter __i = __first;
+ ++__i;
+ while (__i != __last && __n != 0 && *__i == __val) {
+ ++__i;
+ --__n;
+ }
+ if (__n == 0)
+ return __first;
+ else
+ __first = find(__i, __last, __val);
+ }
+ return __last;
+ }
+ }
+
+ /**
+ * @brief Search a sequence for a number of consecutive values using a
+ * predicate.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param count The number of consecutive values.
+ * @param val The value to find.
+ * @param binary_pred A binary predicate.
+ * @return The first iterator @c i in the range @p [first,last-count)
+ * such that @p binary_pred(*(i+N),val) is true for each @c N in the
+ * range @p [0,count), or @p last if no such iterator exists.
+ *
+ * Searches the range @p [first,last) for @p count consecutive elements
+ * for which the predicate returns true.
+ */
+ template<typename _ForwardIter, typename _Integer, typename _Tp,
+ typename _BinaryPred>
+ _ForwardIter
+ search_n(_ForwardIter __first, _ForwardIter __last,
+ _Integer __count, const _Tp& __val,
+ _BinaryPred __binary_pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPred,
+ typename iterator_traits<_ForwardIter>::value_type, _Tp>)
+
+ if (__count <= 0)
+ return __first;
+ else {
+ while (__first != __last) {
+ if (__binary_pred(*__first, __val))
+ break;
+ ++__first;
+ }
+ while (__first != __last) {
+ _Integer __n = __count - 1;
+ _ForwardIter __i = __first;
+ ++__i;
+ while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) {
+ ++__i;
+ --__n;
+ }
+ if (__n == 0)
+ return __first;
+ else {
+ while (__i != __last) {
+ if (__binary_pred(*__i, __val))
+ break;
+ ++__i;
+ }
+ __first = __i;
+ }
+ }
+ return __last;
+ }
+ }
+
+ /**
+ * @brief Swap the elements of two sequences.
+ * @param first1 A forward iterator.
+ * @param last1 A forward iterator.
+ * @param first2 A forward iterator.
+ * @return An iterator equal to @p first2+(last1-first1).
+ *
+ * Swaps each element in the range @p [first1,last1) with the
+ * corresponding element in the range @p [first2,(last1-first1)).
+ * The ranges must not overlap.
+ */
+ template<typename _ForwardIter1, typename _ForwardIter2>
+ _ForwardIter2
+ swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1,
+ _ForwardIter2 __first2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter1>)
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter2>)
+ __glibcpp_function_requires(_ConvertibleConcept<
+ typename iterator_traits<_ForwardIter1>::value_type,
+ typename iterator_traits<_ForwardIter2>::value_type>)
+ __glibcpp_function_requires(_ConvertibleConcept<
+ typename iterator_traits<_ForwardIter2>::value_type,
+ typename iterator_traits<_ForwardIter1>::value_type>)
+
+ for ( ; __first1 != __last1; ++__first1, ++__first2)
+ iter_swap(__first1, __first2);
+ return __first2;
+ }
+
+ /**
+ * @brief Perform an operation on a sequence.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @param unary_op A unary operator.
+ * @return An output iterator equal to @p result+(last-first).
+ *
+ * Applies the operator to each element in the input range and assigns
+ * the results to successive elements of the output sequence.
+ * Evaluates @p *(result+N)=unary_op(*(first+N)) for each @c N in the
+ * range @p [0,last-first).
+ *
+ * @p unary_op must not alter its argument.
+ */
+ template<typename _InputIter, typename _OutputIter, typename _UnaryOperation>
+ _OutputIter
+ transform(_InputIter __first, _InputIter __last,
+ _OutputIter __result, _UnaryOperation __unary_op)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ // "the type returned by a _UnaryOperation"
+ __typeof__(__unary_op(*__first))>)
+
+ for ( ; __first != __last; ++__first, ++__result)
+ *__result = __unary_op(*__first);
+ return __result;
+ }
+
+ /**
+ * @brief Perform an operation on corresponding elements of two sequences.
+ * @param first1 An input iterator.
+ * @param last1 An input iterator.
+ * @param first2 An input iterator.
+ * @param result An output iterator.
+ * @param binary_op A binary operator.
+ * @return An output iterator equal to @p result+(last-first).
+ *
+ * Applies the operator to the corresponding elements in the two
+ * input ranges and assigns the results to successive elements of the
+ * output sequence.
+ * Evaluates @p *(result+N)=binary_op(*(first1+N),*(first2+N)) for each
+ * @c N in the range @p [0,last1-first1).
+ *
+ * @p binary_op must not alter either of its arguments.
+ */
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
+ typename _BinaryOperation>
+ _OutputIter
+ transform(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _OutputIter __result,
+ _BinaryOperation __binary_op)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ // "the type returned by a _BinaryOperation"
+ __typeof__(__binary_op(*__first1,*__first2))>)
+
+ for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
+ *__result = __binary_op(*__first1, *__first2);
+ return __result;
+ }
+
+ /**
+ * @brief Replace each occurrence of one value in a sequence with another
+ * value.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param old_value The value to be replaced.
+ * @param new_value The replacement value.
+ * @return replace() returns no value.
+ *
+ * For each iterator @c i in the range @p [first,last) if @c *i ==
+ * @p old_value then the assignment @c *i = @p new_value is performed.
+ */
+ template<typename _ForwardIter, typename _Tp>
+ void
+ replace(_ForwardIter __first, _ForwardIter __last,
+ const _Tp& __old_value, const _Tp& __new_value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_ForwardIter>::value_type, _Tp>)
+ __glibcpp_function_requires(_ConvertibleConcept<_Tp,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ for ( ; __first != __last; ++__first)
+ if (*__first == __old_value)
+ *__first = __new_value;
+ }
+
+ /**
+ * @brief Replace each value in a sequence for which a predicate returns
+ * true with another value.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param pred A predicate.
+ * @param new_value The replacement value.
+ * @return replace_if() returns no value.
+ *
+ * For each iterator @c i in the range @p [first,last) if @p pred(*i)
+ * is true then the assignment @c *i = @p new_value is performed.
+ */
+ template<typename _ForwardIter, typename _Predicate, typename _Tp>
+ void
+ replace_if(_ForwardIter __first, _ForwardIter __last,
+ _Predicate __pred, const _Tp& __new_value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_ConvertibleConcept<_Tp,
+ typename iterator_traits<_ForwardIter>::value_type>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ for ( ; __first != __last; ++__first)
+ if (__pred(*__first))
+ *__first = __new_value;
+ }
+
+ /**
+ * @brief Copy a sequence, replacing each element of one value with another
+ * value.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @param old_value The value to be replaced.
+ * @param new_value The replacement value.
+ * @return The end of the output sequence, @p result+(last-first).
+ *
+ * Copies each element in the input range @p [first,last) to the
+ * output range @p [result,result+(last-first)) replacing elements
+ * equal to @p old_value with @p new_value.
+ */
+ template<typename _InputIter, typename _OutputIter, typename _Tp>
+ _OutputIter
+ replace_copy(_InputIter __first, _InputIter __last,
+ _OutputIter __result,
+ const _Tp& __old_value, const _Tp& __new_value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter>::value_type>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_InputIter>::value_type, _Tp>)
+
+ for ( ; __first != __last; ++__first, ++__result)
+ *__result = *__first == __old_value ? __new_value : *__first;
+ return __result;
+ }
+
+ /**
+ * @brief Copy a sequence, replacing each value for which a predicate
+ * returns true with another value.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @param pred A predicate.
+ * @param new_value The replacement value.
+ * @return The end of the output sequence, @p result+(last-first).
+ *
+ * Copies each element in the range @p [first,last) to the range
+ * @p [result,result+(last-first)) replacing elements for which
+ * @p pred returns true with @p new_value.
+ */
+ template<typename _InputIter, typename _OutputIter, typename _Predicate,
+ typename _Tp>
+ _OutputIter
+ replace_copy_if(_InputIter __first, _InputIter __last,
+ _OutputIter __result,
+ _Predicate __pred, const _Tp& __new_value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter>::value_type>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_InputIter>::value_type>)
+
+ for ( ; __first != __last; ++__first, ++__result)
+ *__result = __pred(*__first) ? __new_value : *__first;
+ return __result;
+ }
+
+ /**
+ * @brief Assign the result of a function object to each value in a
+ * sequence.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param gen A function object taking no arguments.
+ * @return generate() returns no value.
+ *
+ * Performs the assignment @c *i = @p gen() for each @c i in the range
+ * @p [first,last).
+ */
+ template<typename _ForwardIter, typename _Generator>
+ void
+ generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_GeneratorConcept<_Generator,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ for ( ; __first != __last; ++__first)
+ *__first = __gen();
+ }
+
+ /**
+ * @brief Assign the result of a function object to each value in a
+ * sequence.
+ * @param first A forward iterator.
+ * @param n The length of the sequence.
+ * @param gen A function object taking no arguments.
+ * @return The end of the sequence, @p first+n
+ *
+ * Performs the assignment @c *i = @p gen() for each @c i in the range
+ * @p [first,first+n).
+ */
+ template<typename _OutputIter, typename _Size, typename _Generator>
+ _OutputIter
+ generate_n(_OutputIter __first, _Size __n, _Generator __gen)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ // "the type returned by a _Generator"
+ __typeof__(gen())>)
+
+ for ( ; __n > 0; --__n, ++__first)
+ *__first = __gen();
+ return __first;
+ }
+
+ /**
+ * @brief Copy a sequence, removing elements of a given value.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @param value The value to be removed.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * Copies each element in the range @p [first,last) not equal to @p value
+ * to the range beginning at @p result.
+ * remove_copy() is stable, so the relative order of elements that are
+ * copied is unchanged.
+ */
+ template<typename _InputIter, typename _OutputIter, typename _Tp>
+ _OutputIter
+ remove_copy(_InputIter __first, _InputIter __last,
+ _OutputIter __result, const _Tp& __value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter>::value_type>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_InputIter>::value_type, _Tp>)
+
+ for ( ; __first != __last; ++__first)
+ if (!(*__first == __value)) {
+ *__result = *__first;
+ ++__result;
+ }
+ return __result;
+ }
+
+ /**
+ * @brief Copy a sequence, removing elements for which a predicate is true.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @param pred A predicate.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * Copies each element in the range @p [first,last) for which
+ * @p pred returns true to the range beginning at @p result.
+ *
+ * remove_copy_if() is stable, so the relative order of elements that are
+ * copied is unchanged.
+ */
+ template<typename _InputIter, typename _OutputIter, typename _Predicate>
+ _OutputIter
+ remove_copy_if(_InputIter __first, _InputIter __last,
+ _OutputIter __result, _Predicate __pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter>::value_type>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_InputIter>::value_type>)
+
+ for ( ; __first != __last; ++__first)
+ if (!__pred(*__first)) {
+ *__result = *__first;
+ ++__result;
+ }
+ return __result;
+ }
+
+ /**
+ * @brief Remove elements from a sequence.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param value The value to be removed.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * All elements equal to @p value are removed from the range
+ * @p [first,last).
+ *
+ * remove() is stable, so the relative order of elements that are
+ * not removed is unchanged.
+ *
+ * Elements between the end of the resulting sequence and @p last
+ * are still present, but their value is unspecified.
+ */
+ template<typename _ForwardIter, typename _Tp>
+ _ForwardIter
+ remove(_ForwardIter __first, _ForwardIter __last,
+ const _Tp& __value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_ConvertibleConcept<_Tp,
+ typename iterator_traits<_ForwardIter>::value_type>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_ForwardIter>::value_type, _Tp>)
+
+ __first = find(__first, __last, __value);
+ _ForwardIter __i = __first;
+ return __first == __last ? __first
+ : remove_copy(++__i, __last, __first, __value);
+ }
+
+ /**
+ * @brief Remove elements from a sequence using a predicate.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param pred A predicate.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * All elements for which @p pred returns true are removed from the range
+ * @p [first,last).
+ *
+ * remove_if() is stable, so the relative order of elements that are
+ * not removed is unchanged.
+ *
+ * Elements between the end of the resulting sequence and @p last
+ * are still present, but their value is unspecified.
+ */
+ template<typename _ForwardIter, typename _Predicate>
+ _ForwardIter
+ remove_if(_ForwardIter __first, _ForwardIter __last,
+ _Predicate __pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ __first = find_if(__first, __last, __pred);
+ _ForwardIter __i = __first;
+ return __first == __last ? __first
+ : remove_copy_if(++__i, __last, __first, __pred);
+ }
+
+ /**
+ * @if maint
+ * This is an uglified unique_copy(_InputIter, _InputIter, _OutputIter)
+ * overloaded for output iterators.
+ * @endif
+ */
+ template<typename _InputIter, typename _OutputIter>
+ _OutputIter
+ __unique_copy(_InputIter __first, _InputIter __last,
+ _OutputIter __result,
+ output_iterator_tag)
+ {
+ // concept requirements -- taken care of in dispatching function
+ typename iterator_traits<_InputIter>::value_type __value = *__first;
+ *__result = __value;
+ while (++__first != __last)
+ if (!(__value == *__first)) {
+ __value = *__first;
+ *++__result = __value;
+ }
+ return ++__result;
+ }
+
+ /**
+ * @if maint
+ * This is an uglified unique_copy(_InputIter, _InputIter, _OutputIter)
+ * overloaded for forward iterators.
+ * @endif
+ */
+ template<typename _InputIter, typename _ForwardIter>
+ _ForwardIter
+ __unique_copy(_InputIter __first, _InputIter __last,
+ _ForwardIter __result,
+ forward_iterator_tag)
+ {
+ // concept requirements -- taken care of in dispatching function
+ *__result = *__first;
+ while (++__first != __last)
+ if (!(*__result == *__first))
+ *++__result = *__first;
+ return ++__result;
+ }
+
+ /**
+ * @brief Copy a sequence, removing consecutive duplicate values.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * 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
+ unique_copy(_InputIter __first, _InputIter __last,
+ _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter>::value_type>)
+ __glibcpp_function_requires(_EqualityComparableConcept<
+ typename iterator_traits<_InputIter>::value_type>)
+
+ typedef typename iterator_traits<_OutputIter>::iterator_category _IterType;
+
+ if (__first == __last) return __result;
+ return __unique_copy(__first, __last, __result, _IterType());
+ }
+
+ /**
+ * @if maint
+ * This is an uglified
+ * unique_copy(_InputIter, _InputIter, _OutputIter, _BinaryPredicate)
+ * overloaded for output iterators.
+ * @endif
+ */
+ template<typename _InputIter, typename _OutputIter, typename _BinaryPredicate>
+ _OutputIter
+ __unique_copy(_InputIter __first, _InputIter __last,
+ _OutputIter __result,
+ _BinaryPredicate __binary_pred,
+ output_iterator_tag)
+ {
+ // concept requirements -- iterators already checked
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_InputIter>::value_type,
+ typename iterator_traits<_InputIter>::value_type>)
+
+ typename iterator_traits<_InputIter>::value_type __value = *__first;
+ *__result = __value;
+ while (++__first != __last)
+ if (!__binary_pred(__value, *__first)) {
+ __value = *__first;
+ *++__result = __value;
+ }
+ return ++__result;
+ }
+
+ /**
+ * @if maint
+ * This is an uglified
+ * unique_copy(_InputIter, _InputIter, _OutputIter, _BinaryPredicate)
+ * overloaded for forward iterators.
+ * @endif
+ */
+ template<typename _InputIter, typename _ForwardIter, typename _BinaryPredicate>
+ _ForwardIter
+ __unique_copy(_InputIter __first, _InputIter __last,
+ _ForwardIter __result,
+ _BinaryPredicate __binary_pred,
+ forward_iterator_tag)
+ {
+ // concept requirements -- iterators already checked
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_ForwardIter>::value_type,
+ typename iterator_traits<_InputIter>::value_type>)
+
+ *__result = *__first;
+ while (++__first != __last)
+ if (!__binary_pred(*__result, *__first)) *++__result = *__first;
+ return ++__result;
+ }
+
+ /**
+ * @brief Copy a sequence, removing consecutive values using a predicate.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @param binary_pred A binary predicate.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * 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 for which @p binary_pred returns
+ * true.
+ * unique_copy() is stable, so the relative order of elements that are
+ * copied is unchanged.
+ */
+ template<typename _InputIter, typename _OutputIter, typename _BinaryPredicate>
+ inline _OutputIter
+ unique_copy(_InputIter __first, _InputIter __last,
+ _OutputIter __result,
+ _BinaryPredicate __binary_pred)
+ {
+ // concept requirements -- predicates checked later
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter>::value_type>)
+
+ typedef typename iterator_traits<_OutputIter>::iterator_category _IterType;
+
+ if (__first == __last) return __result;
+ return __unique_copy(__first, __last,
+__result, __binary_pred, _IterType());
+ }
+
+ /**
+ * @brief Remove consecutive duplicate values from a sequence.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * Removes all but the first element from each group of consecutive
+ * values that compare equal.
+ * unique() is stable, so the relative order of elements that are
+ * not removed is unchanged.
+ * Elements between the end of the resulting sequence and @p last
+ * are still present, but their value is unspecified.
+ */
+ template<typename _ForwardIter>
+ _ForwardIter
+ unique(_ForwardIter __first, _ForwardIter __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_EqualityComparableConcept<
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ __first = adjacent_find(__first, __last);
+ return unique_copy(__first, __last, __first);
+ }
+
+ /**
+ * @brief Remove consecutive values from a sequence using a predicate.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param binary_pred A binary predicate.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * Removes all but the first element from each group of consecutive
+ * values for which @p binary_pred returns true.
+ * unique() is stable, so the relative order of elements that are
+ * not removed is unchanged.
+ * Elements between the end of the resulting sequence and @p last
+ * are still present, but their value is unspecified.
+ */
+ template<typename _ForwardIter, typename _BinaryPredicate>
+ _ForwardIter
+ unique(_ForwardIter __first, _ForwardIter __last,
+ _BinaryPredicate __binary_pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_ForwardIter>::value_type,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ __first = adjacent_find(__first, __last, __binary_pred);
+ return unique_copy(__first, __last, __first, __binary_pred);
+ }
+
+ /**
+ * @if maint
+ * This is an uglified reverse(_BidirectionalIter, _BidirectionalIter)
+ * overloaded for bidirectional iterators.
+ * @endif
+ */
+ template<typename _BidirectionalIter>
+ void
+ __reverse(_BidirectionalIter __first, _BidirectionalIter __last,
+ bidirectional_iterator_tag)
+ {
+ while (true)
+ if (__first == __last || __first == --__last)
+ return;
+ else
+ iter_swap(__first++, __last);
+ }
+
+ /**
+ * @if maint
+ * This is an uglified reverse(_BidirectionalIter, _BidirectionalIter)
+ * overloaded for bidirectional iterators.
+ * @endif
+ */
+ template<typename _RandomAccessIter>
+ void
+ __reverse(_RandomAccessIter __first, _RandomAccessIter __last,
+ random_access_iterator_tag)
+ {
+ while (__first < __last)
+ iter_swap(__first++, --__last);
+ }
+
+ /**
+ * @brief Reverse a sequence.
+ * @param first A bidirectional iterator.
+ * @param last A bidirectional iterator.
+ * @return reverse() returns no value.
+ *
+ * Reverses the order of the elements in the range @p [first,last),
+ * so that the first element becomes the last etc.
+ * For every @c i such that @p 0<=i<=(last-first)/2), @p reverse()
+ * swaps @p *(first+i) and @p *(last-(i+1))
+ */
+ template<typename _BidirectionalIter>
+ inline void
+ reverse(_BidirectionalIter __first, _BidirectionalIter __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
+ _BidirectionalIter>)
+ __reverse(__first, __last, __iterator_category(__first));
+ }
+
+ /**
+ * @brief Copy a sequence, reversing its elements.
+ * @param first A bidirectional iterator.
+ * @param last A bidirectional iterator.
+ * @param result An output iterator.
+ * @return An iterator designating the end of the resulting sequence.
+ *
+ * Copies the elements in the range @p [first,last) to the range
+ * @p [result,result+(last-first)) such that the order of the
+ * elements is reversed.
+ * For every @c i such that @p 0<=i<=(last-first), @p reverse_copy()
+ * performs the assignment @p *(result+(last-first)-i) = *(first+i).
+ * The ranges @p [first,last) and @p [result,result+(last-first))
+ * must not overlap.
+ */
+ template<typename _BidirectionalIter, typename _OutputIter>
+ _OutputIter
+ reverse_copy(_BidirectionalIter __first, _BidirectionalIter __last,
+ _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_BidirectionalIter>::value_type>)
+
+ while (__first != __last) {
+ --__last;
+ *__result = *__last;
+ ++__result;
+ }
+ return __result;
+ }
+
+
+ /**
+ * @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)
+ {
+ while (__n != 0) {
+ _EuclideanRingElement __t = __m % __n;
+ __m = __n;
+ __n = __t;
+ }
+ return __m;
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the rotate algorithm.
+ * @endif
+ */
+ template<typename _ForwardIter>
+ void
+ __rotate(_ForwardIter __first,
+ _ForwardIter __middle,
+ _ForwardIter __last,
+ forward_iterator_tag)
+ {
+ if ((__first == __middle) || (__last == __middle))
+ return;
+
+ _ForwardIter __first2 = __middle;
+ do {
+ swap(*__first++, *__first2++);
+ if (__first == __middle)
+ __middle = __first2;
+ } while (__first2 != __last);
+
+ __first2 = __middle;
+
+ while (__first2 != __last) {
+ swap(*__first++, *__first2++);
+ if (__first == __middle)
+ __middle = __first2;
+ else if (__first2 == __last)
+ __first2 = __middle;
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the rotate algorithm.
+ * @endif
+ */
+ template<typename _BidirectionalIter>
+ void
+ __rotate(_BidirectionalIter __first,
+ _BidirectionalIter __middle,
+ _BidirectionalIter __last,
+ bidirectional_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
+ _BidirectionalIter>)
+
+ if ((__first == __middle) || (__last == __middle))
+ return;
+
+ __reverse(__first, __middle, bidirectional_iterator_tag());
+ __reverse(__middle, __last, bidirectional_iterator_tag());
+
+ while (__first != __middle && __middle != __last)
+ swap (*__first++, *--__last);
+
+ if (__first == __middle) {
+ __reverse(__middle, __last, bidirectional_iterator_tag());
+ }
+ else {
+ __reverse(__first, __middle, bidirectional_iterator_tag());
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the rotate algorithm.
+ * @endif
+ */
+ template<typename _RandomAccessIter>
+ void
+ __rotate(_RandomAccessIter __first,
+ _RandomAccessIter __middle,
+ _RandomAccessIter __last,
+ random_access_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+
+ if ((__first == __middle) || (__last == __middle))
+ return;
+
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance;
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ _Distance __n = __last - __first;
+ _Distance __k = __middle - __first;
+ _Distance __l = __n - __k;
+
+ if (__k == __l) {
+ swap_ranges(__first, __middle, __middle);
+ return;
+ }
+
+ _Distance __d = __gcd(__n, __k);
+
+ for (_Distance __i = 0; __i < __d; __i++) {
+ _ValueType __tmp = *__first;
+ _RandomAccessIter __p = __first;
+
+ if (__k < __l) {
+ for (_Distance __j = 0; __j < __l/__d; __j++) {
+ if (__p > __first + __l) {
+ *__p = *(__p - __l);
+ __p -= __l;
+ }
+
+ *__p = *(__p + __k);
+ __p += __k;
+ }
+ }
+
+ else {
+ for (_Distance __j = 0; __j < __k/__d - 1; __j ++) {
+ if (__p < __last - __k) {
+ *__p = *(__p + __k);
+ __p += __k;
+ }
+
+ *__p = * (__p - __l);
+ __p -= __l;
+ }
+ }
+
+ *__p = __tmp;
+ ++__first;
+ }
+ }
+
+ /**
+ * @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)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+
+ typedef typename iterator_traits<_ForwardIter>::iterator_category _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,
+ _ForwardIter __last, _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ return copy(__first, __middle, copy(__middle, __last, __result));
+ }
+
+
+ /**
+ * @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)
+ {
+ #ifdef _GLIBCPP_HAVE_DRAND48
+ return lrand48() % __n;
+ #else
+ return rand() % __n;
+ #endif
+ }
+
+
+ /**
+ * @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)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+
+ if (__first == __last) return;
+ for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
+ 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,
+ _RandomNumberGenerator& __rand)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+
+ if (__first == __last) return;
+ for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
+ iter_swap(__i, __first + __rand((__i - __first) + 1));
+ }
+
+
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
+ template<typename _ForwardIter, typename _Predicate>
+ _ForwardIter
+ __partition(_ForwardIter __first, _ForwardIter __last,
+ _Predicate __pred,
+ forward_iterator_tag)
+ {
+ if (__first == __last) return __first;
+
+ while (__pred(*__first))
+ if (++__first == __last) return __first;
+
+ _ForwardIter __next = __first;
+
+ while (++__next != __last)
+ if (__pred(*__next)) {
+ swap(*__first, *__next);
+ ++__first;
+ }
+
+ return __first;
+ }
+
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
+ template<typename _BidirectionalIter, typename _Predicate>
+ _BidirectionalIter
+ __partition(_BidirectionalIter __first, _BidirectionalIter __last,
+ _Predicate __pred,
+ bidirectional_iterator_tag)
+ {
+ while (true) {
+ while (true)
+ if (__first == __last)
+ return __first;
+ else if (__pred(*__first))
+ ++__first;
+ else
+ break;
+ --__last;
+ while (true)
+ if (__first == __last)
+ return __first;
+ else if (!__pred(*__last))
+ --__last;
+ else
+ break;
+ iter_swap(__first, __last);
+ ++__first;
+ }
+ }
+
+ /**
+ * @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,
+ _Predicate __pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ return __partition(__first, __last, __pred, __iterator_category(__first));
+ }
+
+
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
+ template<typename _ForwardIter, typename _Predicate, typename _Distance>
+ _ForwardIter
+ __inplace_stable_partition(_ForwardIter __first, _ForwardIter __last,
+ _Predicate __pred, _Distance __len)
+ {
+ if (__len == 1)
+ return __pred(*__first) ? __last : __first;
+ _ForwardIter __middle = __first;
+ advance(__middle, __len / 2);
+ _ForwardIter __begin = __inplace_stable_partition(__first, __middle,
+ __pred,
+ __len / 2);
+ _ForwardIter __end = __inplace_stable_partition(__middle, __last,
+ __pred,
+ __len - __len / 2);
+ rotate(__begin, __middle, __end);
+ advance(__begin, distance(__middle, __end));
+ return __begin;
+ }
+
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
+ template<typename _ForwardIter, typename _Pointer, typename _Predicate,
+ typename _Distance>
+ _ForwardIter
+ __stable_partition_adaptive(_ForwardIter __first, _ForwardIter __last,
+ _Predicate __pred, _Distance __len,
+ _Pointer __buffer,
+ _Distance __buffer_size)
+ {
+ if (__len <= __buffer_size) {
+ _ForwardIter __result1 = __first;
+ _Pointer __result2 = __buffer;
+ for ( ; __first != __last ; ++__first)
+ if (__pred(*__first)) {
+ *__result1 = *__first;
+ ++__result1;
+ }
+ else {
+ *__result2 = *__first;
+ ++__result2;
+ }
+ copy(__buffer, __result2, __result1);
+ return __result1;
+ }
+ else {
+ _ForwardIter __middle = __first;
+ advance(__middle, __len / 2);
+ _ForwardIter __begin = __stable_partition_adaptive(__first, __middle,
+ __pred,
+ __len / 2,
+ __buffer, __buffer_size);
+ _ForwardIter __end = __stable_partition_adaptive( __middle, __last,
+ __pred,
+ __len - __len / 2,
+ __buffer, __buffer_size);
+ rotate(__begin, __middle, __end);
+ advance(__begin, distance(__middle, __end));
+ return __begin;
+ }
+ }
+
+ /**
+ * @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,
+ _Predicate __pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ if (__first == __last)
+ return __first;
+ else
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
+
+ _Temporary_buffer<_ForwardIter, _ValueType> __buf(__first, __last);
+ if (__buf.size() > 0)
+ return __stable_partition_adaptive(__first, __last, __pred,
+ _DistanceType(__buf.requested_size()),
+ __buf.begin(), __buf.size());
+ else
+ return __inplace_stable_partition(__first, __last, __pred,
+ _DistanceType(__buf.requested_size()));
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
+ template<typename _RandomAccessIter, typename _Tp>
+ _RandomAccessIter
+ __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Tp __pivot)
+ {
+ while (true) {
+ while (*__first < __pivot)
+ ++__first;
+ --__last;
+ while (__pivot < *__last)
+ --__last;
+ if (!(__first < __last))
+ return __first;
+ iter_swap(__first, __last);
+ ++__first;
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function...
+ * @endif
+ */
+ template<typename _RandomAccessIter, typename _Tp, typename _Compare>
+ _RandomAccessIter
+ __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Tp __pivot, _Compare __comp)
+ {
+ while (true) {
+ while (__comp(*__first, __pivot))
+ ++__first;
+ --__last;
+ while (__comp(__pivot, *__last))
+ --__last;
+ if (!(__first < __last))
+ return __first;
+ iter_swap(__first, __last);
+ ++__first;
+ }
+ }
+
+
+ /**
+ * @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)
+ {
+ _RandomAccessIter __next = __last;
+ --__next;
+ while (__val < *__next) {
+ *__last = *__next;
+ __last = __next;
+ --__next;
+ }
+ *__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)
+ {
+ _RandomAccessIter __next = __last;
+ --__next;
+ while (__comp(__val, *__next)) {
+ *__last = *__next;
+ __last = __next;
+ --__next;
+ }
+ *__last = __val;
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
+ template<typename _RandomAccessIter>
+ void
+ __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
+ {
+ if (__first == __last) return;
+
+ for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
+ {
+ typename iterator_traits<_RandomAccessIter>::value_type __val = *__i;
+ if (__val < *__first) {
+ copy_backward(__first, __i, __i + 1);
+ *__first = __val;
+ }
+ else
+ __unguarded_linear_insert(__i, __val);
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
+ template<typename _RandomAccessIter, typename _Compare>
+ void
+ __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Compare __comp)
+ {
+ if (__first == __last) return;
+
+ for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
+ {
+ typename iterator_traits<_RandomAccessIter>::value_type __val = *__i;
+ if (__comp(__val, *__first)) {
+ copy_backward(__first, __i, __i + 1);
+ *__first = __val;
+ }
+ else
+ __unguarded_linear_insert(__i, __val, __comp);
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the sort routine.
+ * @endif
+ */
+ template<typename _RandomAccessIter>
+ inline void
+ __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ for (_RandomAccessIter __i = __first; __i != __last; ++__i)
+ __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,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ for (_RandomAccessIter __i = __first; __i != __last; ++__i)
+ __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 > _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 > _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)
+ {
+ _Size __k;
+ for (__k = 0; __n != 1; __n >>= 1) ++__k;
+ 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,
+ _Size __depth_limit)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ while (__last - __first > _M_threshold) {
+ if (__depth_limit == 0) {
+ partial_sort(__first, __last, __last);
+ return;
+ }
+ --__depth_limit;
+ _RandomAccessIter __cut =
+ __unguarded_partition(__first, __last,
+ _ValueType(__median(*__first,
+ *(__first + (__last - __first)/2),
+ *(__last - 1))));
+ __introsort_loop(__cut, __last, __depth_limit);
+ __last = __cut;
+ }
+ }
+
+ /**
+ * @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,
+ _Size __depth_limit, _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ while (__last - __first > _M_threshold) {
+ if (__depth_limit == 0) {
+ partial_sort(__first, __last, __last, __comp);
+ return;
+ }
+ --__depth_limit;
+ _RandomAccessIter __cut =
+ __unguarded_partition(__first, __last,
+ _ValueType(__median(*__first,
+ *(__first + (__last - __first)/2),
+ *(__last - 1), __comp)),
+ __comp);
+ __introsort_loop(__cut, __last, __depth_limit, __comp);
+ __last = __cut;
+ }
+ }
+
+ /**
+ * @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)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ if (__first != __last) {
+ __introsort_loop(__first, __last, __lg(__last - __first) * 2);
+ __final_insertion_sort(__first, __last);
+ }
+ }
+
+ /**
+ * @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)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>)
+
+ if (__first != __last) {
+ __introsort_loop(__first, __last, __lg(__last - __first) * 2, __comp);
+ __final_insertion_sort(__first, __last, __comp);
+ }
+ }
+
+
+ /**
+ * @if maint
+ * This is a helper function for the stable sorting routines.
+ * @endif
+ */
+ template<typename _RandomAccessIter>
+ void
+ __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last)
+ {
+ if (__last - __first < 15) {
+ __insertion_sort(__first, __last);
+ return;
+ }
+ _RandomAccessIter __middle = __first + (__last - __first) / 2;
+ __inplace_stable_sort(__first, __middle);
+ __inplace_stable_sort(__middle, __last);
+ __merge_without_buffer(__first, __middle, __last,
+ __middle - __first,
+ __last - __middle);
+ }
+
+ /**
+ * @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,
+ _Compare __comp)
+ {
+ if (__last - __first < 15) {
+ __insertion_sort(__first, __last, __comp);
+ return;
+ }
+ _RandomAccessIter __middle = __first + (__last - __first) / 2;
+ __inplace_stable_sort(__first, __middle, __comp);
+ __inplace_stable_sort(__middle, __last, __comp);
+ __merge_without_buffer(__first, __middle, __last,
+ __middle - __first,
+ __last - __middle,
+ __comp);
+ }
+
+ template<typename _RandomAccessIter1, typename _RandomAccessIter2,
+ typename _Distance>
+ void
+ __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last,
+ _RandomAccessIter2 __result, _Distance __step_size)
+ {
+ _Distance __two_step = 2 * __step_size;
+
+ while (__last - __first >= __two_step) {
+ __result = merge(__first, __first + __step_size,
+ __first + __step_size, __first + __two_step,
+ __result);
+ __first += __two_step;
+ }
+
+ __step_size = min(_Distance(__last - __first), __step_size);
+ merge(__first, __first + __step_size, __first + __step_size, __last,
+ __result);
+ }
+
+ template<typename _RandomAccessIter1, typename _RandomAccessIter2,
+ typename _Distance, typename _Compare>
+ void
+ __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last,
+ _RandomAccessIter2 __result, _Distance __step_size,
+ _Compare __comp)
+ {
+ _Distance __two_step = 2 * __step_size;
+
+ while (__last - __first >= __two_step) {
+ __result = merge(__first, __first + __step_size,
+ __first + __step_size, __first + __two_step,
+ __result,
+ __comp);
+ __first += __two_step;
+ }
+ __step_size = min(_Distance(__last - __first), __step_size);
+
+ merge(__first, __first + __step_size,
+ __first + __step_size, __last,
+ __result,
+ __comp);
+ }
+
+ enum { _M_chunk_size = 7 };
+
+ template<typename _RandomAccessIter, typename _Distance>
+ void
+ __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Distance __chunk_size)
+ {
+ while (__last - __first >= __chunk_size) {
+ __insertion_sort(__first, __first + __chunk_size);
+ __first += __chunk_size;
+ }
+ __insertion_sort(__first, __last);
+ }
+
+ template<typename _RandomAccessIter, typename _Distance, typename _Compare>
+ void
+ __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Distance __chunk_size, _Compare __comp)
+ {
+ while (__last - __first >= __chunk_size) {
+ __insertion_sort(__first, __first + __chunk_size, __comp);
+ __first += __chunk_size;
+ }
+ __insertion_sort(__first, __last, __comp);
+ }
+
+ template<typename _RandomAccessIter, typename _Pointer>
+ void
+ __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Pointer __buffer)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance;
+
+ _Distance __len = __last - __first;
+ _Pointer __buffer_last = __buffer + __len;
+
+ _Distance __step_size = _M_chunk_size;
+ __chunk_insertion_sort(__first, __last, __step_size);
+
+ while (__step_size < __len) {
+ __merge_sort_loop(__first, __last, __buffer, __step_size);
+ __step_size *= 2;
+ __merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
+ __step_size *= 2;
+ }
+ }
+
+ template<typename _RandomAccessIter, typename _Pointer, typename _Compare>
+ void
+ __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Pointer __buffer, _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance;
+
+ _Distance __len = __last - __first;
+ _Pointer __buffer_last = __buffer + __len;
+
+ _Distance __step_size = _M_chunk_size;
+ __chunk_insertion_sort(__first, __last, __step_size, __comp);
+
+ while (__step_size < __len) {
+ __merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
+ __step_size *= 2;
+ __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
+ __step_size *= 2;
+ }
+ }
+
+ template<typename _RandomAccessIter, typename _Pointer, typename _Distance>
+ void
+ __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Pointer __buffer, _Distance __buffer_size)
+ {
+ _Distance __len = (__last - __first + 1) / 2;
+ _RandomAccessIter __middle = __first + __len;
+ if (__len > __buffer_size) {
+ __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size);
+ __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size);
+ }
+ else {
+ __merge_sort_with_buffer(__first, __middle, __buffer);
+ __merge_sort_with_buffer(__middle, __last, __buffer);
+ }
+ __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
+ _Distance(__last - __middle), __buffer, __buffer_size);
+ }
+
+ template<typename _RandomAccessIter, typename _Pointer, typename _Distance,
+ typename _Compare>
+ void
+ __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Pointer __buffer, _Distance __buffer_size,
+ _Compare __comp)
+ {
+ _Distance __len = (__last - __first + 1) / 2;
+ _RandomAccessIter __middle = __first + __len;
+ if (__len > __buffer_size) {
+ __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size,
+ __comp);
+ __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size,
+ __comp);
+ }
+ else {
+ __merge_sort_with_buffer(__first, __middle, __buffer, __comp);
+ __merge_sort_with_buffer(__middle, __last, __buffer, __comp);
+ }
+ __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
+ _Distance(__last - __middle), __buffer, __buffer_size,
+ __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)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ _Temporary_buffer<_RandomAccessIter, _ValueType> buf(__first, __last);
+ if (buf.begin() == 0)
+ __inplace_stable_sort(__first, __last);
+ else
+ __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)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ _ValueType, _ValueType>)
+
+ _Temporary_buffer<_RandomAccessIter, _ValueType> buf(__first, __last);
+ if (buf.begin() == 0)
+ __inplace_stable_sort(__first, __last, __comp);
+ else
+ __stable_sort_adaptive(__first, __last, buf.begin(), _DistanceType(buf.size()),
+ __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,
+ _RandomAccessIter __middle,
+ _RandomAccessIter __last)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ make_heap(__first, __middle);
+ for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
+ if (*__i < *__first)
+ __pop_heap(__first, __middle, __i, _ValueType(*__i));
+ 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,
+ _RandomAccessIter __middle,
+ _RandomAccessIter __last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ _ValueType, _ValueType>)
+
+ make_heap(__first, __middle, __comp);
+ for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
+ if (__comp(*__i, *__first))
+ __pop_heap(__first, __middle, __i, _ValueType(*__i), __comp);
+ 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,
+ _RandomAccessIter __result_first,
+ _RandomAccessIter __result_last)
+ {
+ typedef typename iterator_traits<_InputIter>::value_type _InputValueType;
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _OutputValueType;
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_OutputValueType>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_InputValueType>)
+
+ if (__result_first == __result_last) return __result_last;
+ _RandomAccessIter __result_real_last = __result_first;
+ while(__first != __last && __result_real_last != __result_last) {
+ *__result_real_last = *__first;
+ ++__result_real_last;
+ ++__first;
+ }
+ make_heap(__result_first, __result_real_last);
+ while (__first != __last) {
+ if (*__first < *__result_first)
+ __adjust_heap(__result_first, _DistanceType(0),
+ _DistanceType(__result_real_last - __result_first),
+ _InputValueType(*__first));
+ ++__first;
+ }
+ sort_heap(__result_first, __result_real_last);
+ 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,
+ _RandomAccessIter __result_first,
+ _RandomAccessIter __result_last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_InputIter>::value_type _InputValueType;
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _OutputValueType;
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>)
+ __glibcpp_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ _OutputValueType, _OutputValueType>)
+
+ if (__result_first == __result_last) return __result_last;
+ _RandomAccessIter __result_real_last = __result_first;
+ while(__first != __last && __result_real_last != __result_last) {
+ *__result_real_last = *__first;
+ ++__result_real_last;
+ ++__first;
+ }
+ make_heap(__result_first, __result_real_last, __comp);
+ while (__first != __last) {
+ if (__comp(*__first, *__result_first))
+ __adjust_heap(__result_first, _DistanceType(0),
+ _DistanceType(__result_real_last - __result_first),
+ _InputValueType(*__first),
+ __comp);
+ ++__first;
+ }
+ sort_heap(__result_first, __result_real_last, __comp);
+ 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,
+ _RandomAccessIter __nth,
+ _RandomAccessIter __last)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ while (__last - __first > 3) {
+ _RandomAccessIter __cut =
+ __unguarded_partition(__first, __last,
+ _ValueType(__median(*__first,
+ *(__first + (__last - __first)/2),
+ *(__last - 1))));
+ if (__cut <= __nth)
+ __first = __cut;
+ else
+ __last = __cut;
+ }
+ __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,
+ _RandomAccessIter __nth,
+ _RandomAccessIter __last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ _ValueType, _ValueType>)
+
+ while (__last - __first > 3) {
+ _RandomAccessIter __cut =
+ __unguarded_partition(__first, __last,
+ _ValueType(__median(*__first,
+ *(__first + (__last - __first)/2),
+ *(__last - 1),
+ __comp)),
+ __comp);
+ if (__cut <= __nth)
+ __first = __cut;
+ else
+ __last = __cut;
+ }
+ __insertion_sort(__first, __last, __comp);
+ }
+
+
+ /**
+ * @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)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
+
+ // concept requirements
+ // Note that these are slightly stricter than those of the 4-argument
+ // version, defined next. The difference is in the strictness of the
+ // comparison operations... so for looser checking, define your own
+ // comparison function, as was intended.
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
+
+ _DistanceType __len = distance(__first, __last);
+ _DistanceType __half;
+ _ForwardIter __middle;
+
+ while (__len > 0) {
+ __half = __len >> 1;
+ __middle = __first;
+ advance(__middle, __half);
+ if (*__middle < __val) {
+ __first = __middle;
+ ++__first;
+ __len = __len - __half - 1;
+ }
+ else
+ __len = __half;
+ }
+ return __first;
+ }
+
+ /**
+ * @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,
+ const _Tp& __val, _Compare __comp)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _Tp>)
+
+ _DistanceType __len = distance(__first, __last);
+ _DistanceType __half;
+ _ForwardIter __middle;
+
+ while (__len > 0) {
+ __half = __len >> 1;
+ __middle = __first;
+ advance(__middle, __half);
+ if (__comp(*__middle, __val)) {
+ __first = __middle;
+ ++__first;
+ __len = __len - __half - 1;
+ }
+ else
+ __len = __half;
+ }
+ return __first;
+ }
+
+ /**
+ * @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)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
+
+ // concept requirements
+ // See comments on lower_bound.
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
+
+ _DistanceType __len = distance(__first, __last);
+ _DistanceType __half;
+ _ForwardIter __middle;
+
+ while (__len > 0) {
+ __half = __len >> 1;
+ __middle = __first;
+ advance(__middle, __half);
+ if (__val < *__middle)
+ __len = __half;
+ else {
+ __first = __middle;
+ ++__first;
+ __len = __len - __half - 1;
+ }
+ }
+ return __first;
+ }
+
+ /**
+ * @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,
+ const _Tp& __val, _Compare __comp)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _ValueType>)
+
+ _DistanceType __len = distance(__first, __last);
+ _DistanceType __half;
+ _ForwardIter __middle;
+
+ while (__len > 0) {
+ __half = __len >> 1;
+ __middle = __first;
+ advance(__middle, __half);
+ if (__comp(__val, *__middle))
+ __len = __half;
+ else {
+ __first = __middle;
+ ++__first;
+ __len = __len - __half - 1;
+ }
+ }
+ return __first;
+ }
+
+ /**
+ * @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)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
+
+ // concept requirements
+ // See comments on lower_bound.
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
+
+ _DistanceType __len = distance(__first, __last);
+ _DistanceType __half;
+ _ForwardIter __middle, __left, __right;
+
+ while (__len > 0) {
+ __half = __len >> 1;
+ __middle = __first;
+ advance(__middle, __half);
+ if (*__middle < __val) {
+ __first = __middle;
+ ++__first;
+ __len = __len - __half - 1;
+ }
+ else if (__val < *__middle)
+ __len = __half;
+ else {
+ __left = lower_bound(__first, __middle, __val);
+ advance(__first, __len);
+ __right = upper_bound(++__middle, __first, __val);
+ return pair<_ForwardIter, _ForwardIter>(__left, __right);
+ }
+ }
+ return pair<_ForwardIter, _ForwardIter>(__first, __first);
+ }
+
+ /**
+ * @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,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _Tp>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _ValueType>)
+
+ _DistanceType __len = distance(__first, __last);
+ _DistanceType __half;
+ _ForwardIter __middle, __left, __right;
+
+ while (__len > 0) {
+ __half = __len >> 1;
+ __middle = __first;
+ advance(__middle, __half);
+ if (__comp(*__middle, __val)) {
+ __first = __middle;
+ ++__first;
+ __len = __len - __half - 1;
+ }
+ else if (__comp(__val, *__middle))
+ __len = __half;
+ else {
+ __left = lower_bound(__first, __middle, __val, __comp);
+ advance(__first, __len);
+ __right = upper_bound(++__middle, __first, __val, __comp);
+ return pair<_ForwardIter, _ForwardIter>(__left, __right);
+ }
+ }
+ return pair<_ForwardIter, _ForwardIter>(__first, __first);
+ }
+
+ /**
+ * @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,
+ const _Tp& __val)
+ {
+ // concept requirements
+ // See comments on lower_bound.
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_SameTypeConcept<_Tp,
+ typename iterator_traits<_ForwardIter>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
+
+ _ForwardIter __i = lower_bound(__first, __last, __val);
+ 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,
+ const _Tp& __val, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_ForwardIter>::value_type, _Tp>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ _ForwardIter __i = lower_bound(__first, __last, __val, __comp);
+ return __i != __last && !__comp(__val, *__i);
+ }
+
+ /**
+ * @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,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (*__first2 < *__first1) {
+ *__result = *__first2;
+ ++__first2;
+ }
+ else {
+ *__result = *__first1;
+ ++__first1;
+ }
+ ++__result;
+ }
+ 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
+ merge(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (__comp(*__first2, *__first1)) {
+ *__result = *__first2;
+ ++__first2;
+ }
+ else {
+ *__result = *__first1;
+ ++__first1;
+ }
+ ++__result;
+ }
+ return copy(__first2, __last2, copy(__first1, __last1, __result));
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
+ template<typename _BidirectionalIter, typename _Distance>
+ void
+ __merge_without_buffer(_BidirectionalIter __first,
+ _BidirectionalIter __middle,
+ _BidirectionalIter __last,
+ _Distance __len1, _Distance __len2)
+ {
+ if (__len1 == 0 || __len2 == 0)
+ return;
+ if (__len1 + __len2 == 2) {
+ if (*__middle < *__first)
+ iter_swap(__first, __middle);
+ return;
+ }
+ _BidirectionalIter __first_cut = __first;
+ _BidirectionalIter __second_cut = __middle;
+ _Distance __len11 = 0;
+ _Distance __len22 = 0;
+ if (__len1 > __len2) {
+ __len11 = __len1 / 2;
+ advance(__first_cut, __len11);
+ __second_cut = lower_bound(__middle, __last, *__first_cut);
+ __len22 = distance(__middle, __second_cut);
+ }
+ else {
+ __len22 = __len2 / 2;
+ advance(__second_cut, __len22);
+ __first_cut = upper_bound(__first, __middle, *__second_cut);
+ __len11 = distance(__first, __first_cut);
+ }
+ rotate(__first_cut, __middle, __second_cut);
+ _BidirectionalIter __new_middle = __first_cut;
+ advance(__new_middle, distance(__middle, __second_cut));
+ __merge_without_buffer(__first, __first_cut, __new_middle,
+ __len11, __len22);
+ __merge_without_buffer(__new_middle, __second_cut, __last,
+ __len1 - __len11, __len2 - __len22);
+ }
+
+ /**
+ * @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,
+ _BidirectionalIter __middle,
+ _BidirectionalIter __last,
+ _Distance __len1, _Distance __len2,
+ _Compare __comp)
+ {
+ if (__len1 == 0 || __len2 == 0)
+ return;
+ if (__len1 + __len2 == 2) {
+ if (__comp(*__middle, *__first))
+ iter_swap(__first, __middle);
+ return;
+ }
+ _BidirectionalIter __first_cut = __first;
+ _BidirectionalIter __second_cut = __middle;
+ _Distance __len11 = 0;
+ _Distance __len22 = 0;
+ if (__len1 > __len2) {
+ __len11 = __len1 / 2;
+ advance(__first_cut, __len11);
+ __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
+ __len22 = distance(__middle, __second_cut);
+ }
+ else {
+ __len22 = __len2 / 2;
+ advance(__second_cut, __len22);
+ __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
+ __len11 = distance(__first, __first_cut);
+ }
+ rotate(__first_cut, __middle, __second_cut);
+ _BidirectionalIter __new_middle = __first_cut;
+ advance(__new_middle, distance(__middle, __second_cut));
+ __merge_without_buffer(__first, __first_cut, __new_middle,
+ __len11, __len22, __comp);
+ __merge_without_buffer(__new_middle, __second_cut, __last,
+ __len1 - __len11, __len2 - __len22, __comp);
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
+ template<typename _BidirectionalIter1, typename _BidirectionalIter2,
+ typename _Distance>
+ _BidirectionalIter1
+ __rotate_adaptive(_BidirectionalIter1 __first,
+ _BidirectionalIter1 __middle,
+ _BidirectionalIter1 __last,
+ _Distance __len1, _Distance __len2,
+ _BidirectionalIter2 __buffer,
+ _Distance __buffer_size)
+ {
+ _BidirectionalIter2 __buffer_end;
+ if (__len1 > __len2 && __len2 <= __buffer_size) {
+ __buffer_end = copy(__middle, __last, __buffer);
+ copy_backward(__first, __middle, __last);
+ return copy(__buffer, __buffer_end, __first);
+ }
+ else if (__len1 <= __buffer_size) {
+ __buffer_end = copy(__first, __middle, __buffer);
+ copy(__middle, __last, __first);
+ return copy_backward(__buffer, __buffer_end, __last);
+ }
+ else {
+ rotate(__first, __middle, __last);
+ advance(__first, distance(__middle, __last));
+ return __first;
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
+ template<typename _BidirectionalIter1, typename _BidirectionalIter2,
+ typename _BidirectionalIter3>
+ _BidirectionalIter3
+ __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
+ _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
+ _BidirectionalIter3 __result)
+ {
+ if (__first1 == __last1)
+ return copy_backward(__first2, __last2, __result);
+ if (__first2 == __last2)
+ return copy_backward(__first1, __last1, __result);
+ --__last1;
+ --__last2;
+ while (true) {
+ if (*__last2 < *__last1) {
+ *--__result = *__last1;
+ if (__first1 == __last1)
+ return copy_backward(__first2, ++__last2, __result);
+ --__last1;
+ }
+ else {
+ *--__result = *__last2;
+ if (__first2 == __last2)
+ return copy_backward(__first1, ++__last1, __result);
+ --__last2;
+ }
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
+ template<typename _BidirectionalIter1, typename _BidirectionalIter2,
+ typename _BidirectionalIter3, typename _Compare>
+ _BidirectionalIter3
+ __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
+ _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
+ _BidirectionalIter3 __result,
+ _Compare __comp)
+ {
+ if (__first1 == __last1)
+ return copy_backward(__first2, __last2, __result);
+ if (__first2 == __last2)
+ return copy_backward(__first1, __last1, __result);
+ --__last1;
+ --__last2;
+ while (true) {
+ if (__comp(*__last2, *__last1)) {
+ *--__result = *__last1;
+ if (__first1 == __last1)
+ return copy_backward(__first2, ++__last2, __result);
+ --__last1;
+ }
+ else {
+ *--__result = *__last2;
+ if (__first2 == __last2)
+ return copy_backward(__first1, ++__last1, __result);
+ --__last2;
+ }
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
+ template<typename _BidirectionalIter, typename _Distance, typename _Pointer>
+ void
+ __merge_adaptive(_BidirectionalIter __first,
+ _BidirectionalIter __middle,
+ _BidirectionalIter __last,
+ _Distance __len1, _Distance __len2,
+ _Pointer __buffer, _Distance __buffer_size)
+ {
+ if (__len1 <= __len2 && __len1 <= __buffer_size) {
+ _Pointer __buffer_end = copy(__first, __middle, __buffer);
+ merge(__buffer, __buffer_end, __middle, __last, __first);
+ }
+ else if (__len2 <= __buffer_size) {
+ _Pointer __buffer_end = copy(__middle, __last, __buffer);
+ __merge_backward(__first, __middle, __buffer, __buffer_end, __last);
+ }
+ else {
+ _BidirectionalIter __first_cut = __first;
+ _BidirectionalIter __second_cut = __middle;
+ _Distance __len11 = 0;
+ _Distance __len22 = 0;
+ if (__len1 > __len2) {
+ __len11 = __len1 / 2;
+ advance(__first_cut, __len11);
+ __second_cut = lower_bound(__middle, __last, *__first_cut);
+ __len22 = distance(__middle, __second_cut);
+ }
+ else {
+ __len22 = __len2 / 2;
+ advance(__second_cut, __len22);
+ __first_cut = upper_bound(__first, __middle, *__second_cut);
+ __len11 = distance(__first, __first_cut);
+ }
+ _BidirectionalIter __new_middle =
+ __rotate_adaptive(__first_cut, __middle, __second_cut,
+ __len1 - __len11, __len22, __buffer,
+ __buffer_size);
+ __merge_adaptive(__first, __first_cut, __new_middle, __len11,
+ __len22, __buffer, __buffer_size);
+ __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
+ __len2 - __len22, __buffer, __buffer_size);
+ }
+ }
+
+ /**
+ * @if maint
+ * This is a helper function for the merge routines.
+ * @endif
+ */
+ template<typename _BidirectionalIter, typename _Distance, typename _Pointer,
+ typename _Compare>
+ void
+ __merge_adaptive(_BidirectionalIter __first,
+ _BidirectionalIter __middle,
+ _BidirectionalIter __last,
+ _Distance __len1, _Distance __len2,
+ _Pointer __buffer, _Distance __buffer_size,
+ _Compare __comp)
+ {
+ if (__len1 <= __len2 && __len1 <= __buffer_size) {
+ _Pointer __buffer_end = copy(__first, __middle, __buffer);
+ merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
+ }
+ else if (__len2 <= __buffer_size) {
+ _Pointer __buffer_end = copy(__middle, __last, __buffer);
+ __merge_backward(__first, __middle, __buffer, __buffer_end, __last,
+ __comp);
+ }
+ else {
+ _BidirectionalIter __first_cut = __first;
+ _BidirectionalIter __second_cut = __middle;
+ _Distance __len11 = 0;
+ _Distance __len22 = 0;
+ if (__len1 > __len2) {
+ __len11 = __len1 / 2;
+ advance(__first_cut, __len11);
+ __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
+ __len22 = distance(__middle, __second_cut);
+ }
+ else {
+ __len22 = __len2 / 2;
+ advance(__second_cut, __len22);
+ __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
+ __len11 = distance(__first, __first_cut);
+ }
+ _BidirectionalIter __new_middle =
+ __rotate_adaptive(__first_cut, __middle, __second_cut,
+ __len1 - __len11, __len22, __buffer,
+ __buffer_size);
+ __merge_adaptive(__first, __first_cut, __new_middle, __len11,
+ __len22, __buffer, __buffer_size, __comp);
+ __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
+ __len2 - __len22, __buffer, __buffer_size, __comp);
+ }
+ }
+
+ /**
+ * @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,
+ _BidirectionalIter __middle,
+ _BidirectionalIter __last)
+ {
+ typedef typename iterator_traits<_BidirectionalIter>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_BidirectionalIter>::difference_type
+ _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
+ _BidirectionalIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ if (__first == __middle || __middle == __last)
+ return;
+
+ _DistanceType __len1 = distance(__first, __middle);
+ _DistanceType __len2 = distance(__middle, __last);
+
+ _Temporary_buffer<_BidirectionalIter, _ValueType> __buf(__first, __last);
+ if (__buf.begin() == 0)
+ __merge_without_buffer(__first, __middle, __last, __len1, __len2);
+ else
+ __merge_adaptive(__first, __middle, __last, __len1, __len2,
+ __buf.begin(), _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,
+ _BidirectionalIter __middle,
+ _BidirectionalIter __last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_BidirectionalIter>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_BidirectionalIter>::difference_type
+ _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
+ _BidirectionalIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ _ValueType, _ValueType>)
+
+ if (__first == __middle || __middle == __last)
+ return;
+
+ _DistanceType __len1 = distance(__first, __middle);
+ _DistanceType __len2 = distance(__middle, __last);
+
+ _Temporary_buffer<_BidirectionalIter, _ValueType> __buf(__first, __last);
+ if (__buf.begin() == 0)
+ __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp);
+ else
+ __merge_adaptive(__first, __middle, __last, __len1, __len2,
+ __buf.begin(), _DistanceType(__buf.size()),
+ __comp);
+ }
+
+ // Set algorithms: includes, set_union, set_intersection, set_difference,
+ // set_symmetric_difference. All of these algorithms have the precondition
+ // that their input ranges are sorted and the postcondition that their output
+ // ranges are sorted.
+
+ template<typename _InputIter1, typename _InputIter2>
+ bool
+ includes(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first2 < *__first1)
+ return false;
+ else if(*__first1 < *__first2)
+ ++__first1;
+ else
+ ++__first1, ++__first2;
+
+ return __first2 == __last2;
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _Compare>
+ bool
+ includes(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first2, *__first1))
+ return false;
+ else if(__comp(*__first1, *__first2))
+ ++__first1;
+ else
+ ++__first1, ++__first2;
+
+ return __first2 == __last2;
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
+ _OutputIter
+ set_union(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (*__first1 < *__first2) {
+ *__result = *__first1;
+ ++__first1;
+ }
+ else if (*__first2 < *__first1) {
+ *__result = *__first2;
+ ++__first2;
+ }
+ else {
+ *__result = *__first1;
+ ++__first1;
+ ++__first2;
+ }
+ ++__result;
+ }
+ return copy(__first2, __last2, copy(__first1, __last1, __result));
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
+ typename _Compare>
+ _OutputIter
+ set_union(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (__comp(*__first1, *__first2)) {
+ *__result = *__first1;
+ ++__first1;
+ }
+ else if (__comp(*__first2, *__first1)) {
+ *__result = *__first2;
+ ++__first2;
+ }
+ else {
+ *__result = *__first1;
+ ++__first1;
+ ++__first2;
+ }
+ ++__result;
+ }
+ return copy(__first2, __last2, copy(__first1, __last1, __result));
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
+ _OutputIter
+ set_intersection(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first1 < *__first2)
+ ++__first1;
+ else if (*__first2 < *__first1)
+ ++__first2;
+ else {
+ *__result = *__first1;
+ ++__first1;
+ ++__first2;
+ ++__result;
+ }
+ return __result;
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
+ typename _Compare>
+ _OutputIter
+ set_intersection(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first1, *__first2))
+ ++__first1;
+ else if (__comp(*__first2, *__first1))
+ ++__first2;
+ else {
+ *__result = *__first1;
+ ++__first1;
+ ++__first2;
+ ++__result;
+ }
+ return __result;
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
+ _OutputIter
+ set_difference(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first1 < *__first2) {
+ *__result = *__first1;
+ ++__first1;
+ ++__result;
+ }
+ else if (*__first2 < *__first1)
+ ++__first2;
+ else {
+ ++__first1;
+ ++__first2;
+ }
+ return copy(__first1, __last1, __result);
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
+ typename _Compare>
+ _OutputIter
+ set_difference(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first1, *__first2)) {
+ *__result = *__first1;
+ ++__first1;
+ ++__result;
+ }
+ else if (__comp(*__first2, *__first1))
+ ++__first2;
+ else {
+ ++__first1;
+ ++__first2;
+ }
+ return copy(__first1, __last1, __result);
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
+ _OutputIter
+ set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first1 < *__first2) {
+ *__result = *__first1;
+ ++__first1;
+ ++__result;
+ }
+ else if (*__first2 < *__first1) {
+ *__result = *__first2;
+ ++__first2;
+ ++__result;
+ }
+ else {
+ ++__first1;
+ ++__first2;
+ }
+ return copy(__first2, __last2, copy(__first1, __last1, __result));
+ }
+
+ template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
+ typename _Compare>
+ _OutputIter
+ set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _OutputIter __result,
+ _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_SameTypeConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first1, *__first2)) {
+ *__result = *__first1;
+ ++__first1;
+ ++__result;
+ }
+ else if (__comp(*__first2, *__first1)) {
+ *__result = *__first2;
+ ++__first2;
+ ++__result;
+ }
+ else {
+ ++__first1;
+ ++__first2;
+ }
+ return copy(__first2, __last2, copy(__first1, __last1, __result));
+ }
+
+ // min_element and max_element, with and without an explicitly supplied
+ // comparison function.
+
+ template<typename _ForwardIter>
+ _ForwardIter
+ max_element(_ForwardIter __first, _ForwardIter __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ if (__first == __last) return __first;
+ _ForwardIter __result = __first;
+ while (++__first != __last)
+ if (*__result < *__first)
+ __result = __first;
+ return __result;
+ }
+
+ template<typename _ForwardIter, typename _Compare>
+ _ForwardIter
+ max_element(_ForwardIter __first, _ForwardIter __last,
+ _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_ForwardIter>::value_type,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ if (__first == __last) return __first;
+ _ForwardIter __result = __first;
+ while (++__first != __last)
+ if (__comp(*__result, *__first)) __result = __first;
+ return __result;
+ }
+
+ template<typename _ForwardIter>
+ _ForwardIter
+ min_element(_ForwardIter __first, _ForwardIter __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ if (__first == __last) return __first;
+ _ForwardIter __result = __first;
+ while (++__first != __last)
+ if (*__first < *__result)
+ __result = __first;
+ return __result;
+ }
+
+ template<typename _ForwardIter, typename _Compare>
+ _ForwardIter
+ min_element(_ForwardIter __first, _ForwardIter __last,
+ _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_ForwardIter>::value_type,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ if (__first == __last) return __first;
+ _ForwardIter __result = __first;
+ while (++__first != __last)
+ if (__comp(*__first, *__result))
+ __result = __first;
+ return __result;
+ }
+
+ // next_permutation and prev_permutation, with and without an explicitly
+ // supplied comparison function.
+
+ template<typename _BidirectionalIter>
+ bool
+ next_permutation(_BidirectionalIter __first, _BidirectionalIter __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_BidirectionalIter>::value_type>)
+
+ if (__first == __last)
+ return false;
+ _BidirectionalIter __i = __first;
+ ++__i;
+ if (__i == __last)
+ return false;
+ __i = __last;
+ --__i;
+
+ for(;;) {
+ _BidirectionalIter __ii = __i;
+ --__i;
+ if (*__i < *__ii) {
+ _BidirectionalIter __j = __last;
+ while (!(*__i < *--__j))
+ {}
+ iter_swap(__i, __j);
+ reverse(__ii, __last);
+ return true;
+ }
+ if (__i == __first) {
+ reverse(__first, __last);
+ return false;
+ }
+ }
+ }
+
+ template<typename _BidirectionalIter, typename _Compare>
+ bool
+ next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
+ _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_BidirectionalIter>::value_type,
+ typename iterator_traits<_BidirectionalIter>::value_type>)
+
+ if (__first == __last)
+ return false;
+ _BidirectionalIter __i = __first;
+ ++__i;
+ if (__i == __last)
+ return false;
+ __i = __last;
+ --__i;
+
+ for(;;) {
+ _BidirectionalIter __ii = __i;
+ --__i;
+ if (__comp(*__i, *__ii)) {
+ _BidirectionalIter __j = __last;
+ while (!__comp(*__i, *--__j))
+ {}
+ iter_swap(__i, __j);
+ reverse(__ii, __last);
+ return true;
+ }
+ if (__i == __first) {
+ reverse(__first, __last);
+ return false;
+ }
+ }
+ }
+
+ template<typename _BidirectionalIter>
+ bool
+ prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_BidirectionalIter>::value_type>)
+
+ if (__first == __last)
+ return false;
+ _BidirectionalIter __i = __first;
+ ++__i;
+ if (__i == __last)
+ return false;
+ __i = __last;
+ --__i;
+
+ for(;;) {
+ _BidirectionalIter __ii = __i;
+ --__i;
+ if (*__ii < *__i) {
+ _BidirectionalIter __j = __last;
+ while (!(*--__j < *__i))
+ {}
+ iter_swap(__i, __j);
+ reverse(__ii, __last);
+ return true;
+ }
+ if (__i == __first) {
+ reverse(__first, __last);
+ return false;
+ }
+ }
+ }
+
+ template<typename _BidirectionalIter, typename _Compare>
+ bool
+ prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
+ _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_BidirectionalIter>::value_type,
+ typename iterator_traits<_BidirectionalIter>::value_type>)
+
+ if (__first == __last)
+ return false;
+ _BidirectionalIter __i = __first;
+ ++__i;
+ if (__i == __last)
+ return false;
+ __i = __last;
+ --__i;
+
+ for(;;) {
+ _BidirectionalIter __ii = __i;
+ --__i;
+ if (__comp(*__ii, *__i)) {
+ _BidirectionalIter __j = __last;
+ while (!__comp(*--__j, *__i))
+ {}
+ iter_swap(__i, __j);
+ reverse(__ii, __last);
+ return true;
+ }
+ if (__i == __first) {
+ reverse(__first, __last);
+ return false;
+ }
+ }
+ }
+
+ // find_first_of, with and without an explicitly supplied comparison function.
+
+ template<typename _InputIter, typename _ForwardIter>
+ _InputIter
+ find_first_of(_InputIter __first1, _InputIter __last1,
+ _ForwardIter __first2, _ForwardIter __last2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_InputIter>::value_type,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ for ( ; __first1 != __last1; ++__first1)
+ for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
+ if (*__first1 == *__iter)
+ return __first1;
+ return __last1;
+ }
+
+ template<typename _InputIter, typename _ForwardIter, typename _BinaryPredicate>
+ _InputIter
+ find_first_of(_InputIter __first1, _InputIter __last1,
+ _ForwardIter __first2, _ForwardIter __last2,
+ _BinaryPredicate __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_InputIter>::value_type,
+ typename iterator_traits<_ForwardIter>::value_type>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_InputIter>::value_type,
+ typename iterator_traits<_ForwardIter>::value_type>)
+
+ for ( ; __first1 != __last1; ++__first1)
+ for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
+ if (__comp(*__first1, *__iter))
+ return __first1;
+ return __last1;
+ }
+
+
+ // find_end, with and without an explicitly supplied comparison function.
+ // Search [first2, last2) as a subsequence in [first1, last1), and return
+ // the *last* possible match. Note that find_end for bidirectional iterators
+ // is much faster than for forward iterators.
+
+ // find_end for forward iterators.
+ template<typename _ForwardIter1, typename _ForwardIter2>
+ _ForwardIter1
+ __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
+ _ForwardIter2 __first2, _ForwardIter2 __last2,
+ forward_iterator_tag, forward_iterator_tag)
+ {
+ if (__first2 == __last2)
+ return __last1;
+ else {
+ _ForwardIter1 __result = __last1;
+ while (1) {
+ _ForwardIter1 __new_result
+ = search(__first1, __last1, __first2, __last2);
+ if (__new_result == __last1)
+ return __result;
+ else {
+ __result = __new_result;
+ __first1 = __new_result;
+ ++__first1;
+ }
+ }
+ }
+ }
+
+ template<typename _ForwardIter1, typename _ForwardIter2,
+ typename _BinaryPredicate>
+ _ForwardIter1
+ __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
+ _ForwardIter2 __first2, _ForwardIter2 __last2,
+ forward_iterator_tag, forward_iterator_tag,
+ _BinaryPredicate __comp)
+ {
+ if (__first2 == __last2)
+ return __last1;
+ else {
+ _ForwardIter1 __result = __last1;
+ while (1) {
+ _ForwardIter1 __new_result
+ = search(__first1, __last1, __first2, __last2, __comp);
+ if (__new_result == __last1)
+ return __result;
+ else {
+ __result = __new_result;
+ __first1 = __new_result;
+ ++__first1;
+ }
+ }
+ }
+ }
+
+ // find_end for bidirectional iterators. Requires partial specialization.
+ template<typename _BidirectionalIter1, typename _BidirectionalIter2>
+ _BidirectionalIter1
+ __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
+ _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
+ bidirectional_iterator_tag, bidirectional_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter1>)
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter2>)
+
+ typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
+ typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
+
+ _RevIter1 __rlast1(__first1);
+ _RevIter2 __rlast2(__first2);
+ _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
+ _RevIter2(__last2), __rlast2);
+
+ if (__rresult == __rlast1)
+ return __last1;
+ else {
+ _BidirectionalIter1 __result = __rresult.base();
+ advance(__result, -distance(__first2, __last2));
+ return __result;
+ }
+ }
+
+ template<typename _BidirectionalIter1, typename _BidirectionalIter2,
+ typename _BinaryPredicate>
+ _BidirectionalIter1
+ __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
+ _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
+ bidirectional_iterator_tag, bidirectional_iterator_tag,
+ _BinaryPredicate __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter1>)
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter2>)
+
+ typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
+ typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
+
+ _RevIter1 __rlast1(__first1);
+ _RevIter2 __rlast2(__first2);
+ _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
+ _RevIter2(__last2), __rlast2,
+ __comp);
+
+ if (__rresult == __rlast1)
+ return __last1;
+ else {
+ _BidirectionalIter1 __result = __rresult.base();
+ advance(__result, -distance(__first2, __last2));
+ return __result;
+ }
+ }
+
+ // Dispatching functions for find_end.
+
+ template<typename _ForwardIter1, typename _ForwardIter2>
+ inline _ForwardIter1
+ find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
+ _ForwardIter2 __first2, _ForwardIter2 __last2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>)
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_ForwardIter1>::value_type,
+ typename iterator_traits<_ForwardIter2>::value_type>)
+
+ return __find_end(__first1, __last1, __first2, __last2,
+ __iterator_category(__first1),
+ __iterator_category(__first2));
+ }
+
+ template<typename _ForwardIter1, typename _ForwardIter2,
+ typename _BinaryPredicate>
+ inline _ForwardIter1
+ find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
+ _ForwardIter2 __first2, _ForwardIter2 __last2,
+ _BinaryPredicate __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>)
+ __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>)
+ __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_ForwardIter1>::value_type,
+ typename iterator_traits<_ForwardIter2>::value_type>)
+
+ return __find_end(__first1, __last1, __first2, __last2,
+ __iterator_category(__first1),
+ __iterator_category(__first2),
+ __comp);
+ }
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_ALGO_H */
+
diff --git a/contrib/libstdc++/include/bits/stl_algobase.h b/contrib/libstdc++/include/bits/stl_algobase.h
new file mode 100644
index 0000000000000..6e488eae355f2
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_algobase.h
@@ -0,0 +1,820 @@
+// Bits and pieces used in algorithms -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996-1998
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_algobase.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_ALGOBASE_H
+#define __GLIBCPP_INTERNAL_ALGOBASE_H
+
+#include <bits/c++config.h>
+#include <cstring>
+#include <climits>
+#include <cstdlib>
+#include <cstddef>
+#include <new>
+#include <iosfwd>
+#include <bits/stl_pair.h>
+#include <bits/type_traits.h>
+#include <bits/stl_iterator_base_types.h>
+#include <bits/stl_iterator_base_funcs.h>
+#include <bits/stl_iterator.h>
+#include <bits/concept_check.h>
+
+namespace std
+{
+ // swap and iter_swap
+
+ /**
+ * @brief Swaps the contents of two iterators.
+ * @param a An iterator.
+ * @param b Another iterator.
+ * @return Nothing.
+ *
+ * This function swaps the values pointed to by two iterators, not the
+ * iterators themselves.
+ */
+ template<typename _ForwardIter1, typename _ForwardIter2>
+ inline void
+ iter_swap(_ForwardIter1 __a, _ForwardIter2 __b)
+ {
+ typedef typename iterator_traits<_ForwardIter1>::value_type _ValueType1;
+ typedef typename iterator_traits<_ForwardIter2>::value_type _ValueType2;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter1>)
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter2>)
+ __glibcpp_function_requires(_ConvertibleConcept<_ValueType1, _ValueType2>)
+ __glibcpp_function_requires(_ConvertibleConcept<_ValueType2, _ValueType1>)
+
+ _ValueType1 __tmp = *__a;
+ *__a = *__b;
+ *__b = __tmp;
+ }
+
+ /**
+ * @brief Swaps two values.
+ * @param a A thing of arbitrary type.
+ * @param b Another thing of arbitrary type.
+ * @return Nothing.
+ *
+ * This is the simple classic generic implementation. It will work on
+ * any type which has a copy constructor and an assignment operator.
+ */
+ template<typename _Tp>
+ inline void
+ swap(_Tp& __a, _Tp& __b)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_SGIAssignableConcept<_Tp>)
+
+ _Tp __tmp = __a;
+ __a = __b;
+ __b = __tmp;
+ }
+
+ //--------------------------------------------------
+ // min and max
+
+ #undef min
+ #undef max
+
+ /**
+ * @brief This does what you think it does.
+ * @param a A thing of arbitrary type.
+ * @param b Another thing of arbitrary type.
+ * @return The lesser of the parameters.
+ *
+ * This is the simple classic generic implementation. It will work on
+ * temporary expressions, since they are only evaluated once, unlike a
+ * preprocessor macro.
+ */
+ template<typename _Tp>
+ inline const _Tp&
+ min(const _Tp& __a, const _Tp& __b)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
+ //return __b < __a ? __b : __a;
+ if (__b < __a) return __b; return __a;
+ }
+
+ /**
+ * @brief This does what you think it does.
+ * @param a A thing of arbitrary type.
+ * @param b Another thing of arbitrary type.
+ * @return The greater of the parameters.
+ *
+ * This is the simple classic generic implementation. It will work on
+ * temporary expressions, since they are only evaluated once, unlike a
+ * preprocessor macro.
+ */
+ template<typename _Tp>
+ inline const _Tp&
+ max(const _Tp& __a, const _Tp& __b)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
+ //return __a < __b ? __b : __a;
+ if (__a < __b) return __b; return __a;
+ }
+
+ /**
+ * @brief This does what you think it does.
+ * @param a A thing of arbitrary type.
+ * @param b Another thing of arbitrary type.
+ * @param comp A @link s20_3_3_comparisons comparison functor@endlink.
+ * @return The lesser of the parameters.
+ *
+ * This will work on temporary expressions, since they are only evaluated
+ * once, unlike a preprocessor macro.
+ */
+ template<typename _Tp, typename _Compare>
+ inline const _Tp&
+ min(const _Tp& __a, const _Tp& __b, _Compare __comp)
+ {
+ //return __comp(__b, __a) ? __b : __a;
+ if (__comp(__b, __a)) return __b; return __a;
+ }
+
+ /**
+ * @brief This does what you think it does.
+ * @param a A thing of arbitrary type.
+ * @param b Another thing of arbitrary type.
+ * @param comp A @link s20_3_3_comparisons comparison functor@endlink.
+ * @return The greater of the parameters.
+ *
+ * This will work on temporary expressions, since they are only evaluated
+ * once, unlike a preprocessor macro.
+ */
+ template<typename _Tp, typename _Compare>
+ inline const _Tp&
+ max(const _Tp& __a, const _Tp& __b, _Compare __comp)
+ {
+ //return __comp(__a, __b) ? __b : __a;
+ if (__comp(__a, __b)) return __b; return __a;
+ }
+
+ //--------------------------------------------------
+ // copy
+
+ // All of these auxiliary functions serve two purposes. (1) Replace
+ // calls to copy with memmove whenever possible. (Memmove, not memcpy,
+ // because the input and output ranges are permitted to overlap.)
+ // (2) If we're using random access iterators, then write the loop as
+ // a for loop with an explicit count.
+
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ __copy(_InputIter __first, _InputIter __last,
+ _OutputIter __result,
+ input_iterator_tag)
+ {
+ for ( ; __first != __last; ++__result, ++__first)
+ *__result = *__first;
+ return __result;
+ }
+
+ template<typename _RandomAccessIter, typename _OutputIter>
+ inline _OutputIter
+ __copy(_RandomAccessIter __first, _RandomAccessIter __last,
+ _OutputIter __result,
+ random_access_iterator_tag)
+ {
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type
+ _Distance;
+ for (_Distance __n = __last - __first; __n > 0; --__n) {
+ *__result = *__first;
+ ++__first;
+ ++__result;
+ }
+ return __result;
+ }
+
+ template<typename _Tp>
+ inline _Tp*
+ __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result)
+ {
+ memmove(__result, __first, sizeof(_Tp) * (__last - __first));
+ return __result + (__last - __first);
+ }
+
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ __copy_aux2(_InputIter __first, _InputIter __last,
+ _OutputIter __result, __false_type)
+ { return __copy(__first, __last, __result, __iterator_category(__first)); }
+
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ __copy_aux2(_InputIter __first, _InputIter __last,
+ _OutputIter __result, __true_type)
+ { return __copy(__first, __last, __result, __iterator_category(__first)); }
+
+ template<typename _Tp>
+ inline _Tp*
+ __copy_aux2(_Tp* __first, _Tp* __last,
+ _Tp* __result, __true_type)
+ { return __copy_trivial(__first, __last, __result); }
+
+ template<typename _Tp>
+ inline _Tp*
+ __copy_aux2(const _Tp* __first, const _Tp* __last,
+ _Tp* __result, __true_type)
+ { return __copy_trivial(__first, __last, __result); }
+
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ __copy_ni2(_InputIter __first, _InputIter __last,
+ _OutputIter __result, __true_type)
+ {
+ typedef typename iterator_traits<_InputIter>::value_type
+ _ValueType;
+ typedef typename __type_traits<_ValueType>::has_trivial_assignment_operator
+ _Trivial;
+ return _OutputIter(__copy_aux2(__first, __last,
+ __result.base(),
+ _Trivial()));
+ }
+
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ __copy_ni2(_InputIter __first, _InputIter __last,
+ _OutputIter __result, __false_type)
+ {
+ typedef typename iterator_traits<_InputIter>::value_type
+ _ValueType;
+ typedef typename __type_traits<_ValueType>::has_trivial_assignment_operator
+ _Trivial;
+ return __copy_aux2(__first, __last,
+ __result,
+ _Trivial());
+ }
+
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ __copy_ni1(_InputIter __first, _InputIter __last,
+ _OutputIter __result, __true_type)
+ {
+ typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal;
+ return __copy_ni2(__first.base(), __last.base(), __result, __Normal());
+ }
+
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ __copy_ni1(_InputIter __first, _InputIter __last,
+ _OutputIter __result, __false_type)
+ {
+ typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal;
+ return __copy_ni2(__first, __last, __result, __Normal());
+ }
+
+ /**
+ * @brief Copies the range [first,last) into result.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @return result + (first - last)
+ *
+ * This inline function will boil down to a call to @c memmove whenever
+ * possible. Failing that, if random access iterators are passed, then the
+ * loop count will be known (and therefore a candidate for compiler
+ * optimizations such as unrolling). If the input range and the output
+ * range overlap, then the copy_backward function should be used instead.
+ */
+ template<typename _InputIter, typename _OutputIter>
+ inline _OutputIter
+ copy(_InputIter __first, _InputIter __last, _OutputIter __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
+ typename iterator_traits<_InputIter>::value_type>)
+
+ typedef typename _Is_normal_iterator<_InputIter>::_Normal __Normal;
+ return __copy_ni1(__first, __last, __result, __Normal());
+ }
+
+ //--------------------------------------------------
+ // copy_backward
+
+ template<typename _BidirectionalIter1, typename _BidirectionalIter2>
+ inline _BidirectionalIter2
+ __copy_backward(_BidirectionalIter1 __first, _BidirectionalIter1 __last,
+ _BidirectionalIter2 __result,
+ bidirectional_iterator_tag)
+ {
+ while (__first != __last)
+ *--__result = *--__last;
+ return __result;
+ }
+
+ template<typename _RandomAccessIter, typename _BidirectionalIter>
+ inline _BidirectionalIter
+ __copy_backward(_RandomAccessIter __first, _RandomAccessIter __last,
+ _BidirectionalIter __result,
+ random_access_iterator_tag)
+ {
+ typename iterator_traits<_RandomAccessIter>::difference_type __n;
+ for (__n = __last - __first; __n > 0; --__n)
+ *--__result = *--__last;
+ return __result;
+ }
+
+
+ // This dispatch class is a workaround for compilers that do not
+ // have partial ordering of function templates. All we're doing is
+ // creating a specialization so that we can turn a call to copy_backward
+ // into a memmove whenever possible.
+
+ template<typename _BidirectionalIter1, typename _BidirectionalIter2,
+ typename _BoolType>
+ struct __copy_backward_dispatch
+ {
+ static _BidirectionalIter2
+ copy(_BidirectionalIter1 __first, _BidirectionalIter1 __last,
+ _BidirectionalIter2 __result)
+ {
+ return __copy_backward(__first, __last,
+ __result,
+ __iterator_category(__first));
+ }
+ };
+
+ template<typename _Tp>
+ struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
+ {
+ static _Tp*
+ copy(const _Tp* __first, const _Tp* __last, _Tp* __result)
+ {
+ const ptrdiff_t _Num = __last - __first;
+ memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
+ return __result - _Num;
+ }
+ };
+
+ template<typename _Tp>
+ struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type>
+ {
+ static _Tp*
+ copy(const _Tp* __first, const _Tp* __last, _Tp* __result)
+ {
+ return __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
+ ::copy(__first, __last, __result);
+ }
+ };
+
+ template<typename _BI1, typename _BI2>
+ inline _BI2
+ __copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ typedef typename __type_traits<typename iterator_traits<_BI2>::value_type>
+ ::has_trivial_assignment_operator _Trivial;
+ return __copy_backward_dispatch<_BI1, _BI2, _Trivial>
+ ::copy(__first, __last, __result);
+ }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2
+ __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last,
+ _BI2 __result, __true_type)
+ { return _BI2(__copy_backward_aux(__first, __last, __result.base())); }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2
+ __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last,
+ _BI2 __result, __false_type)
+ { return __copy_backward_aux(__first, __last, __result); }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2
+ __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last,
+ _BI2 __result, __true_type)
+ {
+ typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal;
+ return __copy_backward_output_normal_iterator(__first.base(), __last.base(),
+ __result, __Normal());
+ }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2
+ __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last,
+ _BI2 __result, __false_type)
+ {
+ typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal;
+ return __copy_backward_output_normal_iterator(__first, __last, __result,
+ __Normal());
+ }
+
+ /**
+ * @brief Copies the range [first,last) into result.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @return result - (first - last)
+ *
+ * The function has the same effect as copy, but starts at the end of the
+ * range and works its way to the start, returning the start of the result.
+ * This inline function will boil down to a call to @c memmove whenever
+ * possible. Failing that, if random access iterators are passed, then the
+ * loop count will be known (and therefore a candidate for compiler
+ * optimizations such as unrolling).
+ */
+ template <typename _BI1, typename _BI2>
+ inline _BI2
+ copy_backward(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BI1>)
+ __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>)
+ __glibcpp_function_requires(_ConvertibleConcept<
+ typename iterator_traits<_BI1>::value_type,
+ typename iterator_traits<_BI2>::value_type>)
+
+ typedef typename _Is_normal_iterator<_BI1>::_Normal __Normal;
+ return __copy_backward_input_normal_iterator(__first, __last, __result,
+ __Normal());
+ }
+
+
+ //--------------------------------------------------
+ // fill and fill_n
+
+
+ /**
+ * @brief Fills the range [first,last) with copies of value.
+ * @param first A forward iterator.
+ * @param last A forward iterator.
+ * @param value A reference-to-const of arbitrary type.
+ * @return Nothing.
+ *
+ * This function fills a range with copies of the same value. For one-byte
+ * types filling contiguous areas of memory, this becomes an inline call to
+ * @c memset.
+ */
+ template<typename _ForwardIter, typename _Tp>
+ void
+ fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
+
+ for ( ; __first != __last; ++__first)
+ *__first = __value;
+ }
+
+ /**
+ * @brief Fills the range [first,first+n) with copies of value.
+ * @param first An output iterator.
+ * @param n The count of copies to perform.
+ * @param value A reference-to-const of arbitrary type.
+ * @return The iterator at first+n.
+ *
+ * This function fills a range with copies of the same value. For one-byte
+ * types filling contiguous areas of memory, this becomes an inline call to
+ * @c memset.
+ */
+ template<typename _OutputIter, typename _Size, typename _Tp>
+ _OutputIter
+ fill_n(_OutputIter __first, _Size __n, const _Tp& __value)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,_Tp>)
+
+ for ( ; __n > 0; --__n, ++__first)
+ *__first = __value;
+ return __first;
+ }
+
+ // Specialization: for one-byte types we can use memset.
+
+ inline void
+ fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c)
+ {
+ unsigned char __tmp = __c;
+ memset(__first, __tmp, __last - __first);
+ }
+
+ inline void
+ fill(signed char* __first, signed char* __last, const signed char& __c)
+ {
+ signed char __tmp = __c;
+ memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
+ }
+
+ inline void
+ fill(char* __first, char* __last, const char& __c)
+ {
+ char __tmp = __c;
+ memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
+ }
+
+ template<typename _Size>
+ inline unsigned char*
+ fill_n(unsigned char* __first, _Size __n, const unsigned char& __c)
+ {
+ fill(__first, __first + __n, __c);
+ return __first + __n;
+ }
+
+ template<typename _Size>
+ inline signed char*
+ fill_n(char* __first, _Size __n, const signed char& __c)
+ {
+ fill(__first, __first + __n, __c);
+ return __first + __n;
+ }
+
+ template<typename _Size>
+ inline char*
+ fill_n(char* __first, _Size __n, const char& __c)
+ {
+ fill(__first, __first + __n, __c);
+ return __first + __n;
+ }
+
+
+ //--------------------------------------------------
+ // equal and mismatch
+
+ /**
+ * @brief Finds the places in ranges which don't match.
+ * @param first1 An input iterator.
+ * @param last1 An input iterator.
+ * @param first2 An input iterator.
+ * @return A pair of iterators pointing to the first mismatch.
+ *
+ * This compares the elements of two ranges using @c == and returns a pair
+ * of iterators. The first iterator points into the first range, the
+ * second iterator points into the second range, and the elements pointed
+ * to by the iterators are not equal.
+ */
+ template<typename _InputIter1, typename _InputIter2>
+ pair<_InputIter1, _InputIter2>
+ mismatch(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_EqualityComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_EqualityComparableConcept<
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ while (__first1 != __last1 && *__first1 == *__first2) {
+ ++__first1;
+ ++__first2;
+ }
+ return pair<_InputIter1, _InputIter2>(__first1, __first2);
+ }
+
+ /**
+ * @brief Finds the places in ranges which don't match.
+ * @param first1 An input iterator.
+ * @param last1 An input iterator.
+ * @param first2 An input iterator.
+ * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink.
+ * @return A pair of iterators pointing to the first mismatch.
+ *
+ * This compares the elements of two ranges using the binary_pred
+ * parameter, and returns a pair
+ * of iterators. The first iterator points into the first range, the
+ * second iterator points into the second range, and the elements pointed
+ * to by the iterators are not equal.
+ */
+ template<typename _InputIter1, typename _InputIter2, typename _BinaryPredicate>
+ pair<_InputIter1, _InputIter2>
+ mismatch(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2,
+ _BinaryPredicate __binary_pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+
+ while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) {
+ ++__first1;
+ ++__first2;
+ }
+ return pair<_InputIter1, _InputIter2>(__first1, __first2);
+ }
+
+ /**
+ * @brief Tests a range for element-wise equality.
+ * @param first1 An input iterator.
+ * @param last1 An input iterator.
+ * @param first2 An input iterator.
+ * @return A boolean true or false.
+ *
+ * This compares the elements of two ranges using @c == and returns true or
+ * false depending on whether all of the corresponding elements of the
+ * ranges are equal.
+ */
+ template<typename _InputIter1, typename _InputIter2>
+ inline bool
+ equal(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_EqualOpConcept<
+ typename iterator_traits<_InputIter1>::value_type,
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ for ( ; __first1 != __last1; ++__first1, ++__first2)
+ if (!(*__first1 == *__first2))
+ return false;
+ return true;
+ }
+
+ /**
+ * @brief Tests a range for element-wise equality.
+ * @param first1 An input iterator.
+ * @param last1 An input iterator.
+ * @param first2 An input iterator.
+ * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink.
+ * @return A boolean true or false.
+ *
+ * This compares the elements of two ranges using the binary_pred
+ * parameter, and returns true or
+ * false depending on whether all of the corresponding elements of the
+ * ranges are equal.
+ */
+ template<typename _InputIter1, typename _InputIter2, typename _BinaryPredicate>
+ inline bool
+ equal(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2,
+ _BinaryPredicate __binary_pred)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+
+ for ( ; __first1 != __last1; ++__first1, ++__first2)
+ if (!__binary_pred(*__first1, *__first2))
+ return false;
+ return true;
+ }
+
+ //--------------------------------------------------
+ // lexicographical_compare
+
+ /**
+ * @brief Performs "dictionary" comparison on ranges.
+ * @param first1 An input iterator.
+ * @param last1 An input iterator.
+ * @param first2 An input iterator.
+ * @param last2 An input iterator.
+ * @return A boolean true or false.
+ *
+ * "Returns true if the sequence of elements defined by the range
+ * [first1,last1) is lexicographically less than the sequence of elements
+ * defined by the range [first2,last2). Returns false otherwise."
+ * (Quoted from [25.3.8]/1.) If the iterators are all character pointers,
+ * then this is an inline call to @c memcmp.
+ */
+ template<typename _InputIter1, typename _InputIter2>
+ bool
+ lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter1>::value_type>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_InputIter2>::value_type>)
+
+ for ( ; __first1 != __last1 && __first2 != __last2
+ ; ++__first1, ++__first2) {
+ if (*__first1 < *__first2)
+ return true;
+ if (*__first2 < *__first1)
+ return false;
+ }
+ return __first1 == __last1 && __first2 != __last2;
+ }
+
+ /**
+ * @brief Performs "dictionary" comparison on ranges.
+ * @param first1 An input iterator.
+ * @param last1 An input iterator.
+ * @param first2 An input iterator.
+ * @param last2 An input iterator.
+ * @param comp A @link s20_3_3_comparisons comparison functor@endlink.
+ * @return A boolean true or false.
+ *
+ * The same as the four-parameter @c lexigraphical_compare, but uses the
+ * comp parameter instead of @c <.
+ */
+ template<typename _InputIter1, typename _InputIter2, typename _Compare>
+ bool
+ lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
+
+ for ( ; __first1 != __last1 && __first2 != __last2
+ ; ++__first1, ++__first2) {
+ if (__comp(*__first1, *__first2))
+ return true;
+ if (__comp(*__first2, *__first1))
+ return false;
+ }
+ return __first1 == __last1 && __first2 != __last2;
+ }
+
+ inline bool
+ lexicographical_compare(const unsigned char* __first1, const unsigned char* __last1,
+ const unsigned char* __first2, const unsigned char* __last2)
+ {
+ const size_t __len1 = __last1 - __first1;
+ const size_t __len2 = __last2 - __first2;
+ const int __result = memcmp(__first1, __first2, min(__len1, __len2));
+ return __result != 0 ? __result < 0 : __len1 < __len2;
+ }
+
+ inline bool
+ lexicographical_compare(const char* __first1, const char* __last1,
+ const char* __first2, const char* __last2)
+ {
+#if CHAR_MAX == SCHAR_MAX
+ return lexicographical_compare((const signed char*) __first1,
+ (const signed char*) __last1,
+ (const signed char*) __first2,
+ (const signed char*) __last2);
+#else /* CHAR_MAX == SCHAR_MAX */
+ return lexicographical_compare((const unsigned char*) __first1,
+ (const unsigned char*) __last1,
+ (const unsigned char*) __first2,
+ (const unsigned char*) __last2);
+#endif /* CHAR_MAX == SCHAR_MAX */
+ }
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_ALGOBASE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_alloc.h b/contrib/libstdc++/include/bits/stl_alloc.h
new file mode 100644
index 0000000000000..7c34000401c13
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_alloc.h
@@ -0,0 +1,941 @@
+// Allocators -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_alloc.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_ALLOC_H
+#define __GLIBCPP_INTERNAL_ALLOC_H
+
+/**
+ * @defgroup Allocators Memory Allocators
+ * @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
+ * pointer type. The C++ standard allocators are intended to allocate
+ * individual objects, not pools or arenas.
+ *
+ * In this file allocators are of two different styles: "standard" and
+ * "SGI" (quotes included). "Standard" allocators conform to 20.4. "SGI"
+ * allocators differ in AT LEAST the following ways (add to this list as you
+ * discover them):
+ *
+ * - "Standard" allocate() takes two parameters (n_count,hint=0) but "SGI"
+ * allocate() takes one paramter (n_size).
+ * - Likewise, "standard" deallocate()'s argument is a count, but in "SGI"
+ * is a byte size.
+ * - max_size(), construct(), and destroy() are missing in "SGI" allocators.
+ * - reallocate(p,oldsz,newsz) is added in "SGI", and behaves as
+ * if p=realloc(p,newsz).
+ *
+ * "SGI" allocators may be wrapped in __allocator to convert the interface
+ * into a "standard" one.
+ * @endif
+ *
+ * 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
+*/
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
+#include <bits/functexcept.h> // For __throw_bad_alloc
+#include <bits/stl_threads.h>
+
+namespace std
+{
+ /**
+ * @if maint
+ * A new-based allocator, as required by the standard. Allocation and
+ * deallocation forward to global new and delete. "SGI" style, minus
+ * reallocate().
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ class __new_alloc
+ {
+ public:
+ static void*
+ allocate(size_t __n)
+ { return ::operator new(__n); }
+
+ static void
+ deallocate(void* __p, size_t)
+ { ::operator delete(__p); }
+ };
+
+
+ /**
+ * @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.
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template <int __inst>
+ class __malloc_alloc_template
+ {
+ private:
+ static void* _S_oom_malloc(size_t);
+ static void* _S_oom_realloc(void*, size_t);
+ static void (* __malloc_alloc_oom_handler)();
+
+ public:
+ static void*
+ allocate(size_t __n)
+ {
+ void* __result = malloc(__n);
+ if (0 == __result) __result = _S_oom_malloc(__n);
+ return __result;
+ }
+
+ static void
+ deallocate(void* __p, size_t /* __n */)
+ { free(__p); }
+
+ static void*
+ reallocate(void* __p, size_t /* old_sz */, size_t __new_sz)
+ {
+ void* __result = realloc(__p, __new_sz);
+ if (0 == __result) __result = _S_oom_realloc(__p, __new_sz);
+ return __result;
+ }
+
+ static void (* __set_malloc_handler(void (*__f)()))()
+ {
+ void (* __old)() = __malloc_alloc_oom_handler;
+ __malloc_alloc_oom_handler = __f;
+ return(__old);
+ }
+ };
+
+ // malloc_alloc out-of-memory handling
+ template <int __inst>
+ void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0;
+
+ template <int __inst>
+ void*
+ __malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n)
+ {
+ void (* __my_malloc_handler)();
+ void* __result;
+
+ for (;;)
+ {
+ __my_malloc_handler = __malloc_alloc_oom_handler;
+ if (0 == __my_malloc_handler)
+ std::__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)
+ {
+ 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);
+ }
+ }
+
+
+// Determines the underlying allocator choice for the node allocator.
+#ifdef __USE_MALLOC
+ typedef __malloc_alloc_template<0> __mem_interface;
+#else
+ typedef __new_alloc __mem_interface;
+#endif
+
+
+ /**
+ * @if maint
+ * This is used primarily (only?) in _Alloc_traits and other places to
+ * help provide the _Alloc_type typedef.
+ *
+ * This is neither "standard"-conforming nor "SGI". The _Alloc parameter
+ * must be "SGI" style.
+ * @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)); }
+ };
+
+
+ /**
+ * @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
+ * paid, therefore it is far better to just use the underlying allocator
+ * by itelf when no checking is desired.
+ *
+ * "There is some evidence that this can confuse Purify." - SGI comment
+ *
+ * This adaptor is "SGI" style. The _Alloc parameter must also be "SGI".
+ * @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)
+ {
+ char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
+ *(size_t*)__result = __n;
+ return __result + (int) _S_extra;
+ }
+
+ static void deallocate(void* __p, size_t __n)
+ {
+ char* __real_p = (char*)__p - (int) _S_extra;
+ assert(*(size_t*)__real_p == __n);
+ _Alloc::deallocate(__real_p, __n + (int) _S_extra);
+ }
+
+ static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz)
+ {
+ char* __real_p = (char*)__p - (int) _S_extra;
+ assert(*(size_t*)__real_p == __old_sz);
+ char* __result = (char*)
+ _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra,
+ __new_sz + (int) _S_extra);
+ *(size_t*)__result = __new_sz;
+ return __result + (int) _S_extra;
+ }
+ };
+
+
+#ifdef __USE_MALLOC
+
+typedef __mem_interface __alloc;
+typedef __mem_interface __single_client_alloc;
+
+#else
+
+
+/**
+ * @if 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.
+ *
+ * @endif
+ * (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 _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;
+ };
+
+ // __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);
+ };
+
+
+ template<bool __threads, int __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>&)
+ { 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.
+ template<bool __threads, int __inst>
+ char*
+ __default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size,
+ int& __nobjs)
+ {
+ char* __result;
+ size_t __total_bytes = __size * __nobjs;
+ size_t __bytes_left = _S_end_free - _S_start_free;
+
+ if (__bytes_left >= __total_bytes)
+ {
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return(__result);
+ }
+ else if (__bytes_left >= __size)
+ {
+ __nobjs = (int)(__bytes_left/__size);
+ __total_bytes = __size * __nobjs;
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return(__result);
+ }
+ else
+ {
+ size_t __bytes_to_get =
+ 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
+ // Try to make use of the left-over piece.
+ if (__bytes_left > 0)
+ {
+ _Obj* 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));
+ }
+ }
+
+
+ // 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.
+ template<bool __threads, int __inst>
+ void*
+ __default_alloc_template<__threads, __inst>::_S_refill(size_t __n)
+ {
+ int __nobjs = 20;
+ char* __chunk = _S_chunk_alloc(__n, __nobjs);
+ _Obj* volatile* __my_free_list;
+ _Obj* __result;
+ _Obj* __current_obj;
+ _Obj* __next_obj;
+ int __i;
+
+ if (1 == __nobjs) return(__chunk);
+ __my_free_list = _S_free_list + _S_freelist_index(__n);
+
+ /* Build free list in chunk */
+ __result = (_Obj*)__chunk;
+ *__my_free_list = __next_obj = (_Obj*)(__chunk + __n);
+ for (__i = 1; ; __i++) {
+ __current_obj = __next_obj;
+ __next_obj = (_Obj*)((char*)__next_obj + __n);
+ if (__nobjs - 1 == __i) {
+ __current_obj -> _M_free_list_link = 0;
+ break;
+ } else {
+ __current_obj -> _M_free_list_link = __next_obj;
+ }
+ }
+ return(__result);
+ }
+
+
+ template<bool threads, int inst>
+ void*
+ __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) {
+ return(realloc(__p, __new_sz));
+ }
+ if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
+ __result = allocate(__new_sz);
+ __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
+ memcpy(__result, __p, __copy_sz);
+ deallocate(__p, __old_sz);
+ return(__result);
+ }
+
+ template<bool __threads, int __inst>
+ _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;
+
+ template<bool __threads, int __inst>
+ 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;
+
+ 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;
+
+
+#endif /* ! __USE_MALLOC */
+
+
+/**
+ * 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;
+ };
+
+ 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;
+ };
+};
+
+
+template <class _T1, class _T2>
+inline bool operator==(const allocator<_T1>&, const allocator<_T2>&)
+{
+ return true;
+}
+
+template <class _T1, class _T2>
+inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&)
+{
+ return false;
+}
+
+
+/**
+ * @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 <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;
+ };
+
+ __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;
+}
+
+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;
+}
+
+
+//@{
+/** 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 <class _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;
+}
+//@}
+
+
+/**
+ * @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 <class _Tp, class _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;
+
+/// 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
+
+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
+
+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;
+};
+//@}
+
+ // 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>;
+#ifdef __USE_MALLOC
+ extern template class __malloc_alloc_template<0>;
+#else
+ extern template class __default_alloc_template<true, 0>;
+#endif
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_ALLOC_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_bvector.h b/contrib/libstdc++/include/bits/stl_bvector.h
new file mode 100644
index 0000000000000..6cb6d9caf36fe
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_bvector.h
@@ -0,0 +1,726 @@
+// bit_vector and vector<bool> specialization -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996-1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_bvector.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_BVECTOR_H
+#define __GLIBCPP_INTERNAL_BVECTOR_H
+
+namespace std
+{
+ typedef unsigned long _Bit_type;
+ enum { _M_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) };
+
+struct _Bit_reference {
+
+ _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); }
+ _Bit_reference& operator=(bool __x)
+ {
+ if (__x) *_M_p |= _M_mask;
+ else *_M_p &= ~_M_mask;
+ return *this;
+ }
+ _Bit_reference& operator=(const _Bit_reference& __x)
+ { return *this = bool(__x); }
+ bool operator==(const _Bit_reference& __x) const
+ { return bool(*this) == bool(__x); }
+ bool operator<(const _Bit_reference& __x) const
+ { return !bool(*this) && bool(__x); }
+ void flip() { *_M_p ^= _M_mask; }
+};
+
+inline void swap(_Bit_reference __x, _Bit_reference __y)
+{
+ bool __tmp = __x;
+ __x = __y;
+ __y = __tmp;
+}
+
+struct _Bit_iterator_base : public iterator<random_access_iterator_tag, bool>
+{
+ _Bit_type * _M_p;
+ unsigned int _M_offset;
+
+ _Bit_iterator_base(_Bit_type * __x, unsigned int __y)
+ : _M_p(__x), _M_offset(__y) {}
+
+ void _M_bump_up() {
+ if (_M_offset++ == _M_word_bit - 1) {
+ _M_offset = 0;
+ ++_M_p;
+ }
+ }
+ void _M_bump_down() {
+ if (_M_offset-- == 0) {
+ _M_offset = _M_word_bit - 1;
+ --_M_p;
+ }
+ }
+
+ void _M_incr(ptrdiff_t __i) {
+ difference_type __n = __i + _M_offset;
+ _M_p += __n / _M_word_bit;
+ __n = __n % _M_word_bit;
+ if (__n < 0) {
+ _M_offset = (unsigned int) __n + _M_word_bit;
+ --_M_p;
+ } else
+ _M_offset = (unsigned int) __n;
+ }
+
+ bool operator==(const _Bit_iterator_base& __i) const {
+ return _M_p == __i._M_p && _M_offset == __i._M_offset;
+ }
+ bool operator<(const _Bit_iterator_base& __i) const {
+ return _M_p < __i._M_p || (_M_p == __i._M_p && _M_offset < __i._M_offset);
+ }
+ bool operator!=(const _Bit_iterator_base& __i) const {
+ return !(*this == __i);
+ }
+ bool operator>(const _Bit_iterator_base& __i) const {
+ return __i < *this;
+ }
+ bool operator<=(const _Bit_iterator_base& __i) const {
+ return !(__i < *this);
+ }
+ bool operator>=(const _Bit_iterator_base& __i) const {
+ return !(*this < __i);
+ }
+};
+
+inline ptrdiff_t
+operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) {
+ return _M_word_bit * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset;
+}
+
+
+struct _Bit_iterator : public _Bit_iterator_base
+{
+ typedef _Bit_reference reference;
+ typedef _Bit_reference* pointer;
+ typedef _Bit_iterator iterator;
+
+ _Bit_iterator() : _Bit_iterator_base(0, 0) {}
+ _Bit_iterator(_Bit_type * __x, unsigned int __y)
+ : _Bit_iterator_base(__x, __y) {}
+
+ reference operator*() const { return reference(_M_p, 1U << _M_offset); }
+ iterator& operator++() {
+ _M_bump_up();
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator __tmp = *this;
+ _M_bump_up();
+ return __tmp;
+ }
+ iterator& operator--() {
+ _M_bump_down();
+ return *this;
+ }
+ iterator operator--(int) {
+ iterator __tmp = *this;
+ _M_bump_down();
+ return __tmp;
+ }
+ iterator& operator+=(difference_type __i) {
+ _M_incr(__i);
+ return *this;
+ }
+ iterator& operator-=(difference_type __i) {
+ *this += -__i;
+ return *this;
+ }
+ iterator operator+(difference_type __i) const {
+ iterator __tmp = *this;
+ return __tmp += __i;
+ }
+ iterator operator-(difference_type __i) const {
+ iterator __tmp = *this;
+ return __tmp -= __i;
+ }
+
+ reference operator[](difference_type __i) { return *(*this + __i); }
+};
+
+inline _Bit_iterator
+operator+(ptrdiff_t __n, const _Bit_iterator& __x) { return __x + __n; }
+
+
+struct _Bit_const_iterator : public _Bit_iterator_base
+{
+ typedef bool reference;
+ typedef bool const_reference;
+ typedef const bool* pointer;
+ typedef _Bit_const_iterator const_iterator;
+
+ _Bit_const_iterator() : _Bit_iterator_base(0, 0) {}
+ _Bit_const_iterator(_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);
+ }
+ const_iterator& operator++() {
+ _M_bump_up();
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator __tmp = *this;
+ _M_bump_up();
+ return __tmp;
+ }
+ const_iterator& operator--() {
+ _M_bump_down();
+ return *this;
+ }
+ const_iterator operator--(int) {
+ const_iterator __tmp = *this;
+ _M_bump_down();
+ return __tmp;
+ }
+ const_iterator& operator+=(difference_type __i) {
+ _M_incr(__i);
+ return *this;
+ }
+ const_iterator& operator-=(difference_type __i) {
+ *this += -__i;
+ return *this;
+ }
+ const_iterator operator+(difference_type __i) const {
+ const_iterator __tmp = *this;
+ return __tmp += __i;
+ }
+ const_iterator operator-(difference_type __i) const {
+ const_iterator __tmp = *this;
+ return __tmp -= __i;
+ }
+ const_reference operator[](difference_type __i) {
+ return *(*this + __i);
+ }
+};
+
+inline _Bit_const_iterator
+operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) { return __x + __n; }
+
+
+// Bit-vector base class, which encapsulates the difference between
+// old SGI-style allocators and standard-conforming allocators.
+
+// Base class for ordinary allocators.
+template <class _Allocator, bool __is_static>
+class _Bvector_alloc_base {
+public:
+ typedef typename _Alloc_traits<bool, _Allocator>::allocator_type
+ allocator_type;
+ allocator_type get_allocator() const { return _M_data_allocator; }
+
+ _Bvector_alloc_base(const allocator_type& __a)
+ : _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {}
+
+protected:
+ _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<_Bit_type, _Allocator>::allocator_type
+ _M_data_allocator;
+ _Bit_iterator _M_start;
+ _Bit_iterator _M_finish;
+ _Bit_type * _M_end_of_storage;
+};
+
+// Specialization for instanceless allocators.
+template <class _Allocator>
+class _Bvector_alloc_base<_Allocator, true> {
+public:
+ typedef typename _Alloc_traits<bool, _Allocator>::allocator_type
+ allocator_type;
+ allocator_type get_allocator() const { return allocator_type(); }
+
+ _Bvector_alloc_base(const allocator_type&)
+ : _M_start(), _M_finish(), _M_end_of_storage(0) {}
+
+protected:
+ typedef typename _Alloc_traits<_Bit_type, _Allocator>::_Alloc_type
+ _Alloc_type;
+
+ _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,
+ _M_end_of_storage - _M_start._M_p);
+ }
+
+ _Bit_iterator _M_start;
+ _Bit_iterator _M_finish;
+ _Bit_type * _M_end_of_storage;
+};
+
+template <class _Alloc>
+class _Bvector_base
+ : public _Bvector_alloc_base<_Alloc,
+ _Alloc_traits<bool, _Alloc>::_S_instanceless>
+{
+ typedef _Bvector_alloc_base<_Alloc,
+ _Alloc_traits<bool, _Alloc>::_S_instanceless>
+ _Base;
+public:
+ typedef typename _Base::allocator_type allocator_type;
+
+ _Bvector_base(const allocator_type& __a) : _Base(__a) {}
+ ~_Bvector_base() { _Base::_M_deallocate(); }
+};
+
+} // namespace std
+
+// Declare a partial specialization of vector<T, Alloc>.
+#include <bits/stl_vector.h>
+namespace std
+{
+
+template <typename _Alloc>
+ class vector<bool, _Alloc> : public _Bvector_base<_Alloc>
+ {
+ public:
+ typedef bool value_type;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Bit_reference reference;
+ typedef bool const_reference;
+ typedef _Bit_reference* pointer;
+ typedef const bool* const_pointer;
+
+ typedef _Bit_iterator iterator;
+ typedef _Bit_const_iterator const_iterator;
+
+ typedef reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef reverse_iterator<iterator> reverse_iterator;
+
+ typedef typename _Bvector_base<_Alloc>::allocator_type allocator_type;
+ allocator_type get_allocator() const {
+ return _Bvector_base<_Alloc>::get_allocator();
+ }
+
+ protected:
+ using _Bvector_base<_Alloc>::_M_bit_alloc;
+ using _Bvector_base<_Alloc>::_M_deallocate;
+ using _Bvector_base<_Alloc>::_M_start;
+ using _Bvector_base<_Alloc>::_M_finish;
+ using _Bvector_base<_Alloc>::_M_end_of_storage;
+
+ protected:
+ void _M_initialize(size_type __n) {
+ _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);
+ }
+ void _M_insert_aux(iterator __position, bool __x) {
+ if (_M_finish._M_p != _M_end_of_storage) {
+ copy_backward(__position, _M_finish, _M_finish + 1);
+ *__position = __x;
+ ++_M_finish;
+ }
+ else {
+ size_type __len = size()
+ ? 2 * size() : 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 + _M_word_bit - 1)/_M_word_bit;
+ _M_start = iterator(__q, 0);
+ }
+ }
+
+ template <class _InputIterator>
+ void _M_initialize_range(_InputIterator __first, _InputIterator __last,
+ input_iterator_tag) {
+ _M_start = iterator();
+ _M_finish = iterator();
+ _M_end_of_storage = 0;
+ for ( ; __first != __last; ++__first)
+ push_back(*__first);
+ }
+
+ template <class _ForwardIterator>
+ void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag) {
+ size_type __n = distance(__first, __last);
+ _M_initialize(__n);
+ copy(__first, __last, _M_start);
+ }
+
+ template <class _InputIterator>
+ void _M_insert_range(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ input_iterator_tag) {
+ for ( ; __first != __last; ++__first) {
+ __pos = insert(__pos, *__first);
+ ++__pos;
+ }
+ }
+
+ template <class _ForwardIterator>
+ void _M_insert_range(iterator __position,
+ _ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag) {
+ if (__first != __last) {
+ size_type __n = distance(__first, __last);
+ if (capacity() - size() >= __n) {
+ copy_backward(__position, end(), _M_finish + difference_type(__n));
+ copy(__first, __last, __position);
+ _M_finish += difference_type(__n);
+ }
+ else {
+ size_type __len = size() + max(size(), __n);
+ _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 + _M_word_bit - 1)/_M_word_bit;
+ _M_start = iterator(__q, 0);
+ }
+ }
+ }
+
+ public:
+ iterator begin() { return _M_start; }
+ const_iterator begin() const { return _M_start; }
+ iterator end() { return _M_finish; }
+ const_iterator end() const { return _M_finish; }
+
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+ size_type size() const { return size_type(end() - begin()); }
+ size_type max_size() const { return size_type(-1); }
+ size_type capacity() const {
+ return size_type(const_iterator(_M_end_of_storage, 0) - begin());
+ }
+ bool empty() const { return begin() == end(); }
+
+ reference operator[](size_type __n)
+ { return *(begin() + difference_type(__n)); }
+ const_reference operator[](size_type __n) const
+ { return *(begin() + difference_type(__n)); }
+
+ void _M_range_check(size_type __n) const {
+ if (__n >= this->size())
+ __throw_out_of_range("vector<bool>");
+ }
+
+ reference at(size_type __n)
+ { _M_range_check(__n); return (*this)[__n]; }
+ const_reference at(size_type __n) const
+ { _M_range_check(__n); return (*this)[__n]; }
+
+ explicit vector(const allocator_type& __a = allocator_type())
+ : _Bvector_base<_Alloc>(__a) {}
+
+ vector(size_type __n, bool __value,
+ const allocator_type& __a = allocator_type())
+ : _Bvector_base<_Alloc>(__a)
+ {
+ _M_initialize(__n);
+ fill(_M_start._M_p, _M_end_of_storage, __value ? ~0 : 0);
+ }
+
+ explicit vector(size_type __n)
+ : _Bvector_base<_Alloc>(allocator_type())
+ {
+ _M_initialize(__n);
+ fill(_M_start._M_p, _M_end_of_storage, 0);
+ }
+
+ vector(const vector& __x) : _Bvector_base<_Alloc>(__x.get_allocator()) {
+ _M_initialize(__x.size());
+ copy(__x.begin(), __x.end(), _M_start);
+ }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+
+ template <class _Integer>
+ void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) {
+ _M_initialize(__n);
+ fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0);
+ }
+
+ template <class _InputIterator>
+ void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+ __false_type) {
+ _M_initialize_range(__first, __last, __iterator_category(__first));
+ }
+
+ template <class _InputIterator>
+ vector(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a = allocator_type())
+ : _Bvector_base<_Alloc>(__a)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_initialize_dispatch(__first, __last, _Integral());
+ }
+
+ ~vector() { }
+
+ vector& operator=(const vector& __x) {
+ if (&__x == this) return *this;
+ if (__x.size() > capacity()) {
+ _M_deallocate();
+ _M_initialize(__x.size());
+ }
+ copy(__x.begin(), __x.end(), begin());
+ _M_finish = begin() + difference_type(__x.size());
+ return *this;
+ }
+
+ // assign(), a generalized assignment member function. Two
+ // versions: one that takes a count, and one that takes a range.
+ // The range version is a member template, so we dispatch on whether
+ // or not the type is an integer.
+
+ void _M_fill_assign(size_t __n, bool __x) {
+ if (__n > size()) {
+ fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0);
+ insert(end(), __n - size(), __x);
+ }
+ else {
+ erase(begin() + __n, end());
+ fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0);
+ }
+ }
+
+ void assign(size_t __n, bool __x) { _M_fill_assign(__n, __x); }
+
+ template <class _InputIterator>
+ void 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_t) __n, (bool) __val); }
+
+ template <class _InputIter>
+ void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
+ { _M_assign_aux(__first, __last, __iterator_category(__first)); }
+
+ template <class _InputIterator>
+ void _M_assign_aux(_InputIterator __first, _InputIterator __last,
+ input_iterator_tag) {
+ iterator __cur = begin();
+ for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
+ *__cur = *__first;
+ if (__first == __last)
+ erase(__cur, end());
+ else
+ insert(end(), __first, __last);
+ }
+
+ template <class _ForwardIterator>
+ void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag) {
+ size_type __len = distance(__first, __last);
+ if (__len < size())
+ erase(copy(__first, __last, begin()), end());
+ else {
+ _ForwardIterator __mid = __first;
+ advance(__mid, size());
+ copy(__first, __mid, begin());
+ insert(end(), __mid, __last);
+ }
+ }
+
+ void reserve(size_type __n) {
+ if (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 + _M_word_bit - 1)/_M_word_bit;
+ }
+ }
+
+ reference front() { return *begin(); }
+ const_reference front() const { return *begin(); }
+ reference back() { return *(end() - 1); }
+ const_reference back() const { return *(end() - 1); }
+ void push_back(bool __x) {
+ if (_M_finish._M_p != _M_end_of_storage)
+ *_M_finish++ = __x;
+ else
+ _M_insert_aux(end(), __x);
+ }
+ void swap(vector<bool, _Alloc>& __x) {
+ std::swap(_M_start, __x._M_start);
+ std::swap(_M_finish, __x._M_finish);
+ std::swap(_M_end_of_storage, __x._M_end_of_storage);
+ }
+ iterator insert(iterator __position, bool __x = bool()) {
+ difference_type __n = __position - begin();
+ if (_M_finish._M_p != _M_end_of_storage && __position == end())
+ *_M_finish++ = __x;
+ else
+ _M_insert_aux(__position, __x);
+ return begin() + __n;
+ }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+
+ template <class _Integer>
+ void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
+ __true_type) {
+ _M_fill_insert(__pos, __n, __x);
+ }
+
+ template <class _InputIterator>
+ void _M_insert_dispatch(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ __false_type) {
+ _M_insert_range(__pos, __first, __last, __iterator_category(__first));
+ }
+
+ template <class _InputIterator>
+ void insert(iterator __position,
+ _InputIterator __first, _InputIterator __last) {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_insert_dispatch(__position, __first, __last, _Integral());
+ }
+
+ void _M_fill_insert(iterator __position, size_type __n, bool __x) {
+ if (__n == 0) return;
+ if (capacity() - size() >= __n) {
+ copy_backward(__position, end(), _M_finish + difference_type(__n));
+ fill(__position, __position + difference_type(__n), __x);
+ _M_finish += difference_type(__n);
+ }
+ else {
+ size_type __len = size() + max(size(), __n);
+ _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 + _M_word_bit - 1)/_M_word_bit;
+ _M_start = iterator(__q, 0);
+ }
+ }
+
+ void insert(iterator __position, size_type __n, bool __x) {
+ _M_fill_insert(__position, __n, __x);
+ }
+
+ void pop_back() { --_M_finish; }
+ iterator erase(iterator __position) {
+ if (__position + 1 != end())
+ copy(__position + 1, end(), __position);
+ --_M_finish;
+ return __position;
+ }
+ iterator erase(iterator __first, iterator __last) {
+ _M_finish = copy(__last, end(), __first);
+ return __first;
+ }
+ void resize(size_type __new_size, bool __x = bool()) {
+ if (__new_size < size())
+ erase(begin() + difference_type(__new_size), end());
+ else
+ insert(end(), __new_size - size(), __x);
+ }
+ void flip() {
+ for (_Bit_type * __p = _M_start._M_p; __p != _M_end_of_storage; ++__p)
+ *__p = ~*__p;
+ }
+
+ void clear() { erase(begin(), end()); }
+ };
+
+// This typedef is non-standard. It is provided for backward compatibility.
+typedef vector<bool, __alloc> bit_vector;
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_BVECTOR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_construct.h b/contrib/libstdc++/include/bits/stl_construct.h
new file mode 100644
index 0000000000000..685913888c855
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_construct.h
@@ -0,0 +1,148 @@
+// nonstandard construct and destroy functions -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_construct.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STL_CONSTRUCT_H
+#define _CPP_BITS_STL_CONSTRUCT_H 1
+
+#include <bits/type_traits.h>
+#include <new>
+
+namespace std
+{
+ /**
+ * @if maint
+ * Constructs an object in existing memory by invoking an allocated
+ * object's constructor with an initializer.
+ * @endif
+ */
+ template <class _T1, class _T2>
+ inline void
+ _Construct(_T1* __p, const _T2& __value)
+ { new (static_cast<void*>(__p)) _T1(__value); }
+
+ /**
+ * @if maint
+ * Constructs an object in existing memory by invoking an allocated
+ * object's default constructor (no initializers).
+ * @endif
+ */
+ template <class _T1>
+ inline void
+ _Construct(_T1* __p)
+ { new (static_cast<void*>(__p)) _T1(); }
+
+ /**
+ * @if maint
+ * Destroy a range of objects with nontrivial destructors.
+ *
+ * This is a helper function used only by _Destroy().
+ * @endif
+ */
+ template <class _ForwardIterator>
+ inline void
+ __destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type)
+ { for ( ; __first != __last; ++__first) _Destroy(&*__first); }
+
+ /**
+ * @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().
+ * @endif
+ */
+ template <class _ForwardIterator>
+ inline void
+ __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type)
+ { }
+
+ /**
+ * @if maint
+ * Destroy the object pointed to by a pointer type.
+ * @endif
+ */
+ template <class _Tp>
+ inline void
+ _Destroy(_Tp* __pointer)
+ { __pointer->~_Tp(); }
+
+ /**
+ * @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.
+ * @endif
+ */
+ template <class _ForwardIterator>
+ inline void
+ _Destroy(_ForwardIterator __first, _ForwardIterator __last)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::value_type
+ _Value_type;
+ typedef typename __type_traits<_Value_type>::has_trivial_destructor
+ _Has_trivial_destructor;
+
+ __destroy_aux(__first, __last, _Has_trivial_destructor());
+ }
+} // namespace std
+
+#endif /* _CPP_BITS_STL_CONSTRUCT_H */
+
diff --git a/contrib/libstdc++/include/bits/stl_deque.h b/contrib/libstdc++/include/bits/stl_deque.h
new file mode 100644
index 0000000000000..5fa8d125e7561
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_deque.h
@@ -0,0 +1,1580 @@
+// deque implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_deque.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#include <bits/concept_check.h>
+#include <bits/stl_iterator_base_types.h>
+#include <bits/stl_iterator_base_funcs.h>
+
+#ifndef __GLIBCPP_INTERNAL_DEQUE_H
+#define __GLIBCPP_INTERNAL_DEQUE_H
+
+
+// Since this entire file is within namespace std, there's no reason to
+// waste two spaces along the left column. Thus the leading indentation is
+// slightly violated from here on.
+namespace std
+{
+
+/**
+ * @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.
+ * @endif
+*/
+inline size_t
+__deque_buf_size(size_t __size)
+{ return __size < 512 ? size_t(512 / __size) : size_t(1); }
+
+
+/// A deque::iterator.
+/**
+ * Quite a bit of intelligence here. Much of the functionality of deque is
+ * actually passed off to this class. A deque holds two of these internally,
+ * marking its valid range. Access to elements is done as offsets of either
+ * of those two, relying on operator overloading in this class.
+ *
+ * @if maint
+ * All the functions are op overloads except for _M_set_node.
+ * @endif
+*/
+template <class _Tp, class _Ref, class _Ptr>
+struct _Deque_iterator
+{
+ typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
+ typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
+ static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
+
+ typedef random_access_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef _Ptr pointer;
+ typedef _Ref reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp** _Map_pointer;
+ typedef _Deque_iterator _Self;
+
+ _Tp* _M_cur;
+ _Tp* _M_first;
+ _Tp* _M_last;
+ _Map_pointer _M_node;
+
+ _Deque_iterator(_Tp* __x, _Map_pointer __y)
+ : _M_cur(__x), _M_first(*__y),
+ _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
+ _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
+ _Deque_iterator(const iterator& __x)
+ : _M_cur(__x._M_cur), _M_first(__x._M_first),
+ _M_last(__x._M_last), _M_node(__x._M_node) {}
+
+ reference operator*() const { return *_M_cur; }
+ 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) {
+ _M_set_node(_M_node + 1);
+ _M_cur = _M_first;
+ }
+ return *this;
+ }
+ _Self operator++(int) {
+ _Self __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _Self& operator--() {
+ if (_M_cur == _M_first) {
+ _M_set_node(_M_node - 1);
+ _M_cur = _M_last;
+ }
+ --_M_cur;
+ return *this;
+ }
+ _Self operator--(int) {
+ _Self __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _Self& operator+=(difference_type __n)
+ {
+ difference_type __offset = __n + (_M_cur - _M_first);
+ if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
+ _M_cur += __n;
+ else {
+ difference_type __node_offset =
+ __offset > 0 ? __offset / difference_type(_S_buffer_size())
+ : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
+ _M_set_node(_M_node + __node_offset);
+ _M_cur = _M_first +
+ (__offset - __node_offset * difference_type(_S_buffer_size()));
+ }
+ return *this;
+ }
+
+ _Self operator+(difference_type __n) const
+ {
+ _Self __tmp = *this;
+ return __tmp += __n;
+ }
+
+ _Self& operator-=(difference_type __n) { return *this += -__n; }
+
+ _Self operator-(difference_type __n) const {
+ _Self __tmp = *this;
+ return __tmp -= __n;
+ }
+
+ reference operator[](difference_type __n) const { return *(*this + __n); }
+
+ bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
+ bool operator!=(const _Self& __x) const { return !(*this == __x); }
+ bool operator<(const _Self& __x) const {
+ return (_M_node == __x._M_node) ?
+ (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
+ }
+ bool operator>(const _Self& __x) const { return __x < *this; }
+ bool operator<=(const _Self& __x) const { return !(__x < *this); }
+ bool operator>=(const _Self& __x) const { return !(*this < __x); }
+
+ /** @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.
+ * @endif
+ */
+ void _M_set_node(_Map_pointer __new_node) {
+ _M_node = __new_node;
+ _M_first = *__new_node;
+ _M_last = _M_first + difference_type(_S_buffer_size());
+ }
+};
+
+template <class _Tp, class _Ref, class _Ptr>
+inline _Deque_iterator<_Tp, _Ref, _Ptr>
+operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
+{
+ return __x + __n;
+}
+
+
+/// @if maint Primary default version. @endif
+/**
+ * @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.
+ * @endif
+*/
+template <class _Tp, class _Alloc, bool __is_static>
+class _Deque_alloc_base
+{
+public:
+ typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
+ allocator_type get_allocator() const { return _M_node_allocator; }
+
+ _Deque_alloc_base(const allocator_type& __a)
+ : _M_node_allocator(__a), _M_map_allocator(__a),
+ _M_map(0), _M_map_size(0)
+ {}
+
+protected:
+ typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
+ _Map_allocator_type;
+
+ allocator_type _M_node_allocator;
+ _Map_allocator_type _M_map_allocator;
+
+ _Tp* _M_allocate_node() {
+ return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
+ }
+ void _M_deallocate_node(_Tp* __p) {
+ _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+ }
+ _Tp** _M_allocate_map(size_t __n)
+ { return _M_map_allocator.allocate(__n); }
+ void _M_deallocate_map(_Tp** __p, size_t __n)
+ { _M_map_allocator.deallocate(__p, __n); }
+
+ _Tp** _M_map;
+ size_t _M_map_size;
+};
+
+/// @if maint Specialization for instanceless allocators. @endif
+template <class _Tp, class _Alloc>
+class _Deque_alloc_base<_Tp, _Alloc, true>
+{
+public:
+ typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
+ allocator_type get_allocator() const { return allocator_type(); }
+
+ _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
+
+protected:
+ typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
+ typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;
+
+ _Tp* _M_allocate_node() {
+ return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
+ }
+ void _M_deallocate_node(_Tp* __p) {
+ _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+ }
+ _Tp** _M_allocate_map(size_t __n)
+ { return _Map_alloc_type::allocate(__n); }
+ void _M_deallocate_map(_Tp** __p, size_t __n)
+ { _Map_alloc_type::deallocate(__p, __n); }
+
+ _Tp** _M_map;
+ size_t _M_map_size;
+};
+
+
+/**
+ * @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.
+ * @endif
+*/
+template <class _Tp, class _Alloc>
+class _Deque_base
+ : public _Deque_alloc_base<_Tp,_Alloc,
+ _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+{
+public:
+ typedef _Deque_alloc_base<_Tp,_Alloc,
+ _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+ _Base;
+ typedef typename _Base::allocator_type allocator_type;
+ typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator;
+ typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
+
+ _Deque_base(const allocator_type& __a, size_t __num_elements)
+ : _Base(__a), _M_start(), _M_finish()
+ { _M_initialize_map(__num_elements); }
+ _Deque_base(const allocator_type& __a)
+ : _Base(__a), _M_start(), _M_finish() {}
+ ~_Deque_base();
+
+protected:
+ void _M_initialize_map(size_t);
+ void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
+ void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
+ enum { _S_initial_map_size = 8 };
+
+protected:
+ iterator _M_start;
+ iterator _M_finish;
+};
+
+
+template <class _Tp, class _Alloc>
+_Deque_base<_Tp,_Alloc>::~_Deque_base()
+{
+ if (_M_map) {
+ _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
+ _M_deallocate_map(_M_map, _M_map_size);
+ }
+}
+
+/**
+ * @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...
+ * @endif
+*/
+template <class _Tp, class _Alloc>
+void
+_Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
+{
+ size_t __num_nodes =
+ __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
+
+ _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
+ _M_map = _M_allocate_map(_M_map_size);
+
+ _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
+ _Tp** __nfinish = __nstart + __num_nodes;
+
+ try
+ { _M_create_nodes(__nstart, __nfinish); }
+ catch(...)
+ {
+ _M_deallocate_map(_M_map, _M_map_size);
+ _M_map = 0;
+ _M_map_size = 0;
+ __throw_exception_again;
+ }
+
+ _M_start._M_set_node(__nstart);
+ _M_finish._M_set_node(__nfinish - 1);
+ _M_start._M_cur = _M_start._M_first;
+ _M_finish._M_cur = _M_finish._M_first +
+ __num_elements % __deque_buf_size(sizeof(_Tp));
+}
+
+template <class _Tp, class _Alloc>
+void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
+{
+ _Tp** __cur;
+ try {
+ for (__cur = __nstart; __cur < __nfinish; ++__cur)
+ *__cur = _M_allocate_node();
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(__nstart, __cur);
+ __throw_exception_again;
+ }
+}
+
+template <class _Tp, class _Alloc>
+void
+_Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
+{
+ for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
+ _M_deallocate_node(*__n);
+}
+
+
+/**
+ * @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
+ * so users could control the node size. This extension turned out to violate
+ * the C++ standard (it can be detected using template template parameters),
+ * and it was removed.
+ *
+ * @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".
+ * (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,
+ * there will be one Tp element per node (i.e., an "array" of one).
+ * For non-huge Tp's, node size is inversely related to Tp size: the
+ * larger the Tp, the fewer Tp's will fit in a node. The goal here is to
+ * keep the total size of a node relatively small and constant over different
+ * Tp's, to improve allocator efficiency.
+ *
+ * **** As I write this, the nodes are /not/ allocated using the high-speed
+ * 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
+ * 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
+ * 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
+ * correctly: i.node does not actually point to a node.) The member of
+ * 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:
+ * the implication of this is that i.cur is always a dereferenceable
+ * pointer, even if i is a past-the-end iterator.
+ * - Start and Finish are always nonsingular iterators. NOTE: this means that
+ * an empty deque must have one node, a deque with <N elements (where N is
+ * the node buffer size) must have one node, a deque with N through (2N-1)
+ * elements must have two nodes, etc.
+ * - For every node other than start.node and finish.node, every element in the
+ * node is an initialized object. If start.node == finish.node, then
+ * [start.cur, finish.cur) are initialized objects, and the elements outside
+ * that range are uninitialized storage. Otherwise, [start.cur, start.last)
+ * and [finish.first, finish.cur) are initialized objects, and [start.first,
+ * start.cur) and [finish.cur, finish.last) are uninitialized storage.
+ * - [%map, %map + map_size) is a valid, non-empty range.
+ * - [start.node, finish.node] is a valid range contained within
+ * [%map, %map + map_size).
+ * - A pointer in the range [%map, %map + map_size) points to an allocated node
+ * if and only if the pointer is in the range [start.node, finish.node].
+ *
+ * Here's the magic: nothing in deque is "aware" of the discontiguous storage!
+ *
+ * The memory setup and layout occurs in the parent, _Base, and the iterator
+ * class is entirely responsible for "leaping" from one node to the next. All
+ * 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.
+ * @endif
+*/
+template <class _Tp, class _Alloc = allocator<_Tp> >
+class deque : protected _Deque_base<_Tp, _Alloc>
+{
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+
+ typedef _Deque_base<_Tp, _Alloc> _Base;
+
+public:
+ typedef _Tp value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ typedef typename _Base::allocator_type allocator_type;
+ allocator_type get_allocator() const { return _Base::get_allocator(); }
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef reverse_iterator<iterator> reverse_iterator;
+
+protected:
+ typedef pointer* _Map_pointer;
+ static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
+
+ // Functions controlling memory layout, and nothing else.
+ using _Base::_M_initialize_map;
+ using _Base::_M_create_nodes;
+ using _Base::_M_destroy_nodes;
+ using _Base::_M_allocate_node;
+ using _Base::_M_deallocate_node;
+ using _Base::_M_allocate_map;
+ using _Base::_M_deallocate_map;
+
+ /** @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.
+ * @endif
+ */
+ using _Base::_M_map;
+ using _Base::_M_map_size;
+ using _Base::_M_start;
+ using _Base::_M_finish;
+
+public: // Basic accessors
+ iterator begin() { return _M_start; }
+ iterator end() { return _M_finish; }
+ const_iterator begin() const { return _M_start; }
+ const_iterator end() const { return _M_finish; }
+
+ reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
+ reverse_iterator rend() { return reverse_iterator(_M_start); }
+ const_reverse_iterator rbegin() const
+ { return const_reverse_iterator(_M_finish); }
+ const_reverse_iterator rend() const
+ { return const_reverse_iterator(_M_start); }
+
+ reference operator[](size_type __n)
+ { return _M_start[difference_type(__n)]; }
+ const_reference operator[](size_type __n) const
+ { return _M_start[difference_type(__n)]; }
+
+ void _M_range_check(size_type __n) const {
+ if (__n >= this->size())
+ __throw_range_error("deque");
+ }
+
+ reference at(size_type __n)
+ { _M_range_check(__n); return (*this)[__n]; }
+ const_reference at(size_type __n) const
+ { _M_range_check(__n); return (*this)[__n]; }
+
+ reference front() { return *_M_start; }
+ reference back() {
+ iterator __tmp = _M_finish;
+ --__tmp;
+ return *__tmp;
+ }
+ const_reference front() const { return *_M_start; }
+ const_reference back() const {
+ const_iterator __tmp = _M_finish;
+ --__tmp;
+ return *__tmp;
+ }
+
+ size_type size() const { return _M_finish - _M_start; }
+ size_type max_size() const { return size_type(-1); }
+ bool empty() const { return _M_finish == _M_start; }
+
+public: // Constructor, destructor.
+ explicit deque(const allocator_type& __a = allocator_type())
+ : _Base(__a, 0) {}
+ deque(const deque& __x) : _Base(__x.get_allocator(), __x.size())
+ { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
+ deque(size_type __n, const value_type& __value,
+ const allocator_type& __a = allocator_type()) : _Base(__a, __n)
+ { _M_fill_initialize(__value); }
+
+ explicit
+ deque(size_type __n)
+ : _Base(allocator_type(), __n)
+ { _M_fill_initialize(value_type()); }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+ template<class _InputIterator>
+ deque(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_initialize_dispatch(__first, __last, _Integral());
+ }
+
+ template<class _Integer>
+ void
+ _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
+ {
+ _M_initialize_map(__n);
+ _M_fill_initialize(__x);
+ }
+
+ template<class _InputIter>
+ void
+ _M_initialize_dispatch(_InputIter __first, _InputIter __last, __false_type)
+ {
+ typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
+ _M_range_initialize(__first, __last, _IterCategory());
+ }
+
+ ~deque()
+ { _Destroy(_M_start, _M_finish); }
+
+ deque& operator= (const deque& __x) {
+ const size_type __len = size();
+ if (&__x != this) {
+ if (__len >= __x.size())
+ erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
+ else {
+ const_iterator __mid = __x.begin() + difference_type(__len);
+ copy(__x.begin(), __mid, _M_start);
+ insert(_M_finish, __mid, __x.end());
+ }
+ }
+ return *this;
+ }
+
+ void swap(deque& __x) {
+ std::swap(_M_start, __x._M_start);
+ std::swap(_M_finish, __x._M_finish);
+ std::swap(_M_map, __x._M_map);
+ std::swap(_M_map_size, __x._M_map_size);
+ }
+
+public:
+ // assign(), a generalized assignment member function. Two
+ // versions: one that takes a count, and one that takes a range.
+ // The range version is a member template, so we dispatch on whether
+ // or not the type is an integer.
+
+ void _M_fill_assign(size_type __n, const _Tp& __val) {
+ if (__n > size()) {
+ fill(begin(), end(), __val);
+ insert(end(), __n - size(), __val);
+ }
+ else {
+ erase(begin() + __n, end());
+ fill(begin(), end(), __val);
+ }
+ }
+
+ void
+ assign(size_type __n, const _Tp& __val)
+ { _M_fill_assign(__n, __val); }
+
+ template<class _InputIterator>
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_assign_dispatch(__first, __last, _Integral());
+ }
+
+private: // helper functions for assign()
+
+ template<class _Integer>
+ void
+ _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+ { _M_fill_assign(static_cast<size_type>(__n), static_cast<_Tp>(__val)); }
+
+ template<class _InputIterator>
+ void
+ _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type)
+ {
+ typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
+ _M_assign_aux(__first, __last, _IterCategory());
+ }
+
+ template <class _InputIterator>
+ 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) {
+ size_type __len = distance(__first, __last);
+ if (__len > size()) {
+ _ForwardIterator __mid = __first;
+ advance(__mid, size());
+ copy(__first, __mid, begin());
+ insert(end(), __mid, __last);
+ }
+ else
+ erase(copy(__first, __last, begin()), end());
+ }
+
+public: // push_* and pop_*
+
+ void
+ push_back(const value_type& __t)
+ {
+ if (_M_finish._M_cur != _M_finish._M_last - 1) {
+ _Construct(_M_finish._M_cur, __t);
+ ++_M_finish._M_cur;
+ }
+ else
+ _M_push_back_aux(__t);
+ }
+
+ void
+ push_back()
+ {
+ if (_M_finish._M_cur != _M_finish._M_last - 1) {
+ _Construct(_M_finish._M_cur);
+ ++_M_finish._M_cur;
+ }
+ else
+ _M_push_back_aux();
+ }
+
+ void
+ push_front(const value_type& __t)
+ {
+ if (_M_start._M_cur != _M_start._M_first) {
+ _Construct(_M_start._M_cur - 1, __t);
+ --_M_start._M_cur;
+ }
+ else
+ _M_push_front_aux(__t);
+ }
+
+ void
+ push_front()
+ {
+ if (_M_start._M_cur != _M_start._M_first) {
+ _Construct(_M_start._M_cur - 1);
+ --_M_start._M_cur;
+ }
+ else
+ _M_push_front_aux();
+ }
+
+
+ void
+ pop_back()
+ {
+ if (_M_finish._M_cur != _M_finish._M_first) {
+ --_M_finish._M_cur;
+ _Destroy(_M_finish._M_cur);
+ }
+ else
+ _M_pop_back_aux();
+ }
+
+ void
+ pop_front()
+ {
+ if (_M_start._M_cur != _M_start._M_last - 1) {
+ _Destroy(_M_start._M_cur);
+ ++_M_start._M_cur;
+ }
+ else
+ _M_pop_front_aux();
+ }
+
+public: // Insert
+
+ iterator
+ insert(iterator position, const value_type& __x)
+ {
+ if (position._M_cur == _M_start._M_cur) {
+ push_front(__x);
+ return _M_start;
+ }
+ else if (position._M_cur == _M_finish._M_cur) {
+ push_back(__x);
+ iterator __tmp = _M_finish;
+ --__tmp;
+ return __tmp;
+ }
+ else {
+ return _M_insert_aux(position, __x);
+ }
+ }
+
+ iterator
+ insert(iterator __position)
+ { return insert(__position, value_type()); }
+
+ void
+ insert(iterator __pos, size_type __n, const value_type& __x)
+ { _M_fill_insert(__pos, __n, __x); }
+
+ void
+ _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+ template<class _InputIterator>
+ void
+ insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_insert_dispatch(__pos, __first, __last, _Integral());
+ }
+
+ template<class _Integer>
+ void
+ _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type)
+ { _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<value_type>(__x)); }
+
+ template<class _InputIterator>
+ void
+ _M_insert_dispatch(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ __false_type)
+ {
+ typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
+ insert(__pos, __first, __last, _IterCategory());
+ }
+
+ void resize(size_type __new_size, const value_type& __x) {
+ const size_type __len = size();
+ if (__new_size < __len)
+ erase(_M_start + __new_size, _M_finish);
+ else
+ insert(_M_finish, __new_size - __len, __x);
+ }
+
+ void resize(size_type new_size) { resize(new_size, value_type()); }
+
+public: // Erase
+ iterator erase(iterator __pos) {
+ iterator __next = __pos;
+ ++__next;
+ size_type __index = __pos - _M_start;
+ if (__index < (size() >> 1)) {
+ copy_backward(_M_start, __pos, __next);
+ pop_front();
+ }
+ else {
+ copy(__next, _M_finish, __pos);
+ pop_back();
+ }
+ return _M_start + __index;
+ }
+
+ iterator erase(iterator __first, iterator __last);
+ void clear();
+
+protected: // Internal construction/destruction
+
+ void _M_fill_initialize(const value_type& __value);
+
+ template <class _InputIterator>
+ void _M_range_initialize(_InputIterator __first, _InputIterator __last,
+ input_iterator_tag);
+
+ template <class _ForwardIterator>
+ void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag);
+
+protected: // Internal push_* and pop_*
+
+ void _M_push_back_aux(const value_type&);
+ void _M_push_back_aux();
+ void _M_push_front_aux(const value_type&);
+ void _M_push_front_aux();
+ void _M_pop_back_aux();
+ void _M_pop_front_aux();
+
+protected: // Internal insert functions
+
+ template <class _InputIterator>
+ void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
+ input_iterator_tag);
+
+ template <class _ForwardIterator>
+ void insert(iterator __pos,
+ _ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag);
+
+ iterator _M_insert_aux(iterator __pos, const value_type& __x);
+ iterator _M_insert_aux(iterator __pos);
+ void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
+
+ template <class _ForwardIterator>
+ void _M_insert_aux(iterator __pos,
+ _ForwardIterator __first, _ForwardIterator __last,
+ size_type __n);
+
+ iterator _M_reserve_elements_at_front(size_type __n) {
+ size_type __vacancies = _M_start._M_cur - _M_start._M_first;
+ if (__n > __vacancies)
+ _M_new_elements_at_front(__n - __vacancies);
+ return _M_start - difference_type(__n);
+ }
+
+ iterator _M_reserve_elements_at_back(size_type __n) {
+ size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
+ if (__n > __vacancies)
+ _M_new_elements_at_back(__n - __vacancies);
+ return _M_finish + difference_type(__n);
+ }
+
+ void _M_new_elements_at_front(size_type __new_elements);
+ void _M_new_elements_at_back(size_type __new_elements);
+
+protected: // Allocation of _M_map and nodes
+
+ // Makes sure the _M_map has space for new nodes. Does not actually
+ // add the nodes. Can invalidate _M_map pointers. (And consequently,
+ // deque iterators.)
+
+ void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
+ if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
+ _M_reallocate_map(__nodes_to_add, false);
+ }
+
+ void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
+ if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
+ _M_reallocate_map(__nodes_to_add, true);
+ }
+
+ void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
+};
+
+// Non-inline member functions
+
+template <class _Tp, class _Alloc>
+template <class _InputIter>
+void deque<_Tp, _Alloc>
+ ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
+{
+ iterator __cur = begin();
+ for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
+ *__cur = *__first;
+ if (__first == __last)
+ erase(__cur, end());
+ else
+ insert(end(), __first, __last);
+}
+
+template <class _Tp, class _Alloc>
+void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
+ size_type __n, const value_type& __x)
+{
+ if (__pos._M_cur == _M_start._M_cur) {
+ iterator __new_start = _M_reserve_elements_at_front(__n);
+ try {
+ uninitialized_fill(__new_start, _M_start, __x);
+ _M_start = __new_start;
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
+ __throw_exception_again;
+ }
+ }
+ else if (__pos._M_cur == _M_finish._M_cur) {
+ iterator __new_finish = _M_reserve_elements_at_back(__n);
+ try {
+ uninitialized_fill(_M_finish, __new_finish, __x);
+ _M_finish = __new_finish;
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+ __throw_exception_again;
+ }
+ }
+ else
+ _M_insert_aux(__pos, __n, __x);
+}
+
+template <class _Tp, class _Alloc>
+typename deque<_Tp,_Alloc>::iterator
+deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
+{
+ if (__first == _M_start && __last == _M_finish) {
+ clear();
+ return _M_finish;
+ }
+ else {
+ difference_type __n = __last - __first;
+ difference_type __elems_before = __first - _M_start;
+ if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) {
+ copy_backward(_M_start, __first, __last);
+ iterator __new_start = _M_start + __n;
+ _Destroy(_M_start, __new_start);
+ _M_destroy_nodes(_M_start._M_node, __new_start._M_node);
+ _M_start = __new_start;
+ }
+ else {
+ copy(__last, _M_finish, __first);
+ iterator __new_finish = _M_finish - __n;
+ _Destroy(__new_finish, _M_finish);
+ _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
+ _M_finish = __new_finish;
+ }
+ return _M_start + __elems_before;
+ }
+}
+
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::clear()
+{
+ for (_Map_pointer __node = _M_start._M_node + 1;
+ __node < _M_finish._M_node;
+ ++__node) {
+ _Destroy(*__node, *__node + _S_buffer_size());
+ _M_deallocate_node(*__node);
+ }
+
+ if (_M_start._M_node != _M_finish._M_node) {
+ _Destroy(_M_start._M_cur, _M_start._M_last);
+ _Destroy(_M_finish._M_first, _M_finish._M_cur);
+ _M_deallocate_node(_M_finish._M_first);
+ }
+ else
+ _Destroy(_M_start._M_cur, _M_finish._M_cur);
+
+ _M_finish = _M_start;
+}
+
+/**
+ * @if maint
+ * @brief Fills the deque with copies of value.
+ * @param value Initial value.
+ * @return Nothing.
+ * @pre _M_start and _M_finish have already been initialized, but none of the
+ * deque's elements have yet been constructed.
+ *
+ * This function is called only when the user provides an explicit size (with
+ * or without an explicit exemplar value).
+ * @endif
+*/
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value)
+{
+ _Map_pointer __cur;
+ try {
+ for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
+ uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
+ uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
+ }
+ catch(...)
+ {
+ _Destroy(_M_start, iterator(*__cur, __cur));
+ __throw_exception_again;
+ }
+}
+
+/** @{
+ * @if maint
+ * @brief Fills the deque with whatever is in [first,last).
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @return Nothing.
+ *
+ * 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.
+ * @endif
+*/
+template <class _Tp, class _Alloc> template <class _InputIterator>
+void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
+ _InputIterator __last,
+ input_iterator_tag)
+{
+ _M_initialize_map(0);
+ try {
+ for ( ; __first != __last; ++__first)
+ push_back(*__first);
+ }
+ catch(...)
+ {
+ clear();
+ __throw_exception_again;
+ }
+}
+
+template <class _Tp, class _Alloc> template <class _ForwardIterator>
+void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first,
+ _ForwardIterator __last,
+ forward_iterator_tag)
+{
+ size_type __n = distance(__first, __last);
+ _M_initialize_map(__n);
+
+ _Map_pointer __cur_node;
+ try {
+ for (__cur_node = _M_start._M_node;
+ __cur_node < _M_finish._M_node;
+ ++__cur_node) {
+ _ForwardIterator __mid = __first;
+ advance(__mid, _S_buffer_size());
+ uninitialized_copy(__first, __mid, *__cur_node);
+ __first = __mid;
+ }
+ uninitialized_copy(__first, __last, _M_finish._M_first);
+ }
+ catch(...)
+ {
+ _Destroy(_M_start, iterator(*__cur_node, __cur_node));
+ __throw_exception_again;
+ }
+}
+/** @} */
+
+// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
+template <class _Tp, class _Alloc>
+void
+deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
+{
+ value_type __t_copy = __t;
+ _M_reserve_map_at_back();
+ *(_M_finish._M_node + 1) = _M_allocate_node();
+ try {
+ _Construct(_M_finish._M_cur, __t_copy);
+ _M_finish._M_set_node(_M_finish._M_node + 1);
+ _M_finish._M_cur = _M_finish._M_first;
+ }
+ catch(...)
+ {
+ _M_deallocate_node(*(_M_finish._M_node + 1));
+ __throw_exception_again;
+ }
+}
+
+// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
+template <class _Tp, class _Alloc>
+void
+deque<_Tp,_Alloc>::_M_push_back_aux()
+{
+ _M_reserve_map_at_back();
+ *(_M_finish._M_node + 1) = _M_allocate_node();
+ try {
+ _Construct(_M_finish._M_cur);
+ _M_finish._M_set_node(_M_finish._M_node + 1);
+ _M_finish._M_cur = _M_finish._M_first;
+ }
+ catch(...)
+ {
+ _M_deallocate_node(*(_M_finish._M_node + 1));
+ __throw_exception_again;
+ }
+}
+
+// Called only if _M_start._M_cur == _M_start._M_first.
+template <class _Tp, class _Alloc>
+void
+deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
+{
+ value_type __t_copy = __t;
+ _M_reserve_map_at_front();
+ *(_M_start._M_node - 1) = _M_allocate_node();
+ try {
+ _M_start._M_set_node(_M_start._M_node - 1);
+ _M_start._M_cur = _M_start._M_last - 1;
+ _Construct(_M_start._M_cur, __t_copy);
+ }
+ catch(...)
+ {
+ ++_M_start;
+ _M_deallocate_node(*(_M_start._M_node - 1));
+ __throw_exception_again;
+ }
+}
+
+// Called only if _M_start._M_cur == _M_start._M_first.
+template <class _Tp, class _Alloc>
+void
+deque<_Tp,_Alloc>::_M_push_front_aux()
+{
+ _M_reserve_map_at_front();
+ *(_M_start._M_node - 1) = _M_allocate_node();
+ try {
+ _M_start._M_set_node(_M_start._M_node - 1);
+ _M_start._M_cur = _M_start._M_last - 1;
+ _Construct(_M_start._M_cur);
+ }
+ catch(...)
+ {
+ ++_M_start;
+ _M_deallocate_node(*(_M_start._M_node - 1));
+ __throw_exception_again;
+ }
+}
+
+// Called only if _M_finish._M_cur == _M_finish._M_first.
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::_M_pop_back_aux()
+{
+ _M_deallocate_node(_M_finish._M_first);
+ _M_finish._M_set_node(_M_finish._M_node - 1);
+ _M_finish._M_cur = _M_finish._M_last - 1;
+ _Destroy(_M_finish._M_cur);
+}
+
+// Called only if _M_start._M_cur == _M_start._M_last - 1. Note that
+// if the deque has at least one element (a precondition for this member
+// function), and if _M_start._M_cur == _M_start._M_last, then the deque
+// must have at least two nodes.
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::_M_pop_front_aux()
+{
+ _Destroy(_M_start._M_cur);
+ _M_deallocate_node(_M_start._M_first);
+ _M_start._M_set_node(_M_start._M_node + 1);
+ _M_start._M_cur = _M_start._M_first;
+}
+
+template <class _Tp, class _Alloc> template <class _InputIterator>
+void deque<_Tp,_Alloc>::insert(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ input_iterator_tag)
+{
+ copy(__first, __last, inserter(*this, __pos));
+}
+
+template <class _Tp, class _Alloc> template <class _ForwardIterator>
+void
+deque<_Tp,_Alloc>::insert(iterator __pos,
+ _ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag) {
+ size_type __n = distance(__first, __last);
+ if (__pos._M_cur == _M_start._M_cur) {
+ iterator __new_start = _M_reserve_elements_at_front(__n);
+ try {
+ uninitialized_copy(__first, __last, __new_start);
+ _M_start = __new_start;
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
+ __throw_exception_again;
+ }
+ }
+ else if (__pos._M_cur == _M_finish._M_cur) {
+ iterator __new_finish = _M_reserve_elements_at_back(__n);
+ try {
+ uninitialized_copy(__first, __last, _M_finish);
+ _M_finish = __new_finish;
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+ __throw_exception_again;
+ }
+ }
+ else
+ _M_insert_aux(__pos, __first, __last, __n);
+}
+
+template <class _Tp, class _Alloc>
+typename deque<_Tp, _Alloc>::iterator
+deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
+{
+ difference_type __index = __pos - _M_start;
+ value_type __x_copy = __x;
+ if (static_cast<size_type>(__index) < size() / 2) {
+ push_front(front());
+ iterator __front1 = _M_start;
+ ++__front1;
+ iterator __front2 = __front1;
+ ++__front2;
+ __pos = _M_start + __index;
+ iterator __pos1 = __pos;
+ ++__pos1;
+ copy(__front2, __pos1, __front1);
+ }
+ else {
+ push_back(back());
+ iterator __back1 = _M_finish;
+ --__back1;
+ iterator __back2 = __back1;
+ --__back2;
+ __pos = _M_start + __index;
+ copy_backward(__pos, __back2, __back1);
+ }
+ *__pos = __x_copy;
+ return __pos;
+}
+
+template <class _Tp, class _Alloc>
+typename deque<_Tp,_Alloc>::iterator
+deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
+{
+ difference_type __index = __pos - _M_start;
+ if (static_cast<size_type>(__index) < size() / 2) {
+ push_front(front());
+ iterator __front1 = _M_start;
+ ++__front1;
+ iterator __front2 = __front1;
+ ++__front2;
+ __pos = _M_start + __index;
+ iterator __pos1 = __pos;
+ ++__pos1;
+ copy(__front2, __pos1, __front1);
+ }
+ else {
+ push_back(back());
+ iterator __back1 = _M_finish;
+ --__back1;
+ iterator __back2 = __back1;
+ --__back2;
+ __pos = _M_start + __index;
+ copy_backward(__pos, __back2, __back1);
+ }
+ *__pos = value_type();
+ return __pos;
+}
+
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
+ size_type __n,
+ const value_type& __x)
+{
+ const difference_type __elems_before = __pos - _M_start;
+ size_type __length = this->size();
+ value_type __x_copy = __x;
+ if (__elems_before < difference_type(__length / 2)) {
+ iterator __new_start = _M_reserve_elements_at_front(__n);
+ iterator __old_start = _M_start;
+ __pos = _M_start + __elems_before;
+ try {
+ if (__elems_before >= difference_type(__n)) {
+ iterator __start_n = _M_start + difference_type(__n);
+ uninitialized_copy(_M_start, __start_n, __new_start);
+ _M_start = __new_start;
+ copy(__start_n, __pos, __old_start);
+ fill(__pos - difference_type(__n), __pos, __x_copy);
+ }
+ else {
+ __uninitialized_copy_fill(_M_start, __pos, __new_start,
+ _M_start, __x_copy);
+ _M_start = __new_start;
+ fill(__old_start, __pos, __x_copy);
+ }
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
+ __throw_exception_again;
+ }
+ }
+ else {
+ iterator __new_finish = _M_reserve_elements_at_back(__n);
+ iterator __old_finish = _M_finish;
+ const difference_type __elems_after =
+ difference_type(__length) - __elems_before;
+ __pos = _M_finish - __elems_after;
+ try {
+ if (__elems_after > difference_type(__n)) {
+ iterator __finish_n = _M_finish - difference_type(__n);
+ uninitialized_copy(__finish_n, _M_finish, _M_finish);
+ _M_finish = __new_finish;
+ copy_backward(__pos, __finish_n, __old_finish);
+ fill(__pos, __pos + difference_type(__n), __x_copy);
+ }
+ else {
+ __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
+ __x_copy, __pos, _M_finish);
+ _M_finish = __new_finish;
+ fill(__pos, __old_finish, __x_copy);
+ }
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+ __throw_exception_again;
+ }
+ }
+}
+
+template <class _Tp, class _Alloc> template <class _ForwardIterator>
+void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ size_type __n)
+{
+ const difference_type __elemsbefore = __pos - _M_start;
+ size_type __length = size();
+ if (static_cast<size_type>(__elemsbefore) < __length / 2) {
+ iterator __new_start = _M_reserve_elements_at_front(__n);
+ iterator __old_start = _M_start;
+ __pos = _M_start + __elemsbefore;
+ try {
+ if (__elemsbefore >= difference_type(__n)) {
+ iterator __start_n = _M_start + difference_type(__n);
+ uninitialized_copy(_M_start, __start_n, __new_start);
+ _M_start = __new_start;
+ copy(__start_n, __pos, __old_start);
+ copy(__first, __last, __pos - difference_type(__n));
+ }
+ else {
+ _ForwardIterator __mid = __first;
+ advance(__mid, difference_type(__n) - __elemsbefore);
+ __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
+ __new_start);
+ _M_start = __new_start;
+ copy(__mid, __last, __old_start);
+ }
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
+ __throw_exception_again;
+ }
+ }
+ else {
+ iterator __new_finish = _M_reserve_elements_at_back(__n);
+ iterator __old_finish = _M_finish;
+ const difference_type __elemsafter =
+ difference_type(__length) - __elemsbefore;
+ __pos = _M_finish - __elemsafter;
+ try {
+ if (__elemsafter > difference_type(__n)) {
+ iterator __finish_n = _M_finish - difference_type(__n);
+ uninitialized_copy(__finish_n, _M_finish, _M_finish);
+ _M_finish = __new_finish;
+ copy_backward(__pos, __finish_n, __old_finish);
+ copy(__first, __last, __pos);
+ }
+ else {
+ _ForwardIterator __mid = __first;
+ advance(__mid, __elemsafter);
+ __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
+ _M_finish = __new_finish;
+ copy(__first, __mid, __pos);
+ }
+ }
+ catch(...)
+ {
+ _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+ __throw_exception_again;
+ }
+ }
+}
+
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
+{
+ size_type __new_nodes
+ = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
+ _M_reserve_map_at_front(__new_nodes);
+ size_type __i;
+ try {
+ for (__i = 1; __i <= __new_nodes; ++__i)
+ *(_M_start._M_node - __i) = _M_allocate_node();
+ }
+ catch(...) {
+ for (size_type __j = 1; __j < __i; ++__j)
+ _M_deallocate_node(*(_M_start._M_node - __j));
+ __throw_exception_again;
+ }
+}
+
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
+{
+ size_type __new_nodes
+ = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
+ _M_reserve_map_at_back(__new_nodes);
+ size_type __i;
+ try {
+ for (__i = 1; __i <= __new_nodes; ++__i)
+ *(_M_finish._M_node + __i) = _M_allocate_node();
+ }
+ catch(...) {
+ for (size_type __j = 1; __j < __i; ++__j)
+ _M_deallocate_node(*(_M_finish._M_node + __j));
+ __throw_exception_again;
+ }
+}
+
+template <class _Tp, class _Alloc>
+void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
+ bool __add_at_front)
+{
+ size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
+ size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
+
+ _Map_pointer __new_nstart;
+ if (_M_map_size > 2 * __new_num_nodes) {
+ __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2
+ + (__add_at_front ? __nodes_to_add : 0);
+ if (__new_nstart < _M_start._M_node)
+ copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
+ else
+ copy_backward(_M_start._M_node, _M_finish._M_node + 1,
+ __new_nstart + __old_num_nodes);
+ }
+ else {
+ size_type __new_map_size =
+ _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
+
+ _Map_pointer __new_map = _M_allocate_map(__new_map_size);
+ __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
+ + (__add_at_front ? __nodes_to_add : 0);
+ copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
+ _M_deallocate_map(_M_map, _M_map_size);
+
+ _M_map = __new_map;
+ _M_map_size = __new_map_size;
+ }
+
+ _M_start._M_set_node(__new_nstart);
+ _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
+}
+
+
+// Nonmember functions.
+
+template <class _Tp, class _Alloc>
+inline bool operator==(const deque<_Tp, _Alloc>& __x,
+ const deque<_Tp, _Alloc>& __y) {
+ return __x.size() == __y.size() &&
+ equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp, class _Alloc>
+inline bool operator<(const deque<_Tp, _Alloc>& __x,
+ const deque<_Tp, _Alloc>& __y) {
+ return lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end());
+}
+
+template <class _Tp, class _Alloc>
+inline bool operator!=(const deque<_Tp, _Alloc>& __x,
+ const deque<_Tp, _Alloc>& __y) {
+ return !(__x == __y);
+}
+
+template <class _Tp, class _Alloc>
+inline bool operator>(const deque<_Tp, _Alloc>& __x,
+ const deque<_Tp, _Alloc>& __y) {
+ return __y < __x;
+}
+
+template <class _Tp, class _Alloc>
+inline bool operator<=(const deque<_Tp, _Alloc>& __x,
+ const deque<_Tp, _Alloc>& __y) {
+ return !(__y < __x);
+}
+template <class _Tp, class _Alloc>
+inline bool operator>=(const deque<_Tp, _Alloc>& __x,
+ const deque<_Tp, _Alloc>& __y) {
+ return !(__x < __y);
+}
+
+template <class _Tp, class _Alloc>
+inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) {
+ __x.swap(__y);
+}
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_DEQUE_H */
+
diff --git a/contrib/libstdc++/include/bits/stl_function.h b/contrib/libstdc++/include/bits/stl_function.h
new file mode 100644
index 0000000000000..9ea975d4a8dc8
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_function.h
@@ -0,0 +1,736 @@
+// Functor implementations -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996-1998
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_function.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_FUNCTION_H
+#define __GLIBCPP_INTERNAL_FUNCTION_H
+
+namespace std
+{
+// 20.3.1 base classes
+/** @defgroup s20_3_1_base Functor Base Classes
+ * Function objects, or @e functors, are objects with an @c operator()
+ * defined and accessible. They can be passed as arguments to algorithm
+ * templates and used in place of a function pointer. Not only is the
+ * resulting expressiveness of the library increased, but the generated
+ * code can be more efficient than what you might write by hand. When we
+ * refer to "functors," then, generally we include function pointers in
+ * the description as well.
+ *
+ * Often, functors are only created as temporaries passed to algorithm
+ * calls, rather than being created as named variables.
+ *
+ * Two examples taken from the standard itself follow. To perform a
+ * by-element addition of two vectors @c a and @c b containing @c double,
+ * and put the result in @c a, use
+ * \code
+ * transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
+ * \endcode
+ * To negate every element in @c a, use
+ * \code
+ * transform(a.begin(), a.end(), a.begin(), negate<double>());
+ * \endcode
+ * The addition and negation functions will be inlined directly.
+ *
+ * The standard functiors are derived from structs named @c unary_function
+ * and @c binary_function. These two classes contain nothing but typedefs,
+ * to aid in generic (template) programming. If you write your own
+ * functors, you might consider doing the same.
+ *
+ * @{
+*/
+/**
+ * This is one of the @link s20_3_1_base functor base classes@endlink.
+*/
+template <class _Arg, class _Result>
+struct unary_function {
+ typedef _Arg argument_type; ///< @c argument_type is the type of the argument (no surprises here)
+ typedef _Result result_type; ///< @c result_type is the return type
+};
+
+/**
+ * This is one of the @link s20_3_1_base functor base classes@endlink.
+*/
+template <class _Arg1, class _Arg2, class _Result>
+struct binary_function {
+ typedef _Arg1 first_argument_type; ///< the type of the first argument (no surprises here)
+ typedef _Arg2 second_argument_type; ///< the type of the second argument
+ typedef _Result result_type; ///< type of the return type
+};
+/** @} */
+
+// 20.3.2 arithmetic
+/** @defgroup s20_3_2_arithmetic Arithmetic Classes
+ * Because basic math often needs to be done during an algorithm, the library
+ * provides functors for those operations. See the documentation for
+ * @link s20_3_1_base the base classes@endlink for examples of their use.
+ *
+ * @{
+*/
+/// One of the @link s20_3_2_arithmetic math functors@endlink.
+template <class _Tp>
+struct plus : public binary_function<_Tp,_Tp,_Tp> {
+ _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; }
+};
+
+/// One of the @link s20_3_2_arithmetic math functors@endlink.
+template <class _Tp>
+struct minus : public binary_function<_Tp,_Tp,_Tp> {
+ _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; }
+};
+
+/// One of the @link s20_3_2_arithmetic math functors@endlink.
+template <class _Tp>
+struct multiplies : public binary_function<_Tp,_Tp,_Tp> {
+ _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; }
+};
+
+/// One of the @link s20_3_2_arithmetic math functors@endlink.
+template <class _Tp>
+struct divides : public binary_function<_Tp,_Tp,_Tp> {
+ _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; }
+};
+
+/// One of the @link s20_3_2_arithmetic math functors@endlink.
+template <class _Tp>
+struct modulus : public binary_function<_Tp,_Tp,_Tp>
+{
+ _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; }
+};
+
+/// One of the @link s20_3_2_arithmetic math functors@endlink.
+template <class _Tp>
+struct negate : public unary_function<_Tp,_Tp>
+{
+ _Tp operator()(const _Tp& __x) const { return -__x; }
+};
+/** @} */
+
+// 20.3.3 comparisons
+/** @defgroup s20_3_3_comparisons Comparison Classes
+ * The library provides six wrapper functors for all the basic comparisons
+ * in C++, like @c <.
+ *
+ * @{
+*/
+/// One of the @link s20_3_3_comparisons comparison functors@endlink.
+template <class _Tp>
+struct equal_to : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; }
+};
+
+/// One of the @link s20_3_3_comparisons comparison functors@endlink.
+template <class _Tp>
+struct not_equal_to : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; }
+};
+
+/// One of the @link s20_3_3_comparisons comparison functors@endlink.
+template <class _Tp>
+struct greater : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; }
+};
+
+/// One of the @link s20_3_3_comparisons comparison functors@endlink.
+template <class _Tp>
+struct less : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
+};
+
+/// One of the @link s20_3_3_comparisons comparison functors@endlink.
+template <class _Tp>
+struct greater_equal : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; }
+};
+
+/// One of the @link s20_3_3_comparisons comparison functors@endlink.
+template <class _Tp>
+struct less_equal : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; }
+};
+/** @} */
+
+// 20.3.4 logical operations
+/** @defgroup s20_3_4_logical Boolean Operations Classes
+ * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !.
+ *
+ * @{
+*/
+/// One of the @link s20_3_4_logical Boolean operations functors@endlink.
+template <class _Tp>
+struct logical_and : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; }
+};
+
+/// One of the @link s20_3_4_logical Boolean operations functors@endlink.
+template <class _Tp>
+struct logical_or : public binary_function<_Tp,_Tp,bool>
+{
+ bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; }
+};
+
+/// One of the @link s20_3_4_logical Boolean operations functors@endlink.
+template <class _Tp>
+struct logical_not : public unary_function<_Tp,bool>
+{
+ bool operator()(const _Tp& __x) const { return !__x; }
+};
+/** @} */
+
+// 20.3.5 negators
+/** @defgroup s20_3_5_negators Negators
+ * The functions @c not1 and @c not2 each take a predicate functor
+ * and return an instance of @c unary_negate or
+ * @c binary_negate, respectively. These classes are functors whose
+ * @c operator() performs the stored predicate function and then returns
+ * the negation of the result.
+ *
+ * For example, given a vector of integers and a trivial predicate,
+ * \code
+ * struct IntGreaterThanThree
+ * : public std::unary_function<int, bool>
+ * {
+ * bool operator() (int x) { return x > 3; }
+ * };
+ *
+ * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree()));
+ * \endcode
+ * The call to @c find_if will locate the first index (i) of @c v for which
+ * "!(v[i] > 3)" is true.
+ *
+ * The not1/unary_negate combination works on predicates taking a single
+ * argument. The not2/binary_negate combination works on predicates which
+ * take two arguments.
+ *
+ * @{
+*/
+/// One of the @link s20_3_5_negators negation functors@endlink.
+template <class _Predicate>
+class unary_negate
+ : public unary_function<typename _Predicate::argument_type, bool> {
+protected:
+ _Predicate _M_pred;
+public:
+ explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {}
+ bool operator()(const typename _Predicate::argument_type& __x) const {
+ return !_M_pred(__x);
+ }
+};
+
+/// One of the @link s20_3_5_negators negation functors@endlink.
+template <class _Predicate>
+inline unary_negate<_Predicate>
+not1(const _Predicate& __pred)
+{
+ return unary_negate<_Predicate>(__pred);
+}
+
+/// One of the @link s20_3_5_negators negation functors@endlink.
+template <class _Predicate>
+class binary_negate
+ : public binary_function<typename _Predicate::first_argument_type,
+ typename _Predicate::second_argument_type,
+ bool> {
+protected:
+ _Predicate _M_pred;
+public:
+ explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {}
+ bool operator()(const typename _Predicate::first_argument_type& __x,
+ const typename _Predicate::second_argument_type& __y) const
+ {
+ return !_M_pred(__x, __y);
+ }
+};
+
+/// One of the @link s20_3_5_negators negation functors@endlink.
+template <class _Predicate>
+inline binary_negate<_Predicate>
+not2(const _Predicate& __pred)
+{
+ return binary_negate<_Predicate>(__pred);
+}
+/** @} */
+
+// 20.3.6 binders
+/** @defgroup s20_3_6_binder Binder Classes
+ * Binders turn functions/functors with two arguments into functors with
+ * a single argument, storing an argument to be applied later. For
+ * example, an variable @c B of type @c binder1st is constructed from a functor
+ * @c f and an argument @c x. Later, B's @c operator() is called with a
+ * single argument @c y. The return value is the value of @c f(x,y).
+ * @c B can be "called" with various arguments (y1, y2, ...) and will in
+ * turn call @c f(x,y1), @c f(x,y2), ...
+ *
+ * The function @c bind1st is provided to save some typing. It takes the
+ * function and an argument as parameters, and returns an instance of
+ * @c binder1st.
+ *
+ * The type @c binder2nd and its creator function @c bind2nd do the same
+ * thing, but the stored argument is passed as the second parameter instead
+ * of the first, e.g., @c bind2nd(std::minus<float>,1.3) will create a
+ * functor whose @c operator() accepts a floating-point number, subtracts
+ * 1.3 from it, and returns the result. (If @c bind1st had been used,
+ * the functor would perform "1.3 - x" instead.
+ *
+ * Creator-wrapper functions like @c bind1st are intended to be used in
+ * calling algorithms. Their return values will be temporary objects.
+ * (The goal is to not require you to type names like
+ * @c std::binder1st<std::plus<int>> for declaring a variable to hold the
+ * return value from @c bind1st(std::plus<int>,5).
+ *
+ * These become more useful when combined with the composition functions.
+ *
+ * @{
+*/
+/// One of the @link s20_3_6_binder binder functors@endlink.
+template <class _Operation>
+class binder1st
+ : public unary_function<typename _Operation::second_argument_type,
+ typename _Operation::result_type> {
+protected:
+ _Operation op;
+ typename _Operation::first_argument_type value;
+public:
+ binder1st(const _Operation& __x,
+ const typename _Operation::first_argument_type& __y)
+ : op(__x), value(__y) {}
+ typename _Operation::result_type
+ operator()(const typename _Operation::second_argument_type& __x) const {
+ return op(value, __x);
+ }
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ //109. Missing binders for non-const sequence elements
+ typename _Operation::result_type
+ operator()(typename _Operation::second_argument_type& __x) const {
+ return op(value, __x);
+ }
+#endif
+};
+
+/// One of the @link s20_3_6_binder binder functors@endlink.
+template <class _Operation, class _Tp>
+inline binder1st<_Operation>
+bind1st(const _Operation& __fn, const _Tp& __x)
+{
+ typedef typename _Operation::first_argument_type _Arg1_type;
+ return binder1st<_Operation>(__fn, _Arg1_type(__x));
+}
+
+/// One of the @link s20_3_6_binder binder functors@endlink.
+template <class _Operation>
+class binder2nd
+ : public unary_function<typename _Operation::first_argument_type,
+ typename _Operation::result_type> {
+protected:
+ _Operation op;
+ typename _Operation::second_argument_type value;
+public:
+ binder2nd(const _Operation& __x,
+ const typename _Operation::second_argument_type& __y)
+ : op(__x), value(__y) {}
+ typename _Operation::result_type
+ operator()(const typename _Operation::first_argument_type& __x) const {
+ return op(__x, value);
+ }
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ //109. Missing binders for non-const sequence elements
+ typename _Operation::result_type
+ operator()(typename _Operation::first_argument_type& __x) const {
+ return op(__x, value);
+ }
+#endif
+};
+
+/// One of the @link s20_3_6_binder binder functors@endlink.
+template <class _Operation, class _Tp>
+inline binder2nd<_Operation>
+bind2nd(const _Operation& __fn, const _Tp& __x)
+{
+ typedef typename _Operation::second_argument_type _Arg2_type;
+ return binder2nd<_Operation>(__fn, _Arg2_type(__x));
+}
+/** @} */
+
+// 20.3.7 adaptors pointers functions
+/** @defgroup s20_3_7_adaptors Adaptors for pointers to functions
+ * The advantage of function objects over pointers to functions is that
+ * the objects in the standard library declare nested typedefs describing
+ * their argument and result types with uniform names (e.g., @c result_type
+ * from the base classes @c unary_function and @c binary_function).
+ * Sometimes those typedefs are required, not just optional.
+ *
+ * Adaptors are provided to turn pointers to unary (single-argument) and
+ * binary (double-argument) functions into function objects. The long-winded
+ * functor @c pointer_to_unary_function is constructed with a function
+ * pointer @c f, and its @c operator() called with argument @c x returns
+ * @c f(x). The functor @c pointer_to_binary_function does the same thing,
+ * but with a double-argument @c f and @c operator().
+ *
+ * The function @c ptr_fun takes a pointer-to-function @c f and constructs
+ * an instance of the appropriate functor.
+ *
+ * @{
+*/
+/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink.
+template <class _Arg, class _Result>
+class pointer_to_unary_function : public unary_function<_Arg, _Result> {
+protected:
+ _Result (*_M_ptr)(_Arg);
+public:
+ pointer_to_unary_function() {}
+ explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {}
+ _Result operator()(_Arg __x) const { return _M_ptr(__x); }
+};
+
+/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink.
+template <class _Arg, class _Result>
+inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg))
+{
+ return pointer_to_unary_function<_Arg, _Result>(__x);
+}
+
+/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink.
+template <class _Arg1, class _Arg2, class _Result>
+class pointer_to_binary_function :
+ public binary_function<_Arg1,_Arg2,_Result> {
+protected:
+ _Result (*_M_ptr)(_Arg1, _Arg2);
+public:
+ pointer_to_binary_function() {}
+ explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2))
+ : _M_ptr(__x) {}
+ _Result operator()(_Arg1 __x, _Arg2 __y) const {
+ return _M_ptr(__x, __y);
+ }
+};
+
+/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink.
+template <class _Arg1, class _Arg2, class _Result>
+inline pointer_to_binary_function<_Arg1,_Arg2,_Result>
+ptr_fun(_Result (*__x)(_Arg1, _Arg2)) {
+ return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x);
+}
+/** @} */
+
+template <class _Tp>
+struct _Identity : public unary_function<_Tp,_Tp> {
+ _Tp& operator()(_Tp& __x) const { return __x; }
+ const _Tp& operator()(const _Tp& __x) const { return __x; }
+};
+
+template <class _Pair>
+struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> {
+ typename _Pair::first_type& operator()(_Pair& __x) const {
+ return __x.first;
+ }
+ const typename _Pair::first_type& operator()(const _Pair& __x) const {
+ return __x.first;
+ }
+};
+
+template <class _Pair>
+struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type>
+{
+ typename _Pair::second_type& operator()(_Pair& __x) const {
+ return __x.second;
+ }
+ const typename _Pair::second_type& operator()(const _Pair& __x) const {
+ return __x.second;
+ }
+};
+
+// 20.3.8 adaptors pointers members
+/** @defgroup s20_3_8_memadaptors Adaptors for pointers to members
+ * There are a total of 16 = 2^4 function objects in this family.
+ * (1) Member functions taking no arguments vs member functions taking
+ * one argument.
+ * (2) Call through pointer vs call through reference.
+ * (3) Member function with void return type vs member function with
+ * non-void return type.
+ * (4) Const vs non-const member function.
+ *
+ * Note that choice (3) is nothing more than a workaround: according
+ * to the draft, compilers should handle void and non-void the same way.
+ * This feature is not yet widely implemented, though. You can only use
+ * member functions returning void if your compiler supports partial
+ * specialization.
+ *
+ * All of this complexity is in the function objects themselves. You can
+ * ignore it by using the helper function mem_fun and mem_fun_ref,
+ * which create whichever type of adaptor is appropriate.
+ *
+ * @{
+*/
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp>
+class mem_fun_t : public unary_function<_Tp*,_Ret> {
+public:
+ explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {}
+ _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); }
+private:
+ _Ret (_Tp::*_M_f)();
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp>
+class const_mem_fun_t : public unary_function<const _Tp*,_Ret> {
+public:
+ explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {}
+ _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); }
+private:
+ _Ret (_Tp::*_M_f)() const;
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp>
+class mem_fun_ref_t : public unary_function<_Tp,_Ret> {
+public:
+ explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {}
+ _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); }
+private:
+ _Ret (_Tp::*_M_f)();
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp>
+class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> {
+public:
+ explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {}
+ _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); }
+private:
+ _Ret (_Tp::*_M_f)() const;
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp, class _Arg>
+class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> {
+public:
+ explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {}
+ _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); }
+private:
+ _Ret (_Tp::*_M_f)(_Arg);
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp, class _Arg>
+class const_mem_fun1_t : public binary_function<const _Tp*,_Arg,_Ret> {
+public:
+ explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {}
+ _Ret operator()(const _Tp* __p, _Arg __x) const
+ { return (__p->*_M_f)(__x); }
+private:
+ _Ret (_Tp::*_M_f)(_Arg) const;
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp, class _Arg>
+class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> {
+public:
+ explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {}
+ _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); }
+private:
+ _Ret (_Tp::*_M_f)(_Arg);
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Ret, class _Tp, class _Arg>
+class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> {
+public:
+ explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {}
+ _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); }
+private:
+ _Ret (_Tp::*_M_f)(_Arg) const;
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp>
+class mem_fun_t<void, _Tp> : public unary_function<_Tp*,void> {
+public:
+ explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {}
+ void operator()(_Tp* __p) const { (__p->*_M_f)(); }
+private:
+ void (_Tp::*_M_f)();
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp>
+class const_mem_fun_t<void, _Tp> : public unary_function<const _Tp*,void> {
+public:
+ explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {}
+ void operator()(const _Tp* __p) const { (__p->*_M_f)(); }
+private:
+ void (_Tp::*_M_f)() const;
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp>
+class mem_fun_ref_t<void, _Tp> : public unary_function<_Tp,void> {
+public:
+ explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {}
+ void operator()(_Tp& __r) const { (__r.*_M_f)(); }
+private:
+ void (_Tp::*_M_f)();
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp>
+class const_mem_fun_ref_t<void, _Tp> : public unary_function<_Tp,void> {
+public:
+ explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {}
+ void operator()(const _Tp& __r) const { (__r.*_M_f)(); }
+private:
+ void (_Tp::*_M_f)() const;
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp, class _Arg>
+class mem_fun1_t<void, _Tp, _Arg> : public binary_function<_Tp*,_Arg,void> {
+public:
+ explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {}
+ void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); }
+private:
+ void (_Tp::*_M_f)(_Arg);
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp, class _Arg>
+class const_mem_fun1_t<void, _Tp, _Arg>
+ : public binary_function<const _Tp*,_Arg,void> {
+public:
+ explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {}
+ void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); }
+private:
+ void (_Tp::*_M_f)(_Arg) const;
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp, class _Arg>
+class mem_fun1_ref_t<void, _Tp, _Arg>
+ : public binary_function<_Tp,_Arg,void> {
+public:
+ explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {}
+ void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); }
+private:
+ void (_Tp::*_M_f)(_Arg);
+};
+
+/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
+template <class _Tp, class _Arg>
+class const_mem_fun1_ref_t<void, _Tp, _Arg>
+ : public binary_function<_Tp,_Arg,void> {
+public:
+ explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {}
+ void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); }
+private:
+ void (_Tp::*_M_f)(_Arg) const;
+};
+
+
+// Mem_fun adaptor helper functions. There are only two:
+// mem_fun and mem_fun_ref.
+
+template <class _Ret, class _Tp>
+inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)())
+ { return mem_fun_t<_Ret,_Tp>(__f); }
+
+template <class _Ret, class _Tp>
+inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const)
+ { return const_mem_fun_t<_Ret,_Tp>(__f); }
+
+template <class _Ret, class _Tp>
+inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)())
+ { return mem_fun_ref_t<_Ret,_Tp>(__f); }
+
+template <class _Ret, class _Tp>
+inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const)
+ { return const_mem_fun_ref_t<_Ret,_Tp>(__f); }
+
+template <class _Ret, class _Tp, class _Arg>
+inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg))
+ { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); }
+
+template <class _Ret, class _Tp, class _Arg>
+inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const)
+ { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); }
+
+template <class _Ret, class _Tp, class _Arg>
+inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg))
+ { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); }
+
+template <class _Ret, class _Tp, class _Arg>
+inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg>
+mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const)
+ { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); }
+
+/** @} */
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_FUNCTION_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_heap.h b/contrib/libstdc++/include/bits/stl_heap.h
new file mode 100644
index 0000000000000..c19195aad39a4
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_heap.h
@@ -0,0 +1,308 @@
+// Heap implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_heap.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STL_HEAP_H
+#define _CPP_BITS_STL_HEAP_H 1
+
+namespace std
+{
+
+ // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
+
+ template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
+ void
+ __push_heap(_RandomAccessIterator __first,
+ _Distance __holeIndex, _Distance __topIndex, _Tp __value)
+ {
+ _Distance __parent = (__holeIndex - 1) / 2;
+ while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
+ *(__first + __holeIndex) = *(__first + __parent);
+ __holeIndex = __parent;
+ __parent = (__holeIndex - 1) / 2;
+ }
+ *(__first + __holeIndex) = __value;
+ }
+
+ template<typename _RandomAccessIterator>
+ inline void
+ push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+ _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0),
+ _ValueType(*(__last - 1)));
+ }
+
+ template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
+ typename _Compare>
+ void
+ __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
+ _Distance __topIndex, _Tp __value, _Compare __comp)
+ {
+ _Distance __parent = (__holeIndex - 1) / 2;
+ while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) {
+ *(__first + __holeIndex) = *(__first + __parent);
+ __holeIndex = __parent;
+ __parent = (__holeIndex - 1) / 2;
+ }
+ *(__first + __holeIndex) = __value;
+ }
+
+ template<typename _RandomAccessIterator, typename _Compare>
+ inline void
+ push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+ _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+
+ __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0),
+ _ValueType(*(__last - 1)), __comp);
+ }
+
+ template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
+ void
+ __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
+ _Distance __len, _Tp __value)
+ {
+ _Distance __topIndex = __holeIndex;
+ _Distance __secondChild = 2 * __holeIndex + 2;
+ while (__secondChild < __len) {
+ if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
+ __secondChild--;
+ *(__first + __holeIndex) = *(__first + __secondChild);
+ __holeIndex = __secondChild;
+ __secondChild = 2 * (__secondChild + 1);
+ }
+ if (__secondChild == __len) {
+ *(__first + __holeIndex) = *(__first + (__secondChild - 1));
+ __holeIndex = __secondChild - 1;
+ }
+ __push_heap(__first, __holeIndex, __topIndex, __value);
+ }
+
+ template<typename _RandomAccessIterator, typename _Tp>
+ inline void
+ __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _RandomAccessIterator __result, _Tp __value)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance;
+ *__result = *__first;
+ __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
+ }
+
+ template<typename _RandomAccessIterator>
+ inline void
+ pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)));
+ }
+
+ template<typename _RandomAccessIterator, typename _Distance,
+ typename _Tp, typename _Compare>
+ void
+ __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
+ _Distance __len, _Tp __value, _Compare __comp)
+ {
+ _Distance __topIndex = __holeIndex;
+ _Distance __secondChild = 2 * __holeIndex + 2;
+ while (__secondChild < __len) {
+ if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
+ __secondChild--;
+ *(__first + __holeIndex) = *(__first + __secondChild);
+ __holeIndex = __secondChild;
+ __secondChild = 2 * (__secondChild + 1);
+ }
+ if (__secondChild == __len) {
+ *(__first + __holeIndex) = *(__first + (__secondChild - 1));
+ __holeIndex = __secondChild - 1;
+ }
+ __push_heap(__first, __holeIndex, __topIndex, __value, __comp);
+ }
+
+ template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
+ inline void
+ __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _RandomAccessIterator __result, _Tp __value, _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance;
+ *__result = *__first;
+ __adjust_heap(__first, _Distance(0), _Distance(__last - __first),
+ __value, __comp);
+ }
+
+ template<typename _RandomAccessIterator, typename _Compare>
+ inline void
+ pop_heap(_RandomAccessIterator __first,
+ _RandomAccessIterator __last, _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType;
+ __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)), __comp);
+ }
+
+ template<typename _RandomAccessIterator>
+ void
+ make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+ _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+ __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
+
+ if (__last - __first < 2) return;
+ _DistanceType __len = __last - __first;
+ _DistanceType __parent = (__len - 2)/2;
+
+ while (true) {
+ __adjust_heap(__first, __parent, __len, _ValueType(*(__first + __parent)));
+ if (__parent == 0) return;
+ __parent--;
+ }
+ }
+
+ template<typename _RandomAccessIterator, typename _Compare>
+ inline void
+ make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+ _DistanceType;
+
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+
+ if (__last - __first < 2) return;
+ _DistanceType __len = __last - __first;
+ _DistanceType __parent = (__len - 2)/2;
+
+ while (true) {
+ __adjust_heap(__first, __parent, __len,
+ _ValueType(*(__first + __parent)), __comp);
+ if (__parent == 0) return;
+ __parent--;
+ }
+ }
+
+ template<typename _RandomAccessIterator>
+ void
+ sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+ __glibcpp_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
+
+ while (__last - __first > 1)
+ pop_heap(__first, __last--);
+ }
+
+ template<typename _RandomAccessIterator, typename _Compare>
+ void
+ sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _Compare __comp)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+
+ while (__last - __first > 1)
+ pop_heap(__first, __last--, __comp);
+ }
+
+} // namespace std
+
+#endif /* _CPP_BITS_STL_HEAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_iterator.h b/contrib/libstdc++/include/bits/stl_iterator.h
new file mode 100644
index 0000000000000..d8a6d8ca374ae
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_iterator.h
@@ -0,0 +1,733 @@
+// Iterators -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996-1998
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_iterator.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ *
+ * This file implements reverse_iterator, back_insert_iterator,
+ * front_insert_iterator, insert_iterator, __normal_iterator, and their
+ * supporting functions and overloaded operators.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_ITERATOR_H
+#define __GLIBCPP_INTERNAL_ITERATOR_H
+
+namespace std
+{
+ // 24.4.1 Reverse iterators
+ /**
+ * "Bidirectional and random access iterators have corresponding reverse
+ * %iterator adaptors that iterate through the data structure in the
+ * opposite direction. They have the same signatures as the corresponding
+ * iterators. The fundamental relation between a reverse %iterator and its
+ * corresponding %iterator @c i is established by the identity:
+ * @code
+ * &*(reverse_iterator(i)) == &*(i - 1)
+ * @endcode
+ *
+ * This mapping is dictated by the fact that while there is always a
+ * pointer past the end of an array, there might not be a valid pointer
+ * before the beginning of an array." [24.4.1]/1,2
+ *
+ * Reverse iterators can be tricky and surprising at first. Their
+ * semantics make sense, however, and the trickiness is a side effect of
+ * the requirement that the iterators must be safe.
+ */
+ template<typename _Iterator>
+ class reverse_iterator
+ : public iterator<typename iterator_traits<_Iterator>::iterator_category,
+ typename iterator_traits<_Iterator>::value_type,
+ typename iterator_traits<_Iterator>::difference_type,
+ typename iterator_traits<_Iterator>::pointer,
+ typename iterator_traits<_Iterator>::reference>
+ {
+ protected:
+ _Iterator current;
+
+ public:
+ typedef _Iterator iterator_type;
+ typedef typename iterator_traits<_Iterator>::difference_type
+ difference_type;
+ typedef typename iterator_traits<_Iterator>::reference reference;
+ typedef typename iterator_traits<_Iterator>::pointer pointer;
+
+ public:
+ /**
+ * The default constructor gives an undefined state to this %iterator.
+ */
+ reverse_iterator() { }
+
+ /**
+ * This %iterator will move in the opposite direction that @p x does.
+ */
+ explicit
+ reverse_iterator(iterator_type __x) : current(__x) { }
+
+ /**
+ * The copy constructor is normal.
+ */
+ reverse_iterator(const reverse_iterator& __x)
+ : current(__x.current) { }
+
+ /**
+ * A reverse_iterator across other types can be copied in the normal
+ * fashion.
+ */
+ template<typename _Iter>
+ reverse_iterator(const reverse_iterator<_Iter>& __x)
+ : current(__x.base()) { }
+
+ /**
+ * @return @c current, the %iterator used for underlying work.
+ */
+ iterator_type
+ base() const { return current; }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reference
+ operator*() const
+ {
+ _Iterator __tmp = current;
+ return *--__tmp;
+ }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ pointer
+ operator->() const { return &(operator*()); }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator&
+ operator++()
+ {
+ --current;
+ return *this;
+ }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator
+ operator++(int)
+ {
+ reverse_iterator __tmp = *this;
+ --current;
+ return __tmp;
+ }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator&
+ operator--()
+ {
+ ++current;
+ return *this;
+ }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator operator--(int)
+ {
+ reverse_iterator __tmp = *this;
+ ++current;
+ return __tmp;
+ }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator
+ operator+(difference_type __n) const
+ { return reverse_iterator(current - __n); }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator&
+ operator+=(difference_type __n)
+ {
+ current -= __n;
+ return *this;
+ }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator
+ operator-(difference_type __n) const
+ { return reverse_iterator(current + __n); }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reverse_iterator&
+ operator-=(difference_type __n)
+ {
+ current += __n;
+ return *this;
+ }
+
+ /**
+ * @return TODO
+ *
+ * @doctodo
+ */
+ reference
+ operator[](difference_type __n) const { return *(*this + __n); }
+ };
+
+ //@{
+ /**
+ * @param x A %reverse_iterator.
+ * @param y A %reverse_iterator.
+ * @return A simple bool.
+ *
+ * Reverse iterators forward many operations to their underlying base()
+ * iterators. Others are implemented in terms of one another.
+ *
+ */
+ template<typename _Iterator>
+ inline bool
+ operator==(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return __x.base() == __y.base(); }
+
+ template<typename _Iterator>
+ inline bool
+ operator<(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return __y.base() < __x.base(); }
+
+ template<typename _Iterator>
+ inline bool
+ operator!=(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return !(__x == __y); }
+
+ template<typename _Iterator>
+ inline bool
+ operator>(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return __y < __x; }
+
+ template<typename _Iterator>
+ inline bool
+ operator<=(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return !(__y < __x); }
+
+ template<typename _Iterator>
+ inline bool
+ operator>=(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return !(__x < __y); }
+
+ template<typename _Iterator>
+ inline typename reverse_iterator<_Iterator>::difference_type
+ operator-(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return __y.base() - __x.base(); }
+
+ template<typename _Iterator>
+ inline reverse_iterator<_Iterator>
+ operator+(typename reverse_iterator<_Iterator>::difference_type __n,
+ const reverse_iterator<_Iterator>& __x)
+ { return reverse_iterator<_Iterator>(__x.base() - __n); }
+ //@}
+
+ // 24.4.2.2.1 back_insert_iterator
+ /**
+ * These are output iterators, constructed from a container-of-T.
+ * Assigning a T to the iterator appends it to the container using
+ * push_back.
+ *
+ * Tip: Using the back_inserter function to create these iterators can
+ * save typing.
+ */
+ template<typename _Container>
+ class back_insert_iterator
+ : public iterator<output_iterator_tag, void, void, void, void>
+ {
+ protected:
+ _Container* container;
+
+ public:
+ /// A nested typedef for the type of whatever container you used.
+ typedef _Container container_type;
+
+ /// The only way to create this %iterator is with a container.
+ explicit
+ back_insert_iterator(_Container& __x) : container(&__x) { }
+
+ /**
+ * @param value An instance of whatever type
+ * container_type::const_reference is; presumably a
+ * reference-to-const T for container<T>.
+ * @return This %iterator, for chained operations.
+ *
+ * This kind of %iterator doesn't really have a "position" in the
+ * container (you can think of the position as being permanently at
+ * the end, if you like). Assigning a value to the %iterator will
+ * always append the value to the end of the container.
+ */
+ back_insert_iterator&
+ operator=(typename _Container::const_reference __value)
+ {
+ container->push_back(__value);
+ return *this;
+ }
+
+ /// Simply returns *this.
+ back_insert_iterator&
+ operator*() { return *this; }
+
+ /// Simply returns *this. (This %iterator does not "move".)
+ back_insert_iterator&
+ operator++() { return *this; }
+
+ /// Simply returns *this. (This %iterator does not "move".)
+ back_insert_iterator
+ operator++(int) { return *this; }
+ };
+
+ /**
+ * @param x A container of arbitrary type.
+ * @return An instance of back_insert_iterator working on @p x.
+ *
+ * This wrapper function helps in creating back_insert_iterator instances.
+ * Typing the name of the %iterator requires knowing the precise full
+ * type of the container, which can be tedious and impedes generic
+ * programming. Using this function lets you take advantage of automatic
+ * template parameter deduction, making the compiler match the correct
+ * types for you.
+ */
+ template<typename _Container>
+ inline back_insert_iterator<_Container>
+ back_inserter(_Container& __x)
+ { return back_insert_iterator<_Container>(__x); }
+
+ /**
+ * These are output iterators, constructed from a container-of-T.
+ * Assigning a T to the iterator prepends it to the container using
+ * push_front.
+ *
+ * Tip: Using the front_inserter function to create these iterators can
+ * save typing.
+ */
+ template<typename _Container>
+ class front_insert_iterator
+ : public iterator<output_iterator_tag, void, void, void, void>
+ {
+ protected:
+ _Container* container;
+
+ public:
+ /// A nested typedef for the type of whatever container you used.
+ typedef _Container container_type;
+
+ /// The only way to create this %iterator is with a container.
+ explicit front_insert_iterator(_Container& __x) : container(&__x) { }
+
+ /**
+ * @param value An instance of whatever type
+ * container_type::const_reference is; presumably a
+ * reference-to-const T for container<T>.
+ * @return This %iterator, for chained operations.
+ *
+ * This kind of %iterator doesn't really have a "position" in the
+ * container (you can think of the position as being permanently at
+ * the front, if you like). Assigning a value to the %iterator will
+ * always prepend the value to the front of the container.
+ */
+ front_insert_iterator&
+ operator=(typename _Container::const_reference __value)
+ {
+ container->push_front(__value);
+ return *this;
+ }
+
+ /// Simply returns *this.
+ front_insert_iterator&
+ operator*() { return *this; }
+
+ /// Simply returns *this. (This %iterator does not "move".)
+ front_insert_iterator&
+ operator++() { return *this; }
+
+ /// Simply returns *this. (This %iterator does not "move".)
+ front_insert_iterator
+ operator++(int) { return *this; }
+ };
+
+ /**
+ * @param x A container of arbitrary type.
+ * @return An instance of front_insert_iterator working on @p x.
+ *
+ * This wrapper function helps in creating front_insert_iterator instances.
+ * Typing the name of the %iterator requires knowing the precise full
+ * type of the container, which can be tedious and impedes generic
+ * programming. Using this function lets you take advantage of automatic
+ * template parameter deduction, making the compiler match the correct
+ * types for you.
+ */
+ template<typename _Container>
+ inline front_insert_iterator<_Container>
+ front_inserter(_Container& __x)
+ { return front_insert_iterator<_Container>(__x); }
+
+ /**
+ * These are output iterators, constructed from a container-of-T.
+ * Assigning a T to the iterator inserts it in the container at the
+ * %iterator's position, rather than overwriting the value at that
+ * position.
+ *
+ * (Sequences will actually insert a @e copy of the value before the
+ * %iterator's position.)
+ *
+ * Tip: Using the inserter function to create these iterators can
+ * save typing.
+ */
+ template<typename _Container>
+ class insert_iterator
+ : public iterator<output_iterator_tag, void, void, void, void>
+ {
+ protected:
+ _Container* container;
+ typename _Container::iterator iter;
+
+ public:
+ /// A nested typedef for the type of whatever container you used.
+ typedef _Container container_type;
+
+ /**
+ * The only way to create this %iterator is with a container and an
+ * initial position (a normal %iterator into the container).
+ */
+ insert_iterator(_Container& __x, typename _Container::iterator __i)
+ : container(&__x), iter(__i) {}
+
+ /**
+ * @param value An instance of whatever type
+ * container_type::const_reference is; presumably a
+ * reference-to-const T for container<T>.
+ * @return This %iterator, for chained operations.
+ *
+ * This kind of %iterator maintains its own position in the
+ * container. Assigning a value to the %iterator will insert the
+ * value into the container at the place before the %iterator.
+ *
+ * The position is maintained such that subsequent assignments will
+ * insert values immediately after one another. For example,
+ * @code
+ * // vector v contains A and Z
+ *
+ * insert_iterator i (v, ++v.begin());
+ * i = 1;
+ * i = 2;
+ * i = 3;
+ *
+ * // vector v contains A, 1, 2, 3, and Z
+ * @endcode
+ */
+ insert_iterator&
+ operator=(const typename _Container::const_reference __value)
+ {
+ iter = container->insert(iter, __value);
+ ++iter;
+ return *this;
+ }
+
+ /// Simply returns *this.
+ insert_iterator&
+ operator*() { return *this; }
+
+ /// Simply returns *this. (This %iterator does not "move".)
+ insert_iterator&
+ operator++() { return *this; }
+
+ /// Simply returns *this. (This %iterator does not "move".)
+ insert_iterator&
+ operator++(int) { return *this; }
+ };
+
+ /**
+ * @param x A container of arbitrary type.
+ * @return An instance of insert_iterator working on @p x.
+ *
+ * This wrapper function helps in creating insert_iterator instances.
+ * Typing the name of the %iterator requires knowing the precise full
+ * type of the container, which can be tedious and impedes generic
+ * programming. Using this function lets you take advantage of automatic
+ * template parameter deduction, making the compiler match the correct
+ * types for you.
+ */
+ template<typename _Container, typename _Iterator>
+ inline insert_iterator<_Container>
+ inserter(_Container& __x, _Iterator __i)
+ {
+ 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
+ // not a class, e.g. a pointer, into an iterator that is a class.
+ // 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,
+ typename iterator_traits<_Iterator>::value_type,
+ typename iterator_traits<_Iterator>::difference_type,
+ typename iterator_traits<_Iterator>::pointer,
+ typename iterator_traits<_Iterator>::reference>
+ {
+ protected:
+ _Iterator _M_current;
+
+ public:
+ typedef typename iterator_traits<_Iterator>::difference_type
+ difference_type;
+ typedef typename iterator_traits<_Iterator>::reference reference;
+ typedef typename iterator_traits<_Iterator>::pointer pointer;
+
+ __normal_iterator() : _M_current(_Iterator()) { }
+
+ explicit
+ __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
+
+ // Allow iterator to const_iterator conversion
+ template<typename _Iter>
+ inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
+ : _M_current(__i.base()) { }
+
+ // Forward iterator requirements
+ reference
+ operator*() const { return *_M_current; }
+
+ pointer
+ operator->() const { return _M_current; }
+
+ __normal_iterator&
+ operator++() { ++_M_current; return *this; }
+
+ __normal_iterator
+ operator++(int) { return __normal_iterator(_M_current++); }
+
+ // Bidirectional iterator requirements
+ __normal_iterator&
+ operator--() { --_M_current; return *this; }
+
+ __normal_iterator
+ operator--(int) { return __normal_iterator(_M_current--); }
+
+ // Random access iterator requirements
+ reference
+ operator[](const difference_type& __n) const
+ { return _M_current[__n]; }
+
+ __normal_iterator&
+ operator+=(const difference_type& __n)
+ { _M_current += __n; return *this; }
+
+ __normal_iterator
+ operator+(const difference_type& __n) const
+ { return __normal_iterator(_M_current + __n); }
+
+ __normal_iterator&
+ operator-=(const difference_type& __n)
+ { _M_current -= __n; return *this; }
+
+ __normal_iterator
+ 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
+ operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ 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.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>
+ inline bool
+ operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ 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.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.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.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 _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 __gnu_cxx
+
+#endif
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_iterator_base_funcs.h b/contrib/libstdc++/include/bits/stl_iterator_base_funcs.h
new file mode 100644
index 0000000000000..8389f5e7d03a7
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_iterator_base_funcs.h
@@ -0,0 +1,179 @@
+// Functions used by iterators -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996-1998
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_iterator_base_funcs.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ *
+ * This file contains all of the general iterator-related utility
+ * functions, such as distance() and advance().
+ */
+
+#ifndef __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H
+#define __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H
+
+#pragma GCC system_header
+#include <bits/concept_check.h>
+
+// Since this entire file is within namespace std, there's no reason to
+// waste two spaces along the left column. Thus the leading indentation is
+// slightly violated from here on.
+namespace std
+{
+template<typename _InputIterator>
+ inline typename iterator_traits<_InputIterator>::difference_type
+ __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+
+ typename iterator_traits<_InputIterator>::difference_type __n = 0;
+ while (__first != __last) {
+ ++__first; ++__n;
+ }
+ return __n;
+ }
+
+template<typename _RandomAccessIterator>
+ inline typename iterator_traits<_RandomAccessIterator>::difference_type
+ __distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ random_access_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
+ return __last - __first;
+ }
+
+/**
+ * @brief A generalization of pointer arithmetic.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @return The distance between them.
+ *
+ * Returns @c n such that first + n == last. This requires that @p last
+ * must be reachable from @p first. Note that @c n may be negative.
+ *
+ * For random access iterators, this uses their @c + and @c - operations
+ * and are constant time. For other %iterator classes they are linear time.
+*/
+template<typename _InputIterator>
+ inline typename iterator_traits<_InputIterator>::difference_type
+ distance(_InputIterator __first, _InputIterator __last)
+ {
+ // concept requirements -- taken care of in __distance
+ return __distance(__first, __last, __iterator_category(__first));
+ }
+
+template<typename _InputIter, typename _Distance>
+ inline void
+ __advance(_InputIter& __i, _Distance __n, input_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
+ while (__n--) ++__i;
+ }
+
+template<typename _BidirectionalIterator, typename _Distance>
+ inline void
+ __advance(_BidirectionalIterator& __i, _Distance __n,
+ bidirectional_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>)
+
+ if (__n > 0)
+ while (__n--) ++__i;
+ else
+ while (__n++) --__i;
+ }
+
+template<typename _RandomAccessIterator, typename _Distance>
+ inline void
+ __advance(_RandomAccessIterator& __i, _Distance __n,
+ random_access_iterator_tag)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
+ __i += __n;
+ }
+
+/**
+ * @brief A generalization of pointer arithmetic.
+ * @param i An input iterator.
+ * @param n The "delta" by which to change @p i.
+ * @return Nothing.
+ *
+ * This increments @p i by @p n. For bidirectional and random access
+ * iterators, @p n may be negative, in which case @p i is decremented.
+ *
+ * For random access iterators, this uses their @c + and @c - operations
+ * and are constant time. For other %iterator classes they are linear time.
+*/
+template<typename _InputIterator, typename _Distance>
+ inline void
+ advance(_InputIterator& __i, _Distance __n)
+ {
+ // concept requirements -- taken care of in __advance
+ __advance(__i, __n, __iterator_category(__i));
+ }
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H */
+
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_iterator_base_types.h b/contrib/libstdc++/include/bits/stl_iterator_base_types.h
new file mode 100644
index 0000000000000..5dff8fc3f447e
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_iterator_base_types.h
@@ -0,0 +1,162 @@
+// Types used in iterator implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996-1998
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_iterator_base_types.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ *
+ * This file contains all of the general iterator-related utility types,
+ * such as iterator_traits and struct iterator.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_ITERATOR_BASE_TYPES_H
+#define __GLIBCPP_INTERNAL_ITERATOR_BASE_TYPES_H
+
+#pragma GCC system_header
+
+namespace std
+{
+ /**
+ * @defgroup iterator_tags Iterator Tags
+ * These are empty types, used to distinguish different iterators. The
+ * distinction is not made by what they contain, but simply by what they
+ * are. Different underlying algorithms can then be used based on the
+ * different operations supporetd by different iterator types.
+ * @{
+ */
+ /// Marking input iterators.
+ struct input_iterator_tag {};
+ /// Marking output iterators.
+ struct output_iterator_tag {};
+ /// Forward iterators support a superset of input iterator operations.
+ struct forward_iterator_tag : public input_iterator_tag {};
+ /// Bidirectional iterators support a superset of forward iterator operations.
+ struct bidirectional_iterator_tag : public forward_iterator_tag {};
+ /// Random-access iterators support a superset of bidirectional iterator operations.
+ struct random_access_iterator_tag : public bidirectional_iterator_tag {};
+ //@}
+
+
+ /**
+ * This class does nothing but define nested typedefs. %Iterator classes
+ * can inherit from this class to save some work. The typedefs are then
+ * used in specializations and overloading.
+ *
+ * In particular, there are no default implementations of requirements
+ * such as @c operator++ and the like. (How could there be?)
+ */
+ template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t,
+ typename _Pointer = _Tp*, typename _Reference = _Tp&>
+ struct iterator {
+ /// One of the @link iterator_tags tag types@endlink.
+ typedef _Category iterator_category;
+ /// The type "pointed to" by the iterator.
+ typedef _Tp value_type;
+ /// Distance between iterators is represented as this type.
+ typedef _Distance difference_type;
+ /// This type represents a pointer-to-value_type.
+ typedef _Pointer pointer;
+ /// This type represents a reference-to-value_type.
+ typedef _Reference reference;
+ };
+
+ /**
+ * This class does nothing but define nested typedefs. The general
+ * version simply "forwards" the nested typedefs from the Iterator
+ * argument. Specialized versions for pointers and pointers-to-const
+ * provide tighter, more correct semantics.
+ */
+ template<typename _Iterator>
+ struct iterator_traits {
+ typedef typename _Iterator::iterator_category iterator_category;
+ typedef typename _Iterator::value_type value_type;
+ typedef typename _Iterator::difference_type difference_type;
+ typedef typename _Iterator::pointer pointer;
+ typedef typename _Iterator::reference reference;
+ };
+
+ template<typename _Tp>
+ struct iterator_traits<_Tp*> {
+ typedef random_access_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp* pointer;
+ typedef _Tp& reference;
+ };
+
+ template<typename _Tp>
+ struct iterator_traits<const _Tp*> {
+ typedef random_access_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const _Tp* pointer;
+ typedef const _Tp& reference;
+ };
+
+ /**
+ * @if maint
+ * This function is not a part of the C++ standard but is syntactic
+ * sugar for internal library use only.
+ * @endif
+ */
+ template<typename _Iter>
+ inline typename iterator_traits<_Iter>::iterator_category
+ __iterator_category(const _Iter&)
+ { return typename iterator_traits<_Iter>::iterator_category(); }
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_ITERATOR_BASE_TYPES_H */
+
diff --git a/contrib/libstdc++/include/bits/stl_list.h b/contrib/libstdc++/include/bits/stl_list.h
new file mode 100644
index 0000000000000..3d470b1f25f0d
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_list.h
@@ -0,0 +1,989 @@
+// List implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_list.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_LIST_H
+#define __GLIBCPP_INTERNAL_LIST_H
+
+#include <bits/concept_check.h>
+
+namespace std
+{
+
+ struct _List_node_base
+ {
+ _List_node_base* _M_next;
+ _List_node_base* _M_prev;
+ };
+
+ template<typename _Tp>
+ struct _List_node : public _List_node_base
+ {
+ _Tp _M_data;
+ };
+
+ struct _List_iterator_base
+ {
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef bidirectional_iterator_tag iterator_category;
+
+ _List_node_base* _M_node;
+
+ _List_iterator_base(_List_node_base* __x)
+ : _M_node(__x)
+ { }
+
+ _List_iterator_base()
+ { }
+
+ void
+ _M_incr()
+ { _M_node = _M_node->_M_next; }
+
+ void
+ _M_decr()
+ { _M_node = _M_node->_M_prev; }
+
+ bool
+ operator==(const _List_iterator_base& __x) const
+ { return _M_node == __x._M_node; }
+
+ bool
+ operator!=(const _List_iterator_base& __x) const
+ { return _M_node != __x._M_node; }
+ };
+
+ template<typename _Tp, typename _Ref, typename _Ptr>
+ struct _List_iterator : public _List_iterator_base
+ {
+ typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
+ typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
+ typedef _List_iterator<_Tp,_Ref,_Ptr> _Self;
+
+ typedef _Tp value_type;
+ typedef _Ptr pointer;
+ typedef _Ref reference;
+ typedef _List_node<_Tp> _Node;
+
+ _List_iterator(_Node* __x)
+ : _List_iterator_base(__x)
+ { }
+
+ _List_iterator()
+ { }
+
+ _List_iterator(const iterator& __x)
+ : _List_iterator_base(__x._M_node)
+ { }
+
+ reference
+ operator*() const
+ { return ((_Node*) _M_node)->_M_data; }
+
+ pointer
+ operator->() const
+ { return &(operator*()); }
+
+ _Self&
+ operator++()
+ {
+ this->_M_incr();
+ return *this;
+ }
+
+ _Self
+ operator++(int)
+ {
+ _Self __tmp = *this;
+ this->_M_incr();
+ return __tmp;
+ }
+
+ _Self&
+ operator--()
+ {
+ this->_M_decr();
+ return *this;
+ }
+
+ _Self
+ operator--(int)
+ {
+ _Self __tmp = *this;
+ this->_M_decr();
+ return __tmp;
+ }
+ };
+
+
+ // Base class that encapsulates details of allocators. Three cases:
+ // an ordinary standard-conforming allocator, a standard-conforming
+ // allocator with no non-static data, and an SGI-style allocator.
+ // This complexity is necessary only because we're worrying about backward
+ // compatibility and because we want to avoid wasting storage on an
+ // allocator instance if it isn't necessary.
+
+
+ // Base for general standard-conforming allocators.
+ template<typename _Tp, typename _Allocator, bool _IsStatic>
+ class _List_alloc_base
+ {
+ public:
+ typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+ allocator_type;
+
+ allocator_type
+ get_allocator() const
+ { return _Node_allocator; }
+
+ _List_alloc_base(const allocator_type& __a)
+ : _Node_allocator(__a)
+ { }
+
+ protected:
+ _List_node<_Tp>*
+ _M_get_node()
+ { return _Node_allocator.allocate(1); }
+
+ void
+ _M_put_node(_List_node<_Tp>* __p)
+ { _Node_allocator.deallocate(__p, 1); }
+
+ protected:
+ typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
+ _Node_allocator;
+
+ _List_node<_Tp>* _M_node;
+ };
+
+ // Specialization for instanceless allocators.
+
+ template<typename _Tp, typename _Allocator>
+ class _List_alloc_base<_Tp, _Allocator, true>
+ {
+ public:
+ typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+ allocator_type;
+
+ allocator_type
+ get_allocator() const
+ { return allocator_type(); }
+
+ _List_alloc_base(const allocator_type&)
+ { }
+
+ protected:
+ typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
+ _Alloc_type;
+
+ _List_node<_Tp>*
+ _M_get_node()
+ { return _Alloc_type::allocate(1); }
+
+ void
+ _M_put_node(_List_node<_Tp>* __p)
+ { _Alloc_type::deallocate(__p, 1); }
+
+ protected:
+ _List_node<_Tp>* _M_node;
+ };
+
+ template<typename _Tp, typename _Alloc>
+ class _List_base
+ : public _List_alloc_base<_Tp, _Alloc,
+ _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+ {
+ public:
+ typedef _List_alloc_base<_Tp, _Alloc,
+ _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+ _Base;
+ typedef typename _Base::allocator_type allocator_type;
+
+ _List_base(const allocator_type& __a)
+ : _Base(__a)
+ {
+ _M_node = _M_get_node();
+ _M_node->_M_next = _M_node;
+ _M_node->_M_prev = _M_node;
+ }
+
+ ~_List_base()
+ {
+ clear();
+ _M_put_node(_M_node);
+ }
+
+ void clear();
+ };
+
+ /**
+ * @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>
+ {
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+
+ typedef _List_base<_Tp, _Alloc> _Base;
+ protected:
+ typedef void* _Void_pointer;
+
+ public:
+ typedef _Tp value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef _List_node<_Tp> _Node;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ typedef typename _Base::allocator_type allocator_type;
+
+ typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
+ typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
+
+ typedef reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef reverse_iterator<iterator> reverse_iterator;
+
+ protected:
+ using _Base::_M_node;
+ using _Base::_M_put_node;
+ using _Base::_M_get_node;
+
+ protected:
+ _Node*
+ _M_create_node(const _Tp& __x)
+ {
+ _Node* __p = _M_get_node();
+ try {
+ _Construct(&__p->_M_data, __x);
+ }
+ catch(...)
+ {
+ _M_put_node(__p);
+ __throw_exception_again;
+ }
+ return __p;
+ }
+
+ _Node*
+ _M_create_node()
+ {
+ _Node* __p = _M_get_node();
+ try {
+ _Construct(&__p->_M_data);
+ }
+ catch(...)
+ {
+ _M_put_node(__p);
+ __throw_exception_again;
+ }
+ return __p;
+ }
+
+ public:
+ allocator_type
+ get_allocator() const
+ { return _Base::get_allocator(); }
+
+ explicit
+ list(const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ { }
+
+ iterator
+ begin()
+ { return static_cast<_Node*>(_M_node->_M_next); }
+
+ const_iterator
+ begin() const
+ { return static_cast<_Node*>(_M_node->_M_next); }
+
+ iterator
+ end()
+ { return _M_node; }
+
+ const_iterator
+ end() const
+ { return _M_node; }
+
+ reverse_iterator
+ rbegin()
+ { return reverse_iterator(end()); }
+
+ const_reverse_iterator
+ rbegin() const
+ { return const_reverse_iterator(end()); }
+
+ reverse_iterator
+ rend()
+ { return reverse_iterator(begin()); }
+
+ const_reverse_iterator
+ rend() const
+ { return const_reverse_iterator(begin()); }
+
+ bool
+ empty() const
+ { return _M_node->_M_next == _M_node; }
+
+ size_type
+ size() const
+ { return distance(begin(), end()); }
+
+ size_type
+ max_size() const
+ { return size_type(-1); }
+
+ reference
+ front()
+ { return *begin(); }
+
+ const_reference
+ front() const
+ { return *begin(); }
+
+ reference
+ back()
+ { return *(--end()); }
+
+ const_reference
+ back() const
+ { return *(--end()); }
+
+ void
+ swap(list<_Tp, _Alloc>& __x)
+ { std::swap(_M_node, __x._M_node); }
+
+ iterator
+ insert(iterator __position, const _Tp& __x)
+ {
+ _Node* __tmp = _M_create_node(__x);
+ __tmp->_M_next = __position._M_node;
+ __tmp->_M_prev = __position._M_node->_M_prev;
+ __position._M_node->_M_prev->_M_next = __tmp;
+ __position._M_node->_M_prev = __tmp;
+ return __tmp;
+ }
+
+ iterator
+ insert(iterator __position)
+ { return insert(__position, _Tp()); }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+ template<typename _Integer>
+ void
+ _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type)
+ { _M_fill_insert(__pos, (size_type) __n, (_Tp) __x); }
+
+ template<typename _InputIterator>
+ void
+ _M_insert_dispatch(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ __false_type);
+
+ template<typename _InputIterator>
+ void
+ insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_insert_dispatch(__pos, __first, __last, _Integral());
+ }
+
+ void
+ insert(iterator __pos, size_type __n, const _Tp& __x)
+ { _M_fill_insert(__pos, __n, __x); }
+
+ void
+ _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x);
+
+ void
+ push_front(const _Tp& __x)
+ { insert(begin(), __x); }
+
+ void
+ push_front()
+ { insert(begin()); }
+
+ void
+ push_back(const _Tp& __x)
+ { insert(end(), __x); }
+
+ void
+ push_back()
+ { insert(end()); }
+
+ iterator
+ erase(iterator __position)
+ {
+ _List_node_base* __next_node = __position._M_node->_M_next;
+ _List_node_base* __prev_node = __position._M_node->_M_prev;
+ _Node* __n = static_cast<_Node*>(__position._M_node);
+ __prev_node->_M_next = __next_node;
+ __next_node->_M_prev = __prev_node;
+ _Destroy(&__n->_M_data);
+ _M_put_node(__n);
+ return iterator(static_cast<_Node*>(__next_node));
+ }
+
+ iterator
+ erase(iterator __first, iterator __last);
+
+ void
+ clear()
+ { _Base::clear(); }
+
+ void
+ resize(size_type __new_size, const _Tp& __x);
+
+ void
+ resize(size_type __new_size)
+ { this->resize(__new_size, _Tp()); }
+
+ void
+ pop_front()
+ { erase(begin()); }
+
+ void
+ pop_back()
+ {
+ iterator __tmp = end();
+ erase(--__tmp);
+ }
+
+ list(size_type __n, const _Tp& __value,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ { insert(begin(), __n, __value); }
+
+ explicit
+ list(size_type __n)
+ : _Base(allocator_type())
+ { insert(begin(), __n, _Tp()); }
+
+ // We don't need any dispatching tricks here, because insert does all of
+ // that anyway.
+ template<typename _InputIterator>
+ list(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ { insert(begin(), __first, __last); }
+
+ list(const list<_Tp, _Alloc>& __x)
+ : _Base(__x.get_allocator())
+ { insert(begin(), __x.begin(), __x.end()); }
+
+ ~list()
+ { }
+
+ list<_Tp, _Alloc>&
+ operator=(const list<_Tp, _Alloc>& __x);
+
+ public:
+ // assign(), a generalized assignment member function. Two
+ // versions: one that takes a count, and one that takes a range.
+ // The range version is a member template, so we dispatch on whether
+ // or not the type is an integer.
+
+ void
+ assign(size_type __n, const _Tp& __val)
+ { _M_fill_assign(__n, __val); }
+
+ void
+ _M_fill_assign(size_type __n, const _Tp& __val);
+
+ template<typename _InputIterator>
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_assign_dispatch(__first, __last, _Integral());
+ }
+
+ template<typename _Integer>
+ void
+ _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+ { _M_fill_assign((size_type) __n, (_Tp) __val); }
+
+ template<typename _InputIterator>
+ void
+ _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
+ __false_type);
+
+ protected:
+ void
+ _M_transfer(iterator __position, iterator __first, iterator __last)
+ {
+ if (__position != __last) {
+ // Remove [first, last) from its old position.
+ __last._M_node->_M_prev->_M_next = __position._M_node;
+ __first._M_node->_M_prev->_M_next = __last._M_node;
+ __position._M_node->_M_prev->_M_next = __first._M_node;
+
+ // Splice [first, last) into its new position.
+ _List_node_base* __tmp = __position._M_node->_M_prev;
+ __position._M_node->_M_prev = __last._M_node->_M_prev;
+ __last._M_node->_M_prev = __first._M_node->_M_prev;
+ __first._M_node->_M_prev = __tmp;
+ }
+ }
+
+ public:
+ void
+ splice(iterator __position, list& __x)
+ {
+ if (!__x.empty())
+ this->_M_transfer(__position, __x.begin(), __x.end());
+ }
+
+ void
+ splice(iterator __position, list&, iterator __i)
+ {
+ iterator __j = __i;
+ ++__j;
+ if (__position == __i || __position == __j) return;
+ this->_M_transfer(__position, __i, __j);
+ }
+
+ void
+ splice(iterator __position, list&, iterator __first, iterator __last)
+ {
+ if (__first != __last)
+ this->_M_transfer(__position, __first, __last);
+ }
+
+ void
+ remove(const _Tp& __value);
+
+ void
+ unique();
+
+ void
+ merge(list& __x);
+
+ void
+ reverse();
+
+ void
+ sort();
+
+ template<typename _Predicate>
+ void
+ remove_if(_Predicate);
+
+ template<typename _BinaryPredicate>
+ void
+ unique(_BinaryPredicate);
+
+ template<typename _StrictWeakOrdering>
+ void
+ merge(list&, _StrictWeakOrdering);
+
+ template<typename _StrictWeakOrdering>
+ void
+ sort(_StrictWeakOrdering);
+ };
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ {
+ typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
+ const_iterator __end1 = __x.end();
+ const_iterator __end2 = __y.end();
+
+ const_iterator __i1 = __x.begin();
+ const_iterator __i2 = __y.begin();
+ while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
+ ++__i1;
+ ++__i2;
+ }
+ return __i1 == __end1 && __i2 == __end2;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ {
+ return lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end());
+ }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return !(__x == __y); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return __y < __x; }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return !(__y < __x); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+ { return !(__x < __y); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
+ { __x.swap(__y); }
+
+ // move these to stl_list.tcc
+
+ template<typename _Tp, typename _Alloc>
+ void _List_base<_Tp,_Alloc>::
+ clear()
+ {
+ _List_node<_Tp>* __cur = static_cast<_List_node<_Tp>*>(_M_node->_M_next);
+ while (__cur != _M_node) {
+ _List_node<_Tp>* __tmp = __cur;
+ __cur = static_cast<_List_node<_Tp>*>(__cur->_M_next);
+ _Destroy(&__tmp->_M_data);
+ _M_put_node(__tmp);
+ }
+ _M_node->_M_next = _M_node;
+ _M_node->_M_prev = _M_node;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _InputIter>
+ void list<_Tp, _Alloc>::
+ _M_insert_dispatch(iterator __position, _InputIter __first, _InputIter __last,
+ __false_type)
+ {
+ for ( ; __first != __last; ++__first)
+ insert(__position, *__first);
+
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void list<_Tp, _Alloc>::
+ _M_fill_insert(iterator __position, size_type __n, const _Tp& __x)
+ {
+ for ( ; __n > 0; --__n)
+ insert(__position, __x);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::
+ erase(iterator __first, iterator __last)
+ {
+ while (__first != __last)
+ erase(__first++);
+ return __last;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void list<_Tp, _Alloc>::
+ resize(size_type __new_size, const _Tp& __x)
+ {
+ iterator __i = begin();
+ size_type __len = 0;
+ for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
+ ;
+ if (__len == __new_size)
+ erase(__i, end());
+ else // __i == end()
+ insert(end(), __new_size - __len, __x);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ list<_Tp, _Alloc>& list<_Tp, _Alloc>::
+ operator=(const list<_Tp, _Alloc>& __x)
+ {
+ if (this != &__x) {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ const_iterator __first2 = __x.begin();
+ const_iterator __last2 = __x.end();
+ while (__first1 != __last1 && __first2 != __last2)
+ *__first1++ = *__first2++;
+ if (__first2 == __last2)
+ erase(__first1, __last1);
+ else
+ insert(__last1, __first2, __last2);
+ }
+ return *this;
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void list<_Tp, _Alloc>::
+ _M_fill_assign(size_type __n, const _Tp& __val) {
+ iterator __i = begin();
+ for ( ; __i != end() && __n > 0; ++__i, --__n)
+ *__i = __val;
+ if (__n > 0)
+ insert(end(), __n, __val);
+ else
+ erase(__i, end());
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _InputIter>
+ void list<_Tp, _Alloc>::
+ _M_assign_dispatch(_InputIter __first2, _InputIter __last2, __false_type)
+ {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+ *__first1 = *__first2;
+ if (__first2 == __last2)
+ erase(__first1, __last1);
+ else
+ insert(__last1, __first2, __last2);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void list<_Tp, _Alloc>::
+ remove(const _Tp& __value)
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ while (__first != __last) {
+ iterator __next = __first;
+ ++__next;
+ if (*__first == __value) erase(__first);
+ __first = __next;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void list<_Tp, _Alloc>::
+ unique()
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ if (__first == __last) return;
+ iterator __next = __first;
+ while (++__next != __last) {
+ if (*__first == *__next)
+ erase(__next);
+ else
+ __first = __next;
+ __next = __first;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ void list<_Tp, _Alloc>::
+ merge(list<_Tp, _Alloc>& __x)
+ {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ iterator __first2 = __x.begin();
+ iterator __last2 = __x.end();
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first2 < *__first1) {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2) _M_transfer(__last1, __first2, __last2);
+ }
+
+ inline void
+ __List_base_reverse(_List_node_base* __p)
+ {
+ _List_node_base* __tmp = __p;
+ do {
+ std::swap(__tmp->_M_next, __tmp->_M_prev);
+ __tmp = __tmp->_M_prev; // Old next node is now prev.
+ } while (__tmp != __p);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ inline void list<_Tp, _Alloc>::
+ reverse()
+ { __List_base_reverse(this->_M_node); }
+
+ template<typename _Tp, typename _Alloc>
+ void list<_Tp, _Alloc>::
+ sort()
+ {
+ // Do nothing if the list has length 0 or 1.
+ if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
+ list<_Tp, _Alloc> __carry;
+ list<_Tp, _Alloc> __counter[64];
+ int __fill = 0;
+ while (!empty()) {
+ __carry.splice(__carry.begin(), *this, begin());
+ int __i = 0;
+ while(__i < __fill && !__counter[__i].empty()) {
+ __counter[__i].merge(__carry);
+ __carry.swap(__counter[__i++]);
+ }
+ __carry.swap(__counter[__i]);
+ if (__i == __fill) ++__fill;
+ }
+
+ for (int __i = 1; __i < __fill; ++__i)
+ __counter[__i].merge(__counter[__i-1]);
+ swap(__counter[__fill-1]);
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _Predicate>
+ void list<_Tp, _Alloc>::
+ remove_if(_Predicate __pred)
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ while (__first != __last) {
+ iterator __next = __first;
+ ++__next;
+ if (__pred(*__first)) erase(__first);
+ __first = __next;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _BinaryPredicate>
+ void list<_Tp, _Alloc>::
+ unique(_BinaryPredicate __binary_pred)
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ if (__first == __last) return;
+ iterator __next = __first;
+ while (++__next != __last) {
+ if (__binary_pred(*__first, *__next))
+ erase(__next);
+ else
+ __first = __next;
+ __next = __first;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _StrictWeakOrdering>
+ void list<_Tp, _Alloc>::
+ merge(list<_Tp, _Alloc>& __x, _StrictWeakOrdering __comp)
+ {
+ iterator __first1 = begin();
+ iterator __last1 = end();
+ iterator __first2 = __x.begin();
+ iterator __last2 = __x.end();
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first2, *__first1)) {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2) _M_transfer(__last1, __first2, __last2);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template <typename _StrictWeakOrdering>
+ void list<_Tp, _Alloc>::
+ sort(_StrictWeakOrdering __comp)
+ {
+ // Do nothing if the list has length 0 or 1.
+ if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
+ list<_Tp, _Alloc> __carry;
+ list<_Tp, _Alloc> __counter[64];
+ int __fill = 0;
+ while (!empty()) {
+ __carry.splice(__carry.begin(), *this, begin());
+ int __i = 0;
+ while(__i < __fill && !__counter[__i].empty()) {
+ __counter[__i].merge(__carry, __comp);
+ __carry.swap(__counter[__i++]);
+ }
+ __carry.swap(__counter[__i]);
+ if (__i == __fill) ++__fill;
+ }
+
+ for (int __i = 1; __i < __fill; ++__i)
+ __counter[__i].merge(__counter[__i-1], __comp);
+ swap(__counter[__fill-1]);
+ }
+ }
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_LIST_H */
+
+// vi:set ts=2 sw=2:
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_map.h b/contrib/libstdc++/include/bits/stl_map.h
new file mode 100644
index 0000000000000..07c62e4fb5b4f
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_map.h
@@ -0,0 +1,503 @@
+// Map implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_map.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STL_MAP_H
+#define _CPP_BITS_STL_MAP_H 1
+
+#include <bits/concept_check.h>
+
+namespace std
+{
+
+/**
+ * @brief A standard container made up of pairs (see std::pair in <utility>)
+ * which can be retrieved based on a key.
+ *
+ * This is an associative container. Values contained within it can be
+ * quickly retrieved through a key element. Example: MyMap["First"] would
+ * return the data associated with the key "First".
+*/
+template <class _Key, class _Tp, class _Compare = less<_Key>,
+ class _Alloc = allocator<pair<const _Key, _Tp> > >
+class map
+{
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept);
+
+public:
+ // typedefs:
+ typedef _Key key_type;
+ typedef _Tp data_type;
+ typedef _Tp mapped_type;
+ typedef pair<const _Key, _Tp> value_type;
+ typedef _Compare key_compare;
+
+ class value_compare
+ : public binary_function<value_type, value_type, bool> {
+ friend class map<_Key,_Tp,_Compare,_Alloc>;
+ protected :
+ _Compare comp;
+ value_compare(_Compare __c) : comp(__c) {}
+ public:
+ bool operator()(const value_type& __x, const value_type& __y) const {
+ return comp(__x.first, __y.first);
+ }
+ };
+
+private:
+ typedef _Rb_tree<key_type, value_type,
+ _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
+ _Rep_type _M_t; // red-black tree representing map
+public:
+ typedef typename _Rep_type::pointer pointer;
+ typedef typename _Rep_type::const_pointer const_pointer;
+ typedef typename _Rep_type::reference reference;
+ typedef typename _Rep_type::const_reference const_reference;
+ typedef typename _Rep_type::iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
+ typedef typename _Rep_type::allocator_type allocator_type;
+
+ // allocation/deallocation
+
+ map() : _M_t(_Compare(), allocator_type()) {}
+ explicit map(const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) {}
+
+ template <class _InputIterator>
+ map(_InputIterator __first, _InputIterator __last)
+ : _M_t(_Compare(), allocator_type())
+ { _M_t.insert_unique(__first, __last); }
+
+ template <class _InputIterator>
+ map(_InputIterator __first, _InputIterator __last, const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
+ map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {}
+
+ map<_Key,_Tp,_Compare,_Alloc>&
+ operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x)
+ {
+ _M_t = __x._M_t;
+ return *this;
+ }
+
+ // accessors:
+
+ key_compare key_comp() const { return _M_t.key_comp(); }
+ value_compare value_comp() const { return value_compare(_M_t.key_comp()); }
+ allocator_type get_allocator() const { return _M_t.get_allocator(); }
+
+ /**
+ * Returns a read/write iterator that points to the first pair in the map.
+ * Iteration is done in ascending order according to the keys.
+ */
+ iterator begin() { return _M_t.begin(); }
+
+ /**
+ * Returns a read-only (constant) iterator that points to the first pair
+ * in the map. Iteration is done in ascending order according to the keys.
+ */
+ const_iterator begin() const { return _M_t.begin(); }
+
+ /**
+ * Returns a read/write iterator that points one past the last pair in the
+ * map. Iteration is done in ascending order according to the keys.
+ */
+ iterator end() { return _M_t.end(); }
+
+ /**
+ * Returns a read-only (constant) iterator that points one past the last
+ * pair in the map. Iteration is done in ascending order according to the
+ * keys.
+ */
+ const_iterator end() const { return _M_t.end(); }
+
+ /**
+ * Returns a read/write reverse iterator that points to the last pair in
+ * the map. Iteration is done in descending order according to the keys.
+ */
+ reverse_iterator rbegin() { return _M_t.rbegin(); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to the last
+ * pair in the map. Iteration is done in descending order according to
+ * the keys.
+ */
+ const_reverse_iterator rbegin() const { return _M_t.rbegin(); }
+
+ /**
+ * Returns a read/write reverse iterator that points to one before the
+ * first pair in the map. Iteration is done in descending order according
+ * to the keys.
+ */
+ reverse_iterator rend() { return _M_t.rend(); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to one
+ * before the first pair in the map. Iteration is done in descending order
+ * according to the keys.
+ */
+ const_reverse_iterator rend() const { return _M_t.rend(); }
+
+ /** Returns true if the map is empty. (Thus begin() would equal end().) */
+ bool empty() const { return _M_t.empty(); }
+ /** Returns the size of the map. */
+ size_type size() const { return _M_t.size(); }
+ /** Returns the maximum size of the map. */
+ size_type max_size() const { return _M_t.max_size(); }
+
+ /**
+ * @brief Subscript ( [] ) access to map data.
+ * @param k The key for which data should be retrieved.
+ *
+ * Allows for easy lookup with the subscript ( [] ) operator. Returns the
+ * data associated with the key specified in subscript. If the key does
+ * not exist a pair with that key is created with a default value, which
+ * is then returned.
+ */
+ _Tp& operator[](const key_type& __k) {
+ iterator __i = lower_bound(__k);
+ // __i->first is greater than or equivalent to __k.
+ if (__i == end() || key_comp()(__k, (*__i).first))
+ __i = insert(__i, value_type(__k, _Tp()));
+ return (*__i).second;
+ }
+
+ void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
+
+ // insert/erase
+ /**
+ * @brief Attempts to insert a std::pair into the map.
+ * @param x Pair to be inserted (see std::make_pair for easy creation of
+ * pairs).
+ * @return A pair of which the first element is an iterator that points
+ * to the possibly inserted pair, a second element of type bool
+ * to show if the pair was actually inserted.
+ *
+ * This function attempts to insert a (key, value) pair into the map. A
+ * map relies on unique keys and thus a pair is only inserted if its first
+ * element (the key) is not already present in the map.
+ */
+ pair<iterator,bool> insert(const value_type& __x)
+ { return _M_t.insert_unique(__x); }
+
+ /**
+ * @brief Attempts to insert a std::pair into the map.
+ * @param position An iterator that serves as a hint as to where the
+ * pair should be inserted.
+ * @param x Pair to be inserted (see std::make_pair for easy creation of
+ * pairs).
+ * @return An iterator that points to the inserted (key,value) pair.
+ *
+ * This function is not concerned about whether the insertion took place
+ * or not and thus does not return a boolean like the single-argument
+ * insert() does. Note that the first parameter is only a hint and can
+ * potentially improve the performance of the insertion process. A bad
+ * hint would cause no gains in efficiency.
+ */
+ iterator insert(iterator position, const value_type& __x)
+ { return _M_t.insert_unique(position, __x); }
+
+ /**
+ * @brief A template function that attemps to insert elements from
+ * another range (possibly another map).
+ * @param first Iterator pointing to the start of the range to be inserted.
+ * @param last Iterator pointing to the end of the range.
+ */
+ template <class _InputIterator>
+ void insert(_InputIterator __first, _InputIterator __last) {
+ _M_t.insert_unique(__first, __last);
+ }
+
+ /**
+ * @brief Erases an element from a map.
+ * @param position An iterator pointing to the element to be erased.
+ *
+ * This function erases an element, pointed to by the given iterator, from
+ * a map. Note that this function only erases the element, and that if
+ * the element is itself a pointer, the pointed-to memory is not touched
+ * in any way. Managing the pointer is the user's responsibilty.
+ */
+ void erase(iterator __position) { _M_t.erase(__position); }
+
+ /**
+ * @brief Erases an element according to the provided key.
+ * @param x Key of element to be erased.
+ * @return Doc me! (Number of elements that match key? Only makes sense
+ * with multimap)
+ *
+ * This function erases an element, located by the given key, from a map.
+ * Note that this function only erases the element, and that if
+ * the element is itself a pointer, the pointed-to memory is not touched
+ * in any way. Managing the pointer is the user's responsibilty.
+ */
+ size_type erase(const key_type& __x) { return _M_t.erase(__x); }
+
+ /**
+ * @brief Erases a [first,last) range of elements from a map.
+ * @param first Iterator pointing to the start of the range to be erased.
+ * @param last Iterator pointing to the end of the range to be erased.
+ *
+ * This function erases a sequence of elements from a map.
+ * Note that this function only erases the element, and that if
+ * the element is itself a pointer, the pointed-to memory is not touched
+ * in any way. Managing the pointer is the user's responsibilty.
+ */
+ void erase(iterator __first, iterator __last)
+ { _M_t.erase(__first, __last); }
+
+ /** Erases all elements in a map. Note that this function only erases
+ * the elements, and that if the elements themselves are pointers, the
+ * pointed-to memory is not touched in any way. Managing the pointer is
+ * the user's responsibilty.
+ */
+ void clear() { _M_t.clear(); }
+
+ // map operations:
+
+ /**
+ * @brief Tries to locate an element in a map.
+ * @param x Key of (key, value) pair to be located.
+ * @return Iterator pointing to sought-after element, or end() if not
+ * found.
+ *
+ * This function takes a key and tries to locate the element with which
+ * the key matches. If successful the function returns an iterator
+ * pointing to the sought after pair. If unsuccessful it returns the
+ * one past the end ( end() ) iterator.
+ */
+ iterator find(const key_type& __x) { return _M_t.find(__x); }
+
+ /**
+ * @brief Tries to locate an element in a map.
+ * @param x Key of (key, value) pair to be located.
+ * @return Read-only (constant) iterator pointing to sought-after
+ * element, or end() if not found.
+ *
+ * This function takes a key and tries to locate the element with which
+ * the key matches. If successful the function returns a constant iterator
+ * pointing to the sought after pair. If unsuccessful it returns the
+ * one past the end ( end() ) iterator.
+ */
+ const_iterator find(const key_type& __x) const { return _M_t.find(__x); }
+
+ /**
+ * @brief Finds the number of elements with given key.
+ * @param x Key of (key, value) pairs to be located.
+ * @return Number of elements with specified key.
+ *
+ * This function only makes sense for multimaps.
+ */
+ size_type count(const key_type& __x) const {
+ return _M_t.find(__x) == _M_t.end() ? 0 : 1;
+ }
+
+ /**
+ * @brief Finds the beginning of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Iterator pointing to first element matching given key, or
+ * end() if not found.
+ *
+ * This function is useful only with std::multimap. It returns the first
+ * element of a subsequence of elements that matches the given key. If
+ * unsuccessful it returns an iterator pointing to the first element that
+ * has a greater value than given key or end() if no such element exists.
+ */
+ iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); }
+
+ /**
+ * @brief Finds the beginning of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Read-only (constant) iterator pointing to first element
+ * matching given key, or end() if not found.
+ *
+ * This function is useful only with std::multimap. It returns the first
+ * element of a subsequence of elements that matches the given key. If
+ * unsuccessful the iterator will point to the next greatest element or,
+ * if no such greater element exists, to end().
+ */
+ const_iterator lower_bound(const key_type& __x) const {
+ return _M_t.lower_bound(__x);
+ }
+
+ /**
+ * @brief Finds the end of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Iterator pointing to last element matching given key.
+ *
+ * This function only makes sense with multimaps.
+ */
+ iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); }
+
+ /**
+ * @brief Finds the end of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Read-only (constant) iterator pointing to last element matching
+ * given key.
+ *
+ * This function only makes sense with multimaps.
+ */
+ const_iterator upper_bound(const key_type& __x) const {
+ return _M_t.upper_bound(__x);
+ }
+
+ /**
+ * @brief Finds a subsequence matching given key.
+ * @param x Key of (key, value) pairs to be located.
+ * @return Pair of iterators that possibly points to the subsequence
+ * matching given key.
+ *
+ * This function improves on lower_bound() and upper_bound() by giving a more
+ * elegant and efficient solution. It returns a pair of which the first
+ * element possibly points to the first element matching the given key
+ * and the second element possibly points to the last element matching the
+ * given key. If unsuccessful the first element of the returned pair will
+ * contain an iterator pointing to the next greatest element or, if no such
+ * greater element exists, to end().
+ *
+ * This function only makes sense for multimaps.
+ */
+ pair<iterator,iterator> equal_range(const key_type& __x) {
+ return _M_t.equal_range(__x);
+ }
+
+ /**
+ * @brief Finds a subsequence matching given key.
+ * @param x Key of (key, value) pairs to be located.
+ * @return Pair of read-only (constant) iterators that possibly points to
+ * the subsequence matching given key.
+ *
+ * This function improves on lower_bound() and upper_bound() by giving a more
+ * elegant and efficient solution. It returns a pair of which the first
+ * element possibly points to the first element matching the given key
+ * and the second element possibly points to the last element matching the
+ * given key. If unsuccessful the first element of the returned pair will
+ * contain an iterator pointing to the next greatest element or, if no such
+ * a greater element exists, to end().
+ *
+ * This function only makes sense for multimaps.
+ */
+ pair<const_iterator,const_iterator> equal_range(const key_type& __x) const {
+ return _M_t.equal_range(__x);
+ }
+
+ template <class _K1, class _T1, class _C1, class _A1>
+ friend bool operator== (const map<_K1, _T1, _C1, _A1>&,
+ const map<_K1, _T1, _C1, _A1>&);
+ template <class _K1, class _T1, class _C1, class _A1>
+ friend bool operator< (const map<_K1, _T1, _C1, _A1>&,
+ const map<_K1, _T1, _C1, _A1>&);
+};
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+ const map<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return __x._M_t == __y._M_t;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+ const map<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return __x._M_t < __y._M_t;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+ const map<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return !(__x == __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+ const map<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return __y < __x;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+ const map<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return !(__y < __x);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+ const map<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return !(__x < __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x,
+ map<_Key,_Tp,_Compare,_Alloc>& __y) {
+ __x.swap(__y);
+}
+
+} // namespace std
+
+#endif /* _CPP_BITS_STL_MAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_multimap.h b/contrib/libstdc++/include/bits/stl_multimap.h
new file mode 100644
index 0000000000000..5947d7537a671
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_multimap.h
@@ -0,0 +1,491 @@
+// Multimap implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_multimap.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_MULTIMAP_H
+#define __GLIBCPP_INTERNAL_MULTIMAP_H
+
+#include <bits/concept_check.h>
+
+namespace std
+{
+// Forward declaration of operators < and ==, needed for friend declaration.
+template <class _Key, class _Tp,
+ class _Compare = less<_Key>,
+ class _Alloc = allocator<pair<const _Key, _Tp> > >
+class multimap;
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
+
+/**
+ * @brief A standard container made up of pairs (see std::pair in <utility>)
+ * which can be retrieved based on a key.
+ *
+ * This is an associative container. Values contained within it can be
+ * quickly retrieved through a key element. In contrast with a map a
+ * multimap can have multiple duplicate keys.
+*/
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+class multimap
+{
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept);
+
+public:
+
+// typedefs:
+
+ typedef _Key key_type;
+ typedef _Tp data_type;
+ typedef _Tp mapped_type;
+ typedef pair<const _Key, _Tp> value_type;
+ typedef _Compare key_compare;
+
+ class value_compare : public binary_function<value_type, value_type, bool> {
+ friend class multimap<_Key,_Tp,_Compare,_Alloc>;
+ protected:
+ _Compare comp;
+ value_compare(_Compare __c) : comp(__c) {}
+ public:
+ bool operator()(const value_type& __x, const value_type& __y) const {
+ return comp(__x.first, __y.first);
+ }
+ };
+
+private:
+ typedef _Rb_tree<key_type, value_type,
+ _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
+ _Rep_type _M_t; // red-black tree representing multimap
+public:
+ typedef typename _Rep_type::pointer pointer;
+ typedef typename _Rep_type::const_pointer const_pointer;
+ typedef typename _Rep_type::reference reference;
+ typedef typename _Rep_type::const_reference const_reference;
+ typedef typename _Rep_type::iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
+ typedef typename _Rep_type::allocator_type allocator_type;
+
+// allocation/deallocation
+
+ multimap() : _M_t(_Compare(), allocator_type()) { }
+ explicit multimap(const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) { }
+
+ template <class _InputIterator>
+ multimap(_InputIterator __first, _InputIterator __last)
+ : _M_t(_Compare(), allocator_type())
+ { _M_t.insert_equal(__first, __last); }
+
+ template <class _InputIterator>
+ multimap(_InputIterator __first, _InputIterator __last,
+ const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }
+ multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { }
+
+ multimap<_Key,_Tp,_Compare,_Alloc>&
+ operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) {
+ _M_t = __x._M_t;
+ return *this;
+ }
+
+ // accessors:
+
+ key_compare key_comp() const { return _M_t.key_comp(); }
+ value_compare value_comp() const { return value_compare(_M_t.key_comp()); }
+ allocator_type get_allocator() const { return _M_t.get_allocator(); }
+
+ /**
+ * Returns a read/write iterator that points to the first pair in the
+ * multimap. Iteration is done in ascending order according to the keys.
+ */
+ iterator begin() { return _M_t.begin(); }
+
+ /**
+ * Returns a read-only (constant) iterator that points to the first pair
+ * in the multimap. Iteration is done in ascending order according to the
+ * keys.
+ */
+ const_iterator begin() const { return _M_t.begin(); }
+
+ /**
+ * Returns a read/write iterator that points one past the last pair in the
+ * multimap. Iteration is done in ascending order according to the keys.
+ */
+ iterator end() { return _M_t.end(); }
+
+ /**
+ * Returns a read-only (constant) iterator that points one past the last
+ * pair in the multimap. Iteration is done in ascending order according
+ * to the keys.
+ */
+ const_iterator end() const { return _M_t.end(); }
+
+ /**
+ * Returns a read/write reverse iterator that points to the last pair in
+ * the multimap. Iteration is done in descending order according to the
+ * keys.
+ */
+ reverse_iterator rbegin() { return _M_t.rbegin(); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to the last
+ * pair in the multimap. Iteration is done in descending order according
+ * to the keys.
+ */
+ const_reverse_iterator rbegin() const { return _M_t.rbegin(); }
+
+ /**
+ * Returns a read/write reverse iterator that points to one before the
+ * first pair in the multimap. Iteration is done in descending order
+ * according to the keys.
+ */
+ reverse_iterator rend() { return _M_t.rend(); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to one
+ * before the first pair in the multimap. Iteration is done in descending
+ * order according to the keys.
+ */
+ const_reverse_iterator rend() const { return _M_t.rend(); }
+
+ /** Returns true if the map is empty. (Thus begin() would equal end().) */
+ bool empty() const { return _M_t.empty(); }
+
+ /** Returns the size of the map. */
+ size_type size() const { return _M_t.size(); }
+
+ /** Returns the maximum size of the map. */
+ size_type max_size() const { return _M_t.max_size(); }
+
+ void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
+
+ // insert/erase
+ /**
+ * @brief Inserts a std::pair into the multimap.
+ * @param x Pair to be inserted (see std::make_pair for easy creation of
+ * pairs).
+ * @return An iterator that points to the inserted (key,value) pair.
+ *
+ * This function inserts a (key, value) pair into the multimap. Contrary
+ * to a std::map the multimap does not rely on unique keys and thus a
+ * multiple pairs with the same key can be inserted.
+ */
+ iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); }
+
+ /**
+ * @brief Inserts a std::pair into the multimap.
+ * @param position An iterator that serves as a hint as to where the
+ * pair should be inserted.
+ * @param x Pair to be inserted (see std::make_pair for easy creation of
+ * pairs).
+ * @return An iterator that points to the inserted (key,value) pair.
+ *
+ * This function inserts a (key, value) pair into the multimap. Contrary
+ * to a std::map the multimap does not rely on unique keys and thus a
+ * multiple pairs with the same key can be inserted.
+ * Note that the first parameter is only a hint and can potentially
+ * improve the performance of the insertion process. A bad hint would
+ * cause no gains in efficiency.
+ */
+ iterator insert(iterator __position, const value_type& __x) {
+ return _M_t.insert_equal(__position, __x);
+ }
+
+ /**
+ * @brief A template function that attemps to insert elements from
+ * another range (possibly another multimap or standard container).
+ * @param first Iterator pointing to the start of the range to be
+ * inserted.
+ * @param last Iterator pointing to the end of the range to be inserted.
+ */
+ template <class _InputIterator>
+ void insert(_InputIterator __first, _InputIterator __last) {
+ _M_t.insert_equal(__first, __last);
+ }
+
+ /**
+ * @brief Erases an element from a multimap.
+ * @param position An iterator pointing to the element to be erased.
+ *
+ * This function erases an element, pointed to by the given iterator, from
+ * a mutlimap. Note that this function only erases the element, and that
+ * if the element is itself a pointer, the pointed-to memory is not
+ * touched in any way. Managing the pointer is the user's responsibilty.
+ */
+ void erase(iterator __position) { _M_t.erase(__position); }
+
+ /**
+ * @brief Erases an element according to the provided key.
+ * @param x Key of element to be erased.
+ * @return Doc me! (Number of elements erased?)
+ *
+ * This function erases all elements, located by the given key, from a
+ * multimap.
+ * Note that this function only erases the element, and that if
+ * the element is itself a pointer, the pointed-to memory is not touched
+ * in any way. Managing the pointer is the user's responsibilty.
+ */
+ size_type erase(const key_type& __x) { return _M_t.erase(__x); }
+
+ /**
+ * @brief Erases a [first,last) range of elements from a multimap.
+ * @param first Iterator pointing to the start of the range to be erased.
+ * @param last Iterator pointing to the end of the range to be erased.
+ *
+ * This function erases a sequence of elements from a multimap.
+ * Note that this function only erases the elements, and that if
+ * the elements themselves are pointers, the pointed-to memory is not
+ * touched in any way. Managing the pointer is the user's responsibilty.
+ */
+ void erase(iterator __first, iterator __last)
+ { _M_t.erase(__first, __last); }
+
+ /** Erases all elements in a multimap. Note that this function only erases
+ * the elements, and that if the elements themselves are pointers, the
+ * pointed-to memory is not touched in any way. Managing the pointer is
+ * the user's responsibilty.
+ */
+ void clear() { _M_t.clear(); }
+
+ // multimap operations:
+
+ /**
+ * @brief Tries to locate an element in a multimap.
+ * @param x Key of (key, value) pair to be located.
+ * @return Iterator pointing to sought-after (first matching?) element,
+ * or end() if not found.
+ *
+ * This function takes a key and tries to locate the element with which
+ * the key matches. If successful the function returns an iterator
+ * pointing to the sought after pair. If unsuccessful it returns the
+ * one past the end ( end() ) iterator.
+ */
+ iterator find(const key_type& __x) { return _M_t.find(__x); }
+
+ /**
+ * @brief Tries to locate an element in a multimap.
+ * @param x Key of (key, value) pair to be located.
+ * @return Read-only (constant) iterator pointing to sought-after (first
+ * matching?) element, or end() if not found.
+ *
+ * This function takes a key and tries to locate the element with which
+ * the key matches. If successful the function returns a constant iterator
+ * pointing to the sought after pair. If unsuccessful it returns the
+ * one past the end ( end() ) iterator.
+ */
+ const_iterator find(const key_type& __x) const { return _M_t.find(__x); }
+
+ /**
+ * @brief Finds the number of elements with given key.
+ * @param x Key of (key, value) pairs to be located.
+ * @return Number of elements with specified key.
+ */
+ size_type count(const key_type& __x) const { return _M_t.count(__x); }
+
+ /**
+ * @brief Finds the beginning of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Iterator pointing to first element matching given key, or
+ * end() if not found.
+ *
+ * This function returns the first element of a subsequence of elements
+ * that matches the given key. If unsuccessful it returns an iterator
+ * pointing to the first element that has a greater value than given key
+ * or end() if no such element exists.
+ */
+ iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); }
+
+ /**
+ * @brief Finds the beginning of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Read-only (constant) iterator pointing to first element
+ * matching given key, or end() if not found.
+ *
+ * This function returns the first element of a subsequence of elements
+ * that matches the given key. If unsuccessful the iterator will point
+ * to the next greatest element or, if no such greater element exists, to
+ * end().
+ */
+ const_iterator lower_bound(const key_type& __x) const {
+ return _M_t.lower_bound(__x);
+ }
+
+ /**
+ * @brief Finds the end of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Iterator pointing to last element matching given key.
+ */
+ iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); }
+
+ /**
+ * @brief Finds the end of a subsequence matching given key.
+ * @param x Key of (key, value) pair to be located.
+ * @return Read-only (constant) iterator pointing to last element matching
+ * given key.
+ */
+ const_iterator upper_bound(const key_type& __x) const {
+ return _M_t.upper_bound(__x);
+ }
+
+ /**
+ * @brief Finds a subsequence matching given key.
+ * @param x Key of (key, value) pairs to be located.
+ * @return Pair of iterators that possibly points to the subsequence
+ * matching given key.
+ *
+ * This function improves on lower_bound() and upper_bound() by giving a more
+ * elegant and efficient solution. It returns a pair of which the first
+ * element possibly points to the first element matching the given key
+ * and the second element possibly points to the last element matching the
+ * given key. If unsuccessful the first element of the returned pair will
+ * contain an iterator pointing to the next greatest element or, if no such
+ * greater element exists, to end().
+ */
+ pair<iterator,iterator> equal_range(const key_type& __x) {
+ return _M_t.equal_range(__x);
+ }
+
+ /**
+ * @brief Finds a subsequence matching given key.
+ * @param x Key of (key, value) pairs to be located.
+ * @return Pair of read-only (constant) iterators that possibly points to
+ * the subsequence matching given key.
+ *
+ * This function improves on lower_bound() and upper_bound() by giving a more
+ * elegant and efficient solution. It returns a pair of which the first
+ * element possibly points to the first element matching the given key
+ * and the second element possibly points to the last element matching the
+ * given key. If unsuccessful the first element of the returned pair will
+ * contain an iterator pointing to the next greatest element or, if no such
+ * a greater element exists, to end().
+ */
+ pair<const_iterator,const_iterator> equal_range(const key_type& __x) const {
+ return _M_t.equal_range(__x);
+ }
+
+ template <class _K1, class _T1, class _C1, class _A1>
+ friend bool operator== (const multimap<_K1, _T1, _C1, _A1>&,
+ const multimap<_K1, _T1, _C1, _A1>&);
+ template <class _K1, class _T1, class _C1, class _A1>
+ friend bool operator< (const multimap<_K1, _T1, _C1, _A1>&,
+ const multimap<_K1, _T1, _C1, _A1>&);
+};
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return __x._M_t == __y._M_t;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return __x._M_t < __y._M_t;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return !(__x == __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return __y < __x;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return !(__y < __x);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline bool operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ const multimap<_Key,_Tp,_Compare,_Alloc>& __y) {
+ return !(__x < __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Alloc>
+inline void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+ multimap<_Key,_Tp,_Compare,_Alloc>& __y) {
+ __x.swap(__y);
+}
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_MULTIMAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_multiset.h b/contrib/libstdc++/include/bits/stl_multiset.h
new file mode 100644
index 0000000000000..2bfc8f10c32b4
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_multiset.h
@@ -0,0 +1,277 @@
+// Multiset implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_multiset.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_MULTISET_H
+#define __GLIBCPP_INTERNAL_MULTISET_H
+
+#include <bits/concept_check.h>
+
+namespace std
+{
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template <class _Key, class _Compare = less<_Key>,
+ class _Alloc = allocator<_Key> >
+class multiset;
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y);
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y);
+
+template <class _Key, class _Compare, class _Alloc>
+class multiset
+{
+ // concept requirements
+ __glibcpp_class_requires(_Key, _SGIAssignableConcept)
+ __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept);
+
+public:
+
+ // typedefs:
+
+ typedef _Key key_type;
+ typedef _Key value_type;
+ typedef _Compare key_compare;
+ typedef _Compare value_compare;
+private:
+ typedef _Rb_tree<key_type, value_type,
+ _Identity<value_type>, key_compare, _Alloc> _Rep_type;
+ _Rep_type _M_t; // red-black tree representing multiset
+public:
+ typedef typename _Rep_type::const_pointer pointer;
+ typedef typename _Rep_type::const_pointer const_pointer;
+ typedef typename _Rep_type::const_reference reference;
+ typedef typename _Rep_type::const_reference const_reference;
+ typedef typename _Rep_type::const_iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
+ typedef typename _Rep_type::allocator_type allocator_type;
+
+ // allocation/deallocation
+
+ multiset() : _M_t(_Compare(), allocator_type()) {}
+ explicit multiset(const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) {}
+
+ template <class _InputIterator>
+ multiset(_InputIterator __first, _InputIterator __last)
+ : _M_t(_Compare(), allocator_type())
+ { _M_t.insert_equal(__first, __last); }
+
+ template <class _InputIterator>
+ multiset(_InputIterator __first, _InputIterator __last,
+ const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }
+
+ multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {}
+
+ multiset<_Key,_Compare,_Alloc>&
+ operator=(const multiset<_Key,_Compare,_Alloc>& __x) {
+ _M_t = __x._M_t;
+ return *this;
+ }
+
+ // accessors:
+
+ key_compare key_comp() const { return _M_t.key_comp(); }
+ value_compare value_comp() const { return _M_t.key_comp(); }
+ allocator_type get_allocator() const { return _M_t.get_allocator(); }
+
+ iterator begin() const { return _M_t.begin(); }
+ iterator end() const { return _M_t.end(); }
+ reverse_iterator rbegin() const { return _M_t.rbegin(); }
+ reverse_iterator rend() const { return _M_t.rend(); }
+ bool empty() const { return _M_t.empty(); }
+ size_type size() const { return _M_t.size(); }
+ size_type max_size() const { return _M_t.max_size(); }
+ void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
+
+ // insert/erase
+ iterator insert(const value_type& __x) {
+ return _M_t.insert_equal(__x);
+ }
+ iterator insert(iterator __position, const value_type& __x) {
+ typedef typename _Rep_type::iterator _Rep_iterator;
+ return _M_t.insert_equal((_Rep_iterator&)__position, __x);
+ }
+
+ template <class _InputIterator>
+ void insert(_InputIterator __first, _InputIterator __last) {
+ _M_t.insert_equal(__first, __last);
+ }
+ void erase(iterator __position) {
+ typedef typename _Rep_type::iterator _Rep_iterator;
+ _M_t.erase((_Rep_iterator&)__position);
+ }
+ size_type erase(const key_type& __x) {
+ return _M_t.erase(__x);
+ }
+ void erase(iterator __first, iterator __last) {
+ typedef typename _Rep_type::iterator _Rep_iterator;
+ _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
+ }
+ void clear() { _M_t.clear(); }
+
+ // multiset operations:
+
+ size_type count(const key_type& __x) const { return _M_t.count(__x); }
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//214. set::find() missing const overload
+ iterator find(const key_type& __x) { return _M_t.find(__x); }
+ const_iterator find(const key_type& __x) const { return _M_t.find(__x); }
+ iterator lower_bound(const key_type& __x) {
+ return _M_t.lower_bound(__x);
+ }
+ const_iterator lower_bound(const key_type& __x) const {
+ return _M_t.lower_bound(__x);
+ }
+ iterator upper_bound(const key_type& __x) {
+ return _M_t.upper_bound(__x);
+ }
+ const_iterator upper_bound(const key_type& __x) const {
+ return _M_t.upper_bound(__x);
+ }
+ pair<iterator,iterator> equal_range(const key_type& __x) {
+ return _M_t.equal_range(__x);
+ }
+ pair<const_iterator,const_iterator> equal_range(const key_type& __x) const {
+ return _M_t.equal_range(__x);
+ }
+#else
+ iterator find(const key_type& __x) const { return _M_t.find(__x); }
+ iterator lower_bound(const key_type& __x) const {
+ return _M_t.lower_bound(__x);
+ }
+ iterator upper_bound(const key_type& __x) const {
+ return _M_t.upper_bound(__x);
+ }
+ pair<iterator,iterator> equal_range(const key_type& __x) const {
+ return _M_t.equal_range(__x);
+ }
+#endif
+
+ template <class _K1, class _C1, class _A1>
+ friend bool operator== (const multiset<_K1,_C1,_A1>&,
+ const multiset<_K1,_C1,_A1>&);
+ template <class _K1, class _C1, class _A1>
+ friend bool operator< (const multiset<_K1,_C1,_A1>&,
+ const multiset<_K1,_C1,_A1>&);
+};
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y) {
+ return __x._M_t == __y._M_t;
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y) {
+ return __x._M_t < __y._M_t;
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator!=(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y) {
+ return !(__x == __y);
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y) {
+ return __y < __x;
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator<=(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y) {
+ return !(__y < __x);
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator>=(const multiset<_Key,_Compare,_Alloc>& __x,
+ const multiset<_Key,_Compare,_Alloc>& __y) {
+ return !(__x < __y);
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline void swap(multiset<_Key,_Compare,_Alloc>& __x,
+ multiset<_Key,_Compare,_Alloc>& __y) {
+ __x.swap(__y);
+}
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_MULTISET_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_numeric.h b/contrib/libstdc++/include/bits/stl_numeric.h
new file mode 100644
index 0000000000000..23f2bcc4512c5
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_numeric.h
@@ -0,0 +1,215 @@
+// Numeric functions implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_numeric.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STL_NUMERIC_H
+#define _CPP_BITS_STL_NUMERIC_H 1
+
+namespace std
+{
+
+ template<typename _InputIterator, typename _Tp>
+ _Tp
+ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+
+ for ( ; __first != __last; ++__first)
+ __init = __init + *__first;
+ return __init;
+ }
+
+ template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
+ _Tp
+ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
+ _BinaryOperation __binary_op)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+
+ for ( ; __first != __last; ++__first)
+ __init = __binary_op(__init, *__first);
+ return __init;
+ }
+
+ template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
+ _Tp
+ inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _Tp __init)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator2>)
+
+ for ( ; __first1 != __last1; ++__first1, ++__first2)
+ __init = __init + (*__first1 * *__first2);
+ return __init;
+ }
+
+ template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
+ typename _BinaryOperation1, typename _BinaryOperation2>
+ _Tp
+ inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _Tp __init,
+ _BinaryOperation1 __binary_op1,
+ _BinaryOperation2 __binary_op2)
+ {
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator1>)
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator2>)
+
+ for ( ; __first1 != __last1; ++__first1, ++__first2)
+ __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
+ return __init;
+ }
+
+ template<typename _InputIterator, typename _OutputIterator>
+ _OutputIterator
+ partial_sum(_InputIterator __first, _InputIterator __last,
+ _OutputIterator __result)
+ {
+ typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+
+ if (__first == __last) return __result;
+ *__result = *__first;
+ _ValueType __value = *__first;
+ while (++__first != __last) {
+ __value = __value + *__first;
+ *++__result = __value;
+ }
+ return ++__result;
+ }
+
+ template<typename _InputIterator, typename _OutputIterator, typename _BinaryOperation>
+ _OutputIterator
+ partial_sum(_InputIterator __first, _InputIterator __last,
+ _OutputIterator __result, _BinaryOperation __binary_op)
+ {
+ typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+
+ if (__first == __last) return __result;
+ *__result = *__first;
+ _ValueType __value = *__first;
+ while (++__first != __last) {
+ __value = __binary_op(__value, *__first);
+ *++__result = __value;
+ }
+ return ++__result;
+ }
+
+ template<typename _InputIterator, typename _OutputIterator>
+ _OutputIterator
+ adjacent_difference(_InputIterator __first,
+ _InputIterator __last, _OutputIterator __result)
+ {
+ typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+
+ if (__first == __last) return __result;
+ *__result = *__first;
+ _ValueType __value = *__first;
+ while (++__first != __last) {
+ _ValueType __tmp = *__first;
+ *++__result = __tmp - __value;
+ __value = __tmp;
+ }
+ return ++__result;
+ }
+
+ template<typename _InputIterator, typename _OutputIterator, typename _BinaryOperation>
+ _OutputIterator
+ adjacent_difference(_InputIterator __first, _InputIterator __last,
+ _OutputIterator __result, _BinaryOperation __binary_op)
+ {
+ typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
+
+ // concept requirements
+ __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+ __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+
+ if (__first == __last) return __result;
+ *__result = *__first;
+ _ValueType __value = *__first;
+ while (++__first != __last) {
+ _ValueType __tmp = *__first;
+ *++__result = __binary_op(__tmp, __value);
+ __value = __tmp;
+ }
+ return ++__result;
+ }
+
+} // namespace std
+
+#endif /* _CPP_BITS_STL_NUMERIC_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_pair.h b/contrib/libstdc++/include/bits/stl_pair.h
new file mode 100644
index 0000000000000..d689ccc8d27d6
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_pair.h
@@ -0,0 +1,157 @@
+// Pair implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_pair.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_PAIR_H
+#define __GLIBCPP_INTERNAL_PAIR_H
+
+namespace std
+{
+
+/// pair holds two objects of arbitrary type.
+template <class _T1, class _T2>
+struct pair {
+ typedef _T1 first_type; ///< @c first_type is the first bound type
+ typedef _T2 second_type; ///< @c second_type is the second bound type
+
+ _T1 first; ///< @c first is a copy of the first object
+ _T2 second; ///< @c second is a copy of the second object
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//265. std::pair::pair() effects overly restrictive
+ /** The default constructor creates @c first and @c second using their
+ * respective default constructors. */
+ pair() : first(), second() {}
+#else
+ pair() : first(_T1()), second(_T2()) {}
+#endif
+ /** Two objects may be passed to a @c pair constructor to be copied. */
+ pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {}
+
+ /** There is also a templated copy ctor for the @c pair class itself. */
+ template <class _U1, class _U2>
+ pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
+};
+
+/// Two pairs of the same type are equal iff their members are equal.
+template <class _T1, class _T2>
+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
+template <class _T1, class _T2>
+inline bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
+{
+ return __x.first < __y.first ||
+ (!(__y.first < __x.first) && __x.second < __y.second);
+}
+
+/// Uses @c operator== to find the result.
+template <class _T1, class _T2>
+inline bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+ return !(__x == __y);
+}
+
+/// Uses @c operator< to find the result.
+template <class _T1, class _T2>
+inline bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+ return __y < __x;
+}
+
+/// Uses @c operator< to find the result.
+template <class _T1, class _T2>
+inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+ return !(__y < __x);
+}
+
+/// Uses @c operator< to find the result.
+template <class _T1, class _T2>
+inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+ return !(__x < __y);
+}
+
+/**
+ * @brief A convenience wrapper for creating a pair from two objects.
+ * @param x The first object.
+ * @param y The second object.
+ * @return A newly-constructed pair<> object of the appropriate type.
+ *
+ * The standard requires that the objects be passed by reference-to-const,
+ * but LWG issue #181 says they should be passed by const value. We follow
+ * the LWG by default.
+*/
+template <class _T1, class _T2>
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//181. make_pair() unintended behavior
+inline pair<_T1, _T2> make_pair(_T1 __x, _T2 __y)
+#else
+inline pair<_T1, _T2> make_pair(const _T1& __x, const _T2& __y)
+#endif
+{
+ return pair<_T1, _T2>(__x, __y);
+}
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_PAIR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_pthread_alloc.h b/contrib/libstdc++/include/bits/stl_pthread_alloc.h
new file mode 100644
index 0000000000000..09b7d727af65c
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_pthread_alloc.h
@@ -0,0 +1,60 @@
+// Wrapper of pthread allocation header -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_pthread_alloc.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STL_PTHREAD_ALLOC_H
+#define _CPP_BITS_STL_PTHREAD_ALLOC_H 1
+
+#include <bits/pthread_allocimpl.h>
+
+using std::_Pthread_alloc_template;
+using std::pthread_alloc;
+
+#endif /* _CPP_BITS_STL_PTHREAD_ALLOC_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_queue.h b/contrib/libstdc++/include/bits/stl_queue.h
new file mode 100644
index 0000000000000..5503640187aca
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_queue.h
@@ -0,0 +1,244 @@
+// Queue implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_queue.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_QUEUE_H
+#define __GLIBCPP_INTERNAL_QUEUE_H
+
+#include <bits/concept_check.h>
+
+namespace std
+{
+
+// Forward declarations of operators < and ==, needed for friend declaration.
+
+template <class _Tp,
+ class _Sequence = deque<_Tp> >
+class queue;
+
+template <class _Tp, class _Seq>
+inline bool operator==(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&);
+
+template <class _Tp, class _Seq>
+inline bool operator<(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&);
+
+
+template <class _Tp, class _Sequence>
+class queue
+{
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcpp_class_requires(_Sequence, _FrontInsertionSequenceConcept)
+ __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept)
+ typedef typename _Sequence::value_type _Sequence_value_type;
+ __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept);
+
+ template <class _Tp1, class _Seq1>
+ friend bool operator== (const queue<_Tp1, _Seq1>&,
+ const queue<_Tp1, _Seq1>&);
+ template <class _Tp1, class _Seq1>
+ friend bool operator< (const queue<_Tp1, _Seq1>&,
+ const queue<_Tp1, _Seq1>&);
+public:
+ typedef typename _Sequence::value_type value_type;
+ typedef typename _Sequence::size_type size_type;
+ typedef _Sequence container_type;
+
+ typedef typename _Sequence::reference reference;
+ typedef typename _Sequence::const_reference const_reference;
+protected:
+ _Sequence c;
+public:
+ explicit queue(const _Sequence& __c = _Sequence()) : c(__c) {}
+
+ bool empty() const { return c.empty(); }
+ size_type size() const { return c.size(); }
+ reference front() { return c.front(); }
+ const_reference front() const { return c.front(); }
+ reference back() { return c.back(); }
+ const_reference back() const { return c.back(); }
+ void push(const value_type& __x) { c.push_back(__x); }
+ void pop() { c.pop_front(); }
+};
+
+template <class _Tp, class _Sequence>
+bool
+operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
+{
+ return __x.c == __y.c;
+}
+
+template <class _Tp, class _Sequence>
+bool
+operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
+{
+ return __x.c < __y.c;
+}
+
+template <class _Tp, class _Sequence>
+bool
+operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp, class _Sequence>
+bool
+operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp, class _Sequence>
+bool
+operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
+{
+ return !(__y < __x);
+}
+
+template <class _Tp, class _Sequence>
+bool
+operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
+{
+ return !(__x < __y);
+}
+
+template <class _Tp,
+ class _Sequence = vector<_Tp>,
+ class _Compare = less<typename _Sequence::value_type> >
+class priority_queue
+{
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcpp_class_requires(_Sequence, _SequenceConcept)
+ __glibcpp_class_requires(_Sequence, _RandomAccessContainerConcept)
+ typedef typename _Sequence::value_type _Sequence_value_type;
+ __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept);
+ __glibcpp_class_requires4(_Compare, bool, _Tp, _Tp, _BinaryFunctionConcept);
+
+public:
+ typedef typename _Sequence::value_type value_type;
+ typedef typename _Sequence::size_type size_type;
+ typedef _Sequence container_type;
+
+ typedef typename _Sequence::reference reference;
+ typedef typename _Sequence::const_reference const_reference;
+protected:
+ _Sequence c;
+ _Compare comp;
+public:
+ explicit priority_queue(const _Compare& __x = _Compare(),
+ const _Sequence& __s = _Sequence())
+ : c(__s), comp(__x)
+ { make_heap(c.begin(), c.end(), comp); }
+
+ template <class _InputIterator>
+ priority_queue(_InputIterator __first, _InputIterator __last,
+ const _Compare& __x = _Compare(),
+ const _Sequence& __s = _Sequence())
+ : c(__s), comp(__x)
+ {
+ c.insert(c.end(), __first, __last);
+ make_heap(c.begin(), c.end(), comp);
+ }
+
+ bool empty() const { return c.empty(); }
+ size_type size() const { return c.size(); }
+ const_reference top() const { return c.front(); }
+
+ void
+ push(const value_type& __x)
+ {
+ try
+ {
+ c.push_back(__x);
+ push_heap(c.begin(), c.end(), comp);
+ }
+ catch(...)
+ {
+ c.clear();
+ __throw_exception_again;
+ }
+ }
+
+ void
+ pop()
+ {
+ try
+ {
+ pop_heap(c.begin(), c.end(), comp);
+ c.pop_back();
+ }
+ catch(...)
+ {
+ c.clear();
+ __throw_exception_again;
+ }
+ }
+};
+
+// no equality is provided
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_QUEUE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_raw_storage_iter.h b/contrib/libstdc++/include/bits/stl_raw_storage_iter.h
new file mode 100644
index 0000000000000..59aa004296e88
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_raw_storage_iter.h
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_raw_storage_iter.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H
+#define _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H 1
+
+namespace std
+{
+ /**
+ * This iterator class lets algorithms store their results into
+ * uninitialized memory.
+ */
+ template <class _ForwardIterator, class _Tp>
+ class raw_storage_iterator
+ : public iterator<output_iterator_tag, void, void, void, void>
+ {
+ protected:
+ _ForwardIterator _M_iter;
+
+ public:
+ explicit
+ raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {}
+
+ raw_storage_iterator&
+ operator*() { return *this; }
+
+ raw_storage_iterator&
+ operator=(const _Tp& __element)
+ {
+ _Construct(&*_M_iter, __element);
+ return *this;
+ }
+
+ raw_storage_iterator<_ForwardIterator, _Tp>&
+ operator++()
+ {
+ ++_M_iter;
+ return *this;
+ }
+
+ raw_storage_iterator<_ForwardIterator, _Tp>
+ operator++(int)
+ {
+ raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this;
+ ++_M_iter;
+ return __tmp;
+ }
+ };
+} // namespace std
+
+#endif
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_relops.h b/contrib/libstdc++/include/bits/stl_relops.h
new file mode 100644
index 0000000000000..ce3dc0b9b393f
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_relops.h
@@ -0,0 +1,141 @@
+// std::rel_ops implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+/** @file stl_relops.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ *
+ * @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
+ * with http://gcc.gnu.org/ml/libstdc++/2001-01/msg00223.html , or the
+ * 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.
+ * @endif
+ */
+
+#ifndef _CPP_BITS_STL_RELOPS_H
+#define _CPP_BITS_STL_RELOPS_H 1
+
+namespace std
+{
+ namespace rel_ops
+ {
+ /** @namespace std::rel_ops
+ * @brief The generated relational operators are sequestered here.
+ */
+
+/**
+ * @brief Defines @c != for arbitrary types, in terms of @c ==.
+ * @param x A thing.
+ * @param y Another thing.
+ * @return x != y
+ *
+ * This function uses @c == to determine its result.
+*/
+template <class _Tp>
+inline bool operator!=(const _Tp& __x, const _Tp& __y) {
+ return !(__x == __y);
+}
+
+/**
+ * @brief Defines @c > for arbitrary types, in terms of @c <.
+ * @param x A thing.
+ * @param y Another thing.
+ * @return x > y
+ *
+ * This function uses @c < to determine its result.
+*/
+template <class _Tp>
+inline bool operator>(const _Tp& __x, const _Tp& __y) {
+ return __y < __x;
+}
+
+/**
+ * @brief Defines @c <= for arbitrary types, in terms of @c <.
+ * @param x A thing.
+ * @param y Another thing.
+ * @return x <= y
+ *
+ * This function uses @c < to determine its result.
+*/
+template <class _Tp>
+inline bool operator<=(const _Tp& __x, const _Tp& __y) {
+ return !(__y < __x);
+}
+
+/**
+ * @brief Defines @c >= for arbitrary types, in terms of @c <.
+ * @param x A thing.
+ * @param y Another thing.
+ * @return x >= y
+ *
+ * This function uses @c < to determine its result.
+*/
+template <class _Tp>
+inline bool operator>=(const _Tp& __x, const _Tp& __y) {
+ return !(__x < __y);
+}
+
+ } // namespace rel_ops
+} // namespace std
+
+#endif /* _CPP_BITS_STL_RELOPS_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_set.h b/contrib/libstdc++/include/bits/stl_set.h
new file mode 100644
index 0000000000000..ee708c292179a
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_set.h
@@ -0,0 +1,274 @@
+// Set implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_set.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_SET_H
+#define __GLIBCPP_INTERNAL_SET_H
+
+#include <bits/concept_check.h>
+
+namespace std
+{
+
+// Forward declarations of operators < and ==, needed for friend declaration.
+
+template <class _Key, class _Compare = less<_Key>,
+ class _Alloc = allocator<_Key> >
+class set;
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator==(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y);
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator<(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y);
+
+
+template <class _Key, class _Compare, class _Alloc>
+class set
+{
+ // concept requirements
+ __glibcpp_class_requires(_Key, _SGIAssignableConcept)
+ __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept);
+
+public:
+ // typedefs:
+ typedef _Key key_type;
+ typedef _Key value_type;
+ typedef _Compare key_compare;
+ typedef _Compare value_compare;
+private:
+ typedef _Rb_tree<key_type, value_type,
+ _Identity<value_type>, key_compare, _Alloc> _Rep_type;
+ _Rep_type _M_t; // red-black tree representing set
+public:
+ typedef typename _Rep_type::const_pointer pointer;
+ typedef typename _Rep_type::const_pointer const_pointer;
+ typedef typename _Rep_type::const_reference reference;
+ typedef typename _Rep_type::const_reference const_reference;
+ typedef typename _Rep_type::const_iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
+ typedef typename _Rep_type::allocator_type allocator_type;
+
+ // allocation/deallocation
+
+ set() : _M_t(_Compare(), allocator_type()) {}
+ explicit set(const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) {}
+
+ template <class _InputIterator>
+ set(_InputIterator __first, _InputIterator __last)
+ : _M_t(_Compare(), allocator_type())
+ { _M_t.insert_unique(__first, __last); }
+
+ template <class _InputIterator>
+ set(_InputIterator __first, _InputIterator __last, const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
+
+ set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {}
+ set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x)
+ {
+ _M_t = __x._M_t;
+ return *this;
+ }
+
+ // accessors:
+
+ key_compare key_comp() const { return _M_t.key_comp(); }
+ value_compare value_comp() const { return _M_t.key_comp(); }
+ allocator_type get_allocator() const { return _M_t.get_allocator(); }
+
+ iterator begin() const { return _M_t.begin(); }
+ iterator end() const { return _M_t.end(); }
+ reverse_iterator rbegin() const { return _M_t.rbegin(); }
+ reverse_iterator rend() const { return _M_t.rend(); }
+ bool empty() const { return _M_t.empty(); }
+ size_type size() const { return _M_t.size(); }
+ size_type max_size() const { return _M_t.max_size(); }
+ void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
+
+ // insert/erase
+ pair<iterator,bool> insert(const value_type& __x) {
+ pair<typename _Rep_type::iterator, bool> __p = _M_t.insert_unique(__x);
+ return pair<iterator, bool>(__p.first, __p.second);
+ }
+ iterator insert(iterator __position, const value_type& __x) {
+ typedef typename _Rep_type::iterator _Rep_iterator;
+ return _M_t.insert_unique((_Rep_iterator&)__position, __x);
+ }
+ template <class _InputIterator>
+ void insert(_InputIterator __first, _InputIterator __last) {
+ _M_t.insert_unique(__first, __last);
+ }
+ void erase(iterator __position) {
+ typedef typename _Rep_type::iterator _Rep_iterator;
+ _M_t.erase((_Rep_iterator&)__position);
+ }
+ size_type erase(const key_type& __x) {
+ return _M_t.erase(__x);
+ }
+ void erase(iterator __first, iterator __last) {
+ typedef typename _Rep_type::iterator _Rep_iterator;
+ _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
+ }
+ void clear() { _M_t.clear(); }
+
+ // set operations:
+
+ size_type count(const key_type& __x) const {
+ return _M_t.find(__x) == _M_t.end() ? 0 : 1;
+ }
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+//214. set::find() missing const overload
+ iterator find(const key_type& __x) { return _M_t.find(__x); }
+ const_iterator find(const key_type& __x) const { return _M_t.find(__x); }
+ iterator lower_bound(const key_type& __x) {
+ return _M_t.lower_bound(__x);
+ }
+ const_iterator lower_bound(const key_type& __x) const {
+ return _M_t.lower_bound(__x);
+ }
+ iterator upper_bound(const key_type& __x) {
+ return _M_t.upper_bound(__x);
+ }
+ const_iterator upper_bound(const key_type& __x) const {
+ return _M_t.upper_bound(__x);
+ }
+ pair<iterator,iterator> equal_range(const key_type& __x) {
+ return _M_t.equal_range(__x);
+ }
+ pair<const_iterator,const_iterator> equal_range(const key_type& __x) const {
+ return _M_t.equal_range(__x);
+ }
+#else
+ iterator find(const key_type& __x) const { return _M_t.find(__x); }
+ iterator lower_bound(const key_type& __x) const {
+ return _M_t.lower_bound(__x);
+ }
+ iterator upper_bound(const key_type& __x) const {
+ return _M_t.upper_bound(__x);
+ }
+ pair<iterator,iterator> equal_range(const key_type& __x) const {
+ return _M_t.equal_range(__x);
+ }
+#endif
+
+ template <class _K1, class _C1, class _A1>
+ friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
+ template <class _K1, class _C1, class _A1>
+ friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
+};
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator==(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y) {
+ return __x._M_t == __y._M_t;
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator<(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y) {
+ return __x._M_t < __y._M_t;
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator!=(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y) {
+ return !(__x == __y);
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator>(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y) {
+ return __y < __x;
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator<=(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y) {
+ return !(__y < __x);
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline bool operator>=(const set<_Key,_Compare,_Alloc>& __x,
+ const set<_Key,_Compare,_Alloc>& __y) {
+ return !(__x < __y);
+}
+
+template <class _Key, class _Compare, class _Alloc>
+inline void swap(set<_Key,_Compare,_Alloc>& __x,
+ set<_Key,_Compare,_Alloc>& __y) {
+ __x.swap(__y);
+}
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_SET_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_stack.h b/contrib/libstdc++/include/bits/stl_stack.h
new file mode 100644
index 0000000000000..0a80b109f6a8c
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_stack.h
@@ -0,0 +1,160 @@
+// Stack implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_stack.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_STACK_H
+#define __GLIBCPP_INTERNAL_STACK_H
+
+#include <bits/concept_check.h>
+
+namespace std
+{
+
+// Forward declarations of operators == and <, needed for friend declaration.
+
+template <class _Tp,
+ class _Sequence = deque<_Tp> >
+class stack;
+
+template <class _Tp, class _Seq>
+bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
+
+template <class _Tp, class _Seq>
+bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
+
+
+template <class _Tp, class _Sequence>
+class stack
+{
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept)
+ typedef typename _Sequence::value_type _Sequence_value_type;
+ __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept);
+
+ template <class _Tp1, class _Seq1>
+ friend bool operator== (const stack<_Tp1, _Seq1>&,
+ const stack<_Tp1, _Seq1>&);
+ template <class _Tp1, class _Seq1>
+ friend bool operator< (const stack<_Tp1, _Seq1>&,
+ const stack<_Tp1, _Seq1>&);
+public:
+ typedef typename _Sequence::value_type value_type;
+ typedef typename _Sequence::size_type size_type;
+ typedef _Sequence container_type;
+
+ typedef typename _Sequence::reference reference;
+ typedef typename _Sequence::const_reference const_reference;
+protected:
+ _Sequence c;
+public:
+ stack() : c() {}
+ explicit stack(const _Sequence& __s) : c(__s) {}
+
+ bool empty() const { return c.empty(); }
+ size_type size() const { return c.size(); }
+ reference top() { return c.back(); }
+ const_reference top() const { return c.back(); }
+ void push(const value_type& __x) { c.push_back(__x); }
+ void pop() { c.pop_back(); }
+};
+
+template <class _Tp, class _Seq>
+bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+{
+ return __x.c == __y.c;
+}
+
+template <class _Tp, class _Seq>
+bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+{
+ return __x.c < __y.c;
+}
+
+template <class _Tp, class _Seq>
+bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+{
+ return !(__x == __y);
+}
+
+template <class _Tp, class _Seq>
+bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+{
+ return __y < __x;
+}
+
+template <class _Tp, class _Seq>
+bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+{
+ return !(__y < __x);
+}
+
+template <class _Tp, class _Seq>
+bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+{
+ return !(__x < __y);
+}
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_STACK_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_tempbuf.h b/contrib/libstdc++/include/bits/stl_tempbuf.h
new file mode 100644
index 0000000000000..7b88f9333ec76
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_tempbuf.h
@@ -0,0 +1,149 @@
+// Temporary buffer implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_tempbuf.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_TEMPBUF_H
+#define __GLIBCPP_INTERNAL_TEMPBUF_H
+
+namespace std
+{
+
+/**
+ * @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.
+ * @endif
+*/
+template <class _ForwardIterator, class _Tp>
+ class _Temporary_buffer
+{
+ // concept requirements
+ __glibcpp_class_requires(_ForwardIterator, _ForwardIteratorConcept)
+
+ ptrdiff_t _M_original_len;
+ ptrdiff_t _M_len;
+ _Tp* _M_buffer;
+
+ // this is basically get_temporary_buffer() all over again
+ void _M_allocate_buffer() {
+ _M_original_len = _M_len;
+ _M_buffer = 0;
+
+ if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp)))
+ _M_len = INT_MAX / sizeof(_Tp);
+
+ while (_M_len > 0) {
+ _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp));
+ if (_M_buffer)
+ break;
+ _M_len /= 2;
+ }
+ }
+
+ void _M_initialize_buffer(const _Tp&, __true_type) {}
+ void _M_initialize_buffer(const _Tp& val, __false_type) {
+ uninitialized_fill_n(_M_buffer, _M_len, val);
+ }
+
+public:
+ /// As per Table mumble.
+ ptrdiff_t size() const { return _M_len; }
+ /// Returns the size requested by the constructor; may be >size().
+ ptrdiff_t requested_size() const { return _M_original_len; }
+ /// As per Table mumble.
+ _Tp* begin() { return _M_buffer; }
+ /// As per Table mumble.
+ _Tp* end() { return _M_buffer + _M_len; }
+
+ _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) {
+ // Workaround for a __type_traits bug in the pre-7.3 compiler.
+ typedef typename __type_traits<_Tp>::has_trivial_default_constructor
+ _Trivial;
+
+ try {
+ _M_len = distance(__first, __last);
+ _M_allocate_buffer();
+ if (_M_len > 0)
+ _M_initialize_buffer(*__first, _Trivial());
+ }
+ catch(...)
+ {
+ free(_M_buffer);
+ _M_buffer = 0;
+ _M_len = 0;
+ __throw_exception_again;
+ }
+ }
+
+ ~_Temporary_buffer() {
+ _Destroy(_M_buffer, _M_buffer + _M_len);
+ free(_M_buffer);
+ }
+
+private:
+ // Disable copy constructor and assignment operator.
+ _Temporary_buffer(const _Temporary_buffer&) {}
+ void operator=(const _Temporary_buffer&) {}
+};
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_TEMPBUF_H */
+
diff --git a/contrib/libstdc++/include/bits/stl_threads.h b/contrib/libstdc++/include/bits/stl_threads.h
new file mode 100644
index 0000000000000..0150cd58c85cb
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_threads.h
@@ -0,0 +1,236 @@
+// Threading support -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1997-1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_threads.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_THREADS_H
+#define __SGI_STL_INTERNAL_THREADS_H
+
+// The only supported threading model is GCC's own gthr.h abstraction layer.
+#include "bits/gthr.h"
+
+namespace std
+{
+ // Class _Refcount_Base provides a type, _RC_t, a data member,
+ // _M_ref_count, and member functions _M_incr and _M_decr, which perform
+ // atomic preincrement/predecrement. The constructor initializes
+ // _M_ref_count.
+ struct _Refcount_Base
+ {
+ // The type _RC_t
+ typedef size_t _RC_t;
+
+ // The data member _M_ref_count
+ volatile _RC_t _M_ref_count;
+
+ // Constructor
+ __gthread_mutex_t _M_ref_count_lock;
+
+ _Refcount_Base(_RC_t __n) : _M_ref_count(__n)
+ {
+#ifdef __GTHREAD_MUTEX_INIT
+ __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
+ _M_ref_count_lock = __tmp;
+#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+ __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock);
+#else
+#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org.
+#endif
+ }
+
+ void
+ _M_incr()
+ {
+ __gthread_mutex_lock(&_M_ref_count_lock);
+ ++_M_ref_count;
+ __gthread_mutex_unlock(&_M_ref_count_lock);
+ }
+
+ _RC_t
+ _M_decr()
+ {
+ __gthread_mutex_lock(&_M_ref_count_lock);
+ volatile _RC_t __tmp = --_M_ref_count;
+ __gthread_mutex_unlock(&_M_ref_count_lock);
+ return __tmp;
+ }
+ };
+
+ // Atomic swap on unsigned long
+ // This is guaranteed to behave as though it were atomic only if all
+ // possibly concurrent updates use _Atomic_swap.
+ // In some cases the operation is emulated with a lock.
+#if defined (__GTHREAD_MUTEX_INIT)
+ // This could be optimized to use the atomicity.h abstraction layer.
+ // vyzo: simple _Atomic_swap implementation following the guidelines above
+ // We use a template here only to get a unique initialized instance.
+ template<int __dummy>
+ struct _Swap_lock_struct
+ { static __gthread_mutex_t _S_swap_lock; };
+
+ template<int __dummy>
+ __gthread_mutex_t
+ _Swap_lock_struct<__dummy>::_S_swap_lock = __GTHREAD_MUTEX_INIT;
+
+ // This should be portable, but performance is expected to be quite
+ // awful. This really needs platform specific code.
+ inline unsigned long
+ _Atomic_swap(unsigned long * __p, unsigned long __q)
+ {
+ __gthread_mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock);
+ unsigned long __result = *__p;
+ *__p = __q;
+ __gthread_mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock);
+ return __result;
+ }
+#endif
+
+ // Locking class. Note that this class *does not have a
+ // constructor*. It must be initialized either statically, with
+ // __STL_MUTEX_INITIALIZER, or dynamically, by explicitly calling
+ // the _M_initialize member function. (This is similar to the ways
+ // that a pthreads mutex can be initialized.) There are explicit
+ // member functions for acquiring and releasing the lock.
+
+ // There is no constructor because static initialization is
+ // essential for some uses, and only a class aggregate (see section
+ // 8.5.1 of the C++ standard) can be initialized that way. That
+ // means we must have no constructors, no base classes, no virtual
+ // functions, and no private or protected members.
+
+#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+ extern __gthread_mutex_t _GLIBCPP_mutex;
+ extern __gthread_mutex_t *_GLIBCPP_mutex_address;
+ extern __gthread_once_t _GLIBCPP_once;
+ extern void _GLIBCPP_mutex_init (void);
+ extern void _GLIBCPP_mutex_address_init (void);
+#endif
+
+ struct _STL_mutex_lock
+ {
+ // The class must be statically initialized with __STL_MUTEX_INITIALIZER.
+#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+ volatile int _M_init_flag;
+ __gthread_once_t _M_once;
+#endif
+ __gthread_mutex_t _M_lock;
+
+ void
+ _M_initialize()
+ {
+#ifdef __GTHREAD_MUTEX_INIT
+ // There should be no code in this path given the usage rules above.
+#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+ if (_M_init_flag) return;
+ if (__gthread_once (&_GLIBCPP_once, _GLIBCPP_mutex_init) != 0
+ && __gthread_active_p ())
+ abort ();
+ __gthread_mutex_lock (&_GLIBCPP_mutex);
+ if (!_M_init_flag)
+ {
+ // Even though we have a global lock, we use __gthread_once to be
+ // absolutely certain the _M_lock mutex is only initialized once on
+ // multiprocessor systems.
+ _GLIBCPP_mutex_address = &_M_lock;
+ if (__gthread_once (&_M_once, _GLIBCPP_mutex_address_init) != 0
+ && __gthread_active_p ())
+ abort ();
+ _M_init_flag = 1;
+ }
+ __gthread_mutex_unlock (&_GLIBCPP_mutex);
+#endif
+ }
+
+ void
+ _M_acquire_lock()
+ {
+#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+ if (!_M_init_flag) _M_initialize();
+#endif
+ __gthread_mutex_lock(&_M_lock);
+ }
+
+ void
+ _M_release_lock()
+ {
+#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+ if (!_M_init_flag) _M_initialize();
+#endif
+ __gthread_mutex_unlock(&_M_lock);
+ }
+ };
+
+#ifdef __GTHREAD_MUTEX_INIT
+#define __STL_MUTEX_INITIALIZER = { __GTHREAD_MUTEX_INIT }
+#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+#ifdef __GTHREAD_MUTEX_INIT_DEFAULT
+#define __STL_MUTEX_INITIALIZER \
+ = { 0, __GTHREAD_ONCE_INIT, __GTHREAD_MUTEX_INIT_DEFAULT }
+#else
+#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT }
+#endif
+#endif
+
+ // A locking class that uses _STL_mutex_lock. The constructor takes a
+ // reference to an _STL_mutex_lock, and acquires a lock. The
+ // destructor releases the lock. It's not clear that this is exactly
+ // the right functionality. It will probably change in the future.
+ struct _STL_auto_lock
+ {
+ _STL_mutex_lock& _M_lock;
+
+ _STL_auto_lock(_STL_mutex_lock& __lock) : _M_lock(__lock)
+ { _M_lock._M_acquire_lock(); }
+
+ ~_STL_auto_lock() { _M_lock._M_release_lock(); }
+
+ private:
+ void operator=(const _STL_auto_lock&);
+ _STL_auto_lock(const _STL_auto_lock&);
+ };
+
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/stl_tree.h b/contrib/libstdc++/include/bits/stl_tree.h
new file mode 100644
index 0000000000000..d2ae142e9265c
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_tree.h
@@ -0,0 +1,1462 @@
+// RB tree implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ */
+
+/** @file stl_tree.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_TREE_H
+#define __GLIBCPP_INTERNAL_TREE_H
+
+/*
+
+Red-black tree class, designed for use in implementing STL
+associative containers (set, multiset, map, and multimap). The
+insertion and deletion algorithms are based on those in Cormen,
+Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
+except that
+
+(1) the header cell is maintained with links not only to the root
+but also to the leftmost node of the tree, to enable constant time
+begin(), and to the rightmost node of the tree, to enable linear time
+performance when used with the generic set algorithms (set_union,
+etc.);
+
+(2) when a node being deleted has two children its successor node is
+relinked into its place, rather than copied, so that the only
+iterators invalidated are those referring to the deleted node.
+
+*/
+
+#include <bits/stl_algobase.h>
+#include <bits/stl_alloc.h>
+#include <bits/stl_construct.h>
+#include <bits/stl_function.h>
+
+namespace std
+{
+ enum _Rb_tree_color { _M_red = false, _M_black = true };
+
+ 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;
+ }
+
+ static _Base_ptr
+ _S_maximum(_Base_ptr __x)
+ {
+ while (__x->_M_right != 0) __x = __x->_M_right;
+ return __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
+ {
+ 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;
+ }
+
+ _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)
+ {
+ _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 = _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);
+ }
+ }
+ }
+ __root->_M_color = _M_black;
+ }
+
+ inline _Rb_tree_node_base*
+ _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z,
+ _Rb_tree_node_base*& __root,
+ _Rb_tree_node_base*& __leftmost,
+ _Rb_tree_node_base*& __rightmost)
+ {
+ _Rb_tree_node_base* __y = __z;
+ _Rb_tree_node_base* __x = 0;
+ _Rb_tree_node_base* __x_parent = 0;
+ if (__y->_M_left == 0) // __z has at most one non-null child. y == z.
+ __x = __y->_M_right; // __x might be null.
+ else
+ if (__y->_M_right == 0) // __z has exactly one non-null child. y == z.
+ __x = __y->_M_left; // __x is not null.
+ else
+ {
+ // __z has two non-null children. Set __y to
+ __y = __y->_M_right; // __z's successor. __x might be null.
+ while (__y->_M_left != 0)
+ __y = __y->_M_left;
+ __x = __y->_M_right;
+ }
+ if (__y != __z)
+ {
+ // relink y in place of z. y is z's successor
+ __z->_M_left->_M_parent = __y;
+ __y->_M_left = __z->_M_left;
+ if (__y != __z->_M_right)
+ {
+ __x_parent = __y->_M_parent;
+ if (__x) __x->_M_parent = __y->_M_parent;
+ __y->_M_parent->_M_left = __x; // __y must be a child of _M_left
+ __y->_M_right = __z->_M_right;
+ __z->_M_right->_M_parent = __y;
+ }
+ else
+ __x_parent = __y;
+ if (__root == __z)
+ __root = __y;
+ else if (__z->_M_parent->_M_left == __z)
+ __z->_M_parent->_M_left = __y;
+ else
+ __z->_M_parent->_M_right = __y;
+ __y->_M_parent = __z->_M_parent;
+ std::swap(__y->_M_color, __z->_M_color);
+ __y = __z;
+ // __y now points to node to be actually deleted
+ }
+ else
+ { // __y == __z
+ __x_parent = __y->_M_parent;
+ if (__x)
+ __x->_M_parent = __y->_M_parent;
+ if (__root == __z)
+ __root = __x;
+ else
+ if (__z->_M_parent->_M_left == __z)
+ __z->_M_parent->_M_left = __x;
+ else
+ __z->_M_parent->_M_right = __x;
+ if (__leftmost == __z)
+ if (__z->_M_right == 0) // __z->_M_left must be null also
+ __leftmost = __z->_M_parent;
+ // makes __leftmost == _M_header if __z == __root
+ else
+ __leftmost = _Rb_tree_node_base::_S_minimum(__x);
+ if (__rightmost == __z)
+ if (__z->_M_left == 0) // __z->_M_right must be null also
+ __rightmost = __z->_M_parent;
+ // makes __rightmost == _M_header if __z == __root
+ else // __x == __z->_M_left
+ __rightmost = _Rb_tree_node_base::_S_maximum(__x);
+ }
+ if (__y->_M_color != _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;
+ }
+
+ // 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;
+ }
+
+ _Link_type
+ _M_clone_node(_Link_type __x)
+ {
+ _Link_type __tmp = _M_create_node(__x->_M_value_field);
+ __tmp->_M_color = __x->_M_color;
+ __tmp->_M_left = 0;
+ __tmp->_M_right = 0;
+ return __tmp;
+ }
+
+ void
+ destroy_node(_Link_type __p)
+ {
+ _Destroy(&__p->_M_value_field);
+ _M_put_node(__p);
+ }
+
+ 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;
+ }
+
+ ~_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());
+ }
+
+ 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());
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+ }
+
+ 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)
+ {
+ for ( ; __first != __last; ++__first)
+ insert_equal(*__first);
+ }
+
+ 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);
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+ }
+
+ 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++);
+ }
+
+ 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++);
+ }
+
+ 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.
+
+ while (__x != 0)
+ {
+ if (!_M_key_compare(_S_key(__x), __k))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+ }
+ const_iterator __j = const_iterator(__y);
+ return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ?
+ end() : __j;
+ }
+
+ template<typename _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
+ {
+ pair<const_iterator, const_iterator> __p = equal_range(__k);
+ size_type __n = distance(__p.first, __p.second);
+ return __n;
+ }
+
+ 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));
+ }
+
+ 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;
+ }
+
+ 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 == _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 (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
+ return false;
+ return true;
+ }
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/stl_uninitialized.h b/contrib/libstdc++/include/bits/stl_uninitialized.h
new file mode 100644
index 0000000000000..b5f7b8c40b697
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_uninitialized.h
@@ -0,0 +1,290 @@
+// Raw memory manipulators -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_uninitialized.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STL_UNINITIALIZED_H
+#define _CPP_BITS_STL_UNINITIALIZED_H 1
+
+#include <cstring>
+
+namespace std
+{
+
+ // uninitialized_copy
+
+ template<typename _InputIter, typename _ForwardIter>
+ inline _ForwardIter
+ __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
+ _ForwardIter __result,
+ __true_type)
+ { return copy(__first, __last, __result); }
+
+ template<typename _InputIter, typename _ForwardIter>
+ _ForwardIter
+ __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
+ _ForwardIter __result,
+ __false_type)
+ {
+ _ForwardIter __cur = __result;
+ try {
+ for ( ; __first != __last; ++__first, ++__cur)
+ _Construct(&*__cur, *__first);
+ return __cur;
+ }
+ catch(...)
+ {
+ _Destroy(__result, __cur);
+ __throw_exception_again;
+ }
+ }
+
+ /**
+ * @brief Copies the range [first,last) into result.
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param result An output iterator.
+ * @return result + (first - last)
+ *
+ * Like copy(), but does not require an initialized output range.
+ */
+ template<typename _InputIter, typename _ForwardIter>
+ inline _ForwardIter
+ uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result)
+ {
+ 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());
+ }
+
+ inline char*
+ uninitialized_copy(const char* __first, const char* __last, char* __result)
+ {
+ memmove(__result, __first, __last - __first);
+ return __result + (__last - __first);
+ }
+
+ inline wchar_t*
+ uninitialized_copy(const wchar_t* __first, const wchar_t* __last,
+ wchar_t* __result)
+ {
+ memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
+ return __result + (__last - __first);
+ }
+
+ // Valid if copy construction is equivalent to assignment, and if the
+ // destructor is trivial.
+ template<typename _ForwardIter, typename _Tp>
+ inline void
+ __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last,
+ const _Tp& __x, __true_type)
+ { fill(__first, __last, __x); }
+
+ template<typename _ForwardIter, typename _Tp>
+ void
+ __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last,
+ const _Tp& __x, __false_type)
+ {
+ _ForwardIter __cur = __first;
+ try {
+ for ( ; __cur != __last; ++__cur)
+ _Construct(&*__cur, __x);
+ }
+ catch(...)
+ {
+ _Destroy(__first, __cur);
+ __throw_exception_again;
+ }
+ }
+
+ /**
+ * @brief Copies the value x into the range [first,last).
+ * @param first An input iterator.
+ * @param last An input iterator.
+ * @param x The source value.
+ * @return Nothing.
+ *
+ * Like fill(), but does not require an initialized output range.
+ */
+ template<typename _ForwardIter, typename _Tp>
+ inline void
+ uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD;
+ __uninitialized_fill_aux(__first, __last, __x, _Is_POD());
+ }
+
+ // Valid if copy construction is equivalent to assignment, and if the
+ // destructor is trivial.
+ template<typename _ForwardIter, typename _Size, typename _Tp>
+ inline _ForwardIter
+ __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n,
+ const _Tp& __x, __true_type)
+ {
+ return fill_n(__first, __n, __x);
+ }
+
+ template<typename _ForwardIter, typename _Size, typename _Tp>
+ _ForwardIter
+ __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n,
+ const _Tp& __x, __false_type)
+ {
+ _ForwardIter __cur = __first;
+ try {
+ for ( ; __n > 0; --__n, ++__cur)
+ _Construct(&*__cur, __x);
+ return __cur;
+ }
+ catch(...)
+ {
+ _Destroy(__first, __cur);
+ __throw_exception_again;
+ }
+ }
+
+ /**
+ * @brief Copies the value x into the range [first,first+n).
+ * @param first An input iterator.
+ * @param n The number of copies to make.
+ * @param x The source value.
+ * @return first+n
+ *
+ * Like fill_n(), but does not require an initialized output range.
+ */
+ template<typename _ForwardIter, typename _Size, typename _Tp>
+ inline _ForwardIter
+ uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x)
+ {
+ typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
+ typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD;
+ return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD());
+ }
+
+ // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill,
+ // __uninitialized_fill_copy.
+
+ // __uninitialized_copy_copy
+ // Copies [first1, last1) into [result, result + (last1 - first1)), and
+ // copies [first2, last2) into
+ // [result, result + (last1 - first1) + (last2 - first2)).
+
+ template<typename _InputIter1, typename _InputIter2, typename _ForwardIter>
+ inline _ForwardIter
+ __uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1,
+ _InputIter2 __first2, _InputIter2 __last2,
+ _ForwardIter __result)
+ {
+ _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result);
+ try {
+ return uninitialized_copy(__first2, __last2, __mid);
+ }
+ catch(...)
+ {
+ _Destroy(__result, __mid);
+ __throw_exception_again;
+ }
+ }
+
+ // __uninitialized_fill_copy
+ // Fills [result, mid) with x, and copies [first, last) into
+ // [mid, mid + (last - first)).
+ template<typename _ForwardIter, typename _Tp, typename _InputIter>
+ inline _ForwardIter
+ __uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid,
+ const _Tp& __x,
+ _InputIter __first, _InputIter __last)
+ {
+ uninitialized_fill(__result, __mid, __x);
+ try {
+ return uninitialized_copy(__first, __last, __mid);
+ }
+ catch(...)
+ {
+ _Destroy(__result, __mid);
+ __throw_exception_again;
+ }
+ }
+
+ // __uninitialized_copy_fill
+ // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
+ // fills [first2 + (last1 - first1), last2) with x.
+ template<typename _InputIter, typename _ForwardIter, typename _Tp>
+ inline void
+ __uninitialized_copy_fill(_InputIter __first1, _InputIter __last1,
+ _ForwardIter __first2, _ForwardIter __last2,
+ const _Tp& __x)
+ {
+ _ForwardIter __mid2 = uninitialized_copy(__first1, __last1, __first2);
+ try {
+ uninitialized_fill(__mid2, __last2, __x);
+ }
+ catch(...)
+ {
+ _Destroy(__first2, __mid2);
+ __throw_exception_again;
+ }
+ }
+
+} // namespace std
+
+#endif /* _CPP_BITS_STL_UNINITIALIZED_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stl_vector.h b/contrib/libstdc++/include/bits/stl_vector.h
new file mode 100644
index 0000000000000..5e2ea54d9135d
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stl_vector.h
@@ -0,0 +1,1083 @@
+// Vector implementation -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file stl_vector.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GLIBCPP_INTERNAL_VECTOR_H
+#define __GLIBCPP_INTERNAL_VECTOR_H
+
+#include <bits/stl_iterator_base_funcs.h>
+#include <bits/functexcept.h>
+#include <bits/concept_check.h>
+
+namespace std
+{
+
+// The vector base class serves two purposes. First, its constructor
+// and destructor allocate (but don't initialize) storage. This makes
+// exception safety easier. Second, the base class encapsulates all of
+// the differences between SGI-style allocators and standard-conforming
+// allocators.
+
+// Base class for ordinary allocators.
+template <class _Tp, class _Allocator, bool _IsStatic>
+class _Vector_alloc_base {
+public:
+ typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+ allocator_type;
+ allocator_type get_allocator() const { return _M_data_allocator; }
+
+ _Vector_alloc_base(const allocator_type& __a)
+ : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
+ {}
+
+protected:
+ allocator_type _M_data_allocator;
+ _Tp* _M_start;
+ _Tp* _M_finish;
+ _Tp* _M_end_of_storage;
+
+ _Tp* _M_allocate(size_t __n)
+ { return _M_data_allocator.allocate(__n); }
+ void _M_deallocate(_Tp* __p, size_t __n)
+ { if (__p) _M_data_allocator.deallocate(__p, __n); }
+};
+
+// Specialization for allocators that have the property that we don't
+// actually have to store an allocator object.
+template <class _Tp, class _Allocator>
+class _Vector_alloc_base<_Tp, _Allocator, true> {
+public:
+ typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+ allocator_type;
+ allocator_type get_allocator() const { return allocator_type(); }
+
+ _Vector_alloc_base(const allocator_type&)
+ : _M_start(0), _M_finish(0), _M_end_of_storage(0)
+ {}
+
+protected:
+ _Tp* _M_start;
+ _Tp* _M_finish;
+ _Tp* _M_end_of_storage;
+
+ typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
+ _Tp* _M_allocate(size_t __n)
+ { return _Alloc_type::allocate(__n); }
+ void _M_deallocate(_Tp* __p, size_t __n)
+ { _Alloc_type::deallocate(__p, __n);}
+};
+
+template <class _Tp, class _Alloc>
+struct _Vector_base
+ : public _Vector_alloc_base<_Tp, _Alloc,
+ _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+{
+ typedef _Vector_alloc_base<_Tp, _Alloc,
+ _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+ _Base;
+ typedef typename _Base::allocator_type allocator_type;
+
+ _Vector_base(const allocator_type& __a) : _Base(__a) {}
+ _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
+ _M_start = _M_allocate(__n);
+ _M_finish = _M_start;
+ _M_end_of_storage = _M_start + __n;
+ }
+
+ ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
+};
+
+
+/**
+ * @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.
+ * Subscripting ( [] ) access is also provided as with C-style arrays.
+*/
+template <class _Tp, class _Alloc = allocator<_Tp> >
+class vector : protected _Vector_base<_Tp, _Alloc>
+{
+ // concept requirements
+ __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+
+private:
+ typedef _Vector_base<_Tp, _Alloc> _Base;
+ typedef vector<_Tp, _Alloc> vector_type;
+public:
+ typedef _Tp value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ 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;
+ typedef ptrdiff_t difference_type;
+
+ typedef typename _Base::allocator_type allocator_type;
+ allocator_type get_allocator() const { return _Base::get_allocator(); }
+
+ typedef reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef reverse_iterator<iterator> reverse_iterator;
+
+protected:
+ using _Base::_M_allocate;
+ using _Base::_M_deallocate;
+ using _Base::_M_start;
+ using _Base::_M_finish;
+ using _Base::_M_end_of_storage;
+
+protected:
+ void _M_insert_aux(iterator __position, const _Tp& __x);
+ void _M_insert_aux(iterator __position);
+
+public:
+ /**
+ * Returns a read/write iterator that points to the first element in the
+ * vector. Iteration is done in ordinary element order.
+ */
+ iterator begin() { return iterator (_M_start); }
+
+ /**
+ * Returns a read-only (constant) iterator that points to the first element
+ * in the vector. Iteration is done in ordinary element order.
+ */
+ const_iterator begin() const
+ { return const_iterator (_M_start); }
+
+ /**
+ * Returns a read/write iterator that points one past the last element in
+ * the vector. Iteration is done in ordinary element order.
+ */
+ iterator end() { return iterator (_M_finish); }
+
+ /**
+ * Returns a read-only (constant) iterator that points one past the last
+ * element in the vector. Iteration is done in ordinary element order.
+ */
+ const_iterator end() const { return const_iterator (_M_finish); }
+
+ /**
+ * Returns a read/write reverse iterator that points to the last element in
+ * the vector. Iteration is done in reverse element order.
+ */
+ reverse_iterator rbegin()
+ { return reverse_iterator(end()); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to the last
+ * element in the vector. Iteration is done in reverse element order.
+ */
+ const_reverse_iterator rbegin() const
+ { return const_reverse_iterator(end()); }
+
+ /**
+ * Returns a read/write reverse iterator that points to one before the
+ * first element in the vector. Iteration is done in reverse element
+ * order.
+ */
+ reverse_iterator rend()
+ { return reverse_iterator(begin()); }
+
+ /**
+ * Returns a read-only (constant) reverse iterator that points to one
+ * before the first element in the vector. Iteration is done in reverse
+ * element order.
+ */
+ const_reverse_iterator rend() const
+ { return const_reverse_iterator(begin()); }
+
+ /** Returns the number of elements in the vector. */
+ size_type size() const
+ { return size_type(end() - begin()); }
+
+ /** Returns the size of the largest possible vector. */
+ size_type max_size() const
+ { return size_type(-1) / sizeof(_Tp); }
+
+ /**
+ * Returns the amount of memory that has been alocated for the current
+ * elements (?).
+ */
+ size_type capacity() const
+ { return size_type(const_iterator(_M_end_of_storage) - begin()); }
+
+ /**
+ * Returns true if the vector is empty. (Thus begin() would equal end().)
+ */
+ bool empty() const
+ { return begin() == end(); }
+
+ /**
+ * @brief Subscript access to the data contained in the vector.
+ * @param n The element for which data should be accessed.
+ * @return Read/write reference to data.
+ *
+ * This operator allows for easy, array-style, data access.
+ * Note that data access with this operator is unchecked and out_of_range
+ * lookups are not defined. (For checked lookups see at().)
+ */
+ reference operator[](size_type __n) { return *(begin() + __n); }
+
+ /**
+ * @brief Subscript access to the data contained in the vector.
+ * @param n The element for which data should be accessed.
+ * @return Read-only (constant) reference to data.
+ *
+ * This operator allows for easy, array-style, data access.
+ * Note that data access with this operator is unchecked and out_of_range
+ * lookups are not defined. (For checked lookups see at().)
+ */
+ const_reference operator[](size_type __n) const { return *(begin() + __n); }
+
+ void _M_range_check(size_type __n) const {
+ if (__n >= this->size())
+ __throw_out_of_range("vector");
+ }
+
+ /**
+ * @brief Provides access to the data contained in the vector.
+ * @param n The element for which data should be accessed.
+ * @return Read/write reference to data.
+ *
+ * This function provides for safer data access. The parameter is first
+ * checked that it is in the range of the vector. The function throws
+ * out_of_range if the check fails.
+ */
+ reference at(size_type __n)
+ { _M_range_check(__n); return (*this)[__n]; }
+
+ /**
+ * @brief Provides access to the data contained in the vector.
+ * @param n The element for which data should be accessed.
+ * @return Read-only (constant) reference to data.
+ *
+ * This function provides for safer data access. The parameter is first
+ * checked that it is in the range of the vector. The function throws
+ * out_of_range if the check fails.
+ */
+ const_reference at(size_type __n) const
+ { _M_range_check(__n); return (*this)[__n]; }
+
+
+ explicit vector(const allocator_type& __a = allocator_type())
+ : _Base(__a) {}
+
+ vector(size_type __n, const _Tp& __value,
+ const allocator_type& __a = allocator_type())
+ : _Base(__n, __a)
+ { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
+
+ explicit vector(size_type __n)
+ : _Base(__n, allocator_type())
+ { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }
+
+ vector(const vector<_Tp, _Alloc>& __x)
+ : _Base(__x.size(), __x.get_allocator())
+ { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+ template <class _InputIterator>
+ vector(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_initialize_aux(__first, __last, _Integral());
+ }
+
+ template <class _Integer>
+ void _M_initialize_aux(_Integer __n, _Integer __value, __true_type)
+ {
+ _M_start = _M_allocate(__n);
+ _M_end_of_storage = _M_start + __n;
+ _M_finish = uninitialized_fill_n(_M_start, __n, __value);
+ }
+
+ template<class _InputIterator>
+ void
+ _M_initialize_aux(_InputIterator __first, _InputIterator __last, __false_type)
+ {
+ typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
+ _M_range_initialize(__first, __last, _IterCategory());
+ }
+
+ ~vector()
+ { _Destroy(_M_start, _M_finish); }
+
+ vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
+
+ /**
+ * @brief Attempt to preallocate enough memory for specified number of
+ * elements.
+ * @param n Number of elements required
+ *
+ * This function attempts to reserve enough memory for the vector to hold
+ * the specified number of elements. If the number requested is more than
+ * max_size() length_error is thrown.
+ *
+ * The advantage of this function is that if optimal code is a necessity
+ * and the user can determine the number of elements that will be required
+ * the user can reserve the memory and thus prevent a possible
+ * reallocation of memory and copy of vector data.
+ */
+ void reserve(size_type __n) {
+ if (capacity() < __n) {
+ const size_type __old_size = size();
+ pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
+ _Destroy(_M_start, _M_finish);
+ _M_deallocate(_M_start, _M_end_of_storage - _M_start);
+ _M_start = __tmp;
+ _M_finish = __tmp + __old_size;
+ _M_end_of_storage = _M_start + __n;
+ }
+ }
+
+ // assign(), a generalized assignment member function. Two
+ // versions: one that takes a count, and one that takes a range.
+ // The range version is a member template, so we dispatch on whether
+ // or not the type is an integer.
+
+ /**
+ * @brief Assigns a given value or range to a vector.
+ * @param n Number of elements to be assigned.
+ * @param val Value to be assigned.
+ *
+ * This function can be used to assign a range to a vector or fill it
+ * with a specified number of copies of the given value.
+ * Note that the assignment completely changes the vector and that the
+ * resulting vector's size is the same as the number of elements assigned.
+ * Old data may be lost.
+ */
+ void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
+ void _M_fill_assign(size_type __n, const _Tp& __val);
+
+ template<class _InputIterator>
+ void
+ 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); }
+
+ template<class _InputIter>
+ void
+ _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
+ {
+ 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);
+
+ template <class _ForwardIterator>
+ 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
+ * vector.
+ */
+ reference front() { return *begin(); }
+
+ /**
+ * Returns a read-only (constant) reference to the data at the first
+ * element of the vector.
+ */
+ const_reference front() const { return *begin(); }
+
+ /**
+ * Returns a read/write reference to the data at the last element of the
+ * vector.
+ */
+ reference back() { return *(end() - 1); }
+
+ /**
+ * Returns a read-only (constant) reference to the data at the first
+ * element of the vector.
+ */
+ const_reference back() const { return *(end() - 1); }
+
+ /**
+ * @brief Add data to the end of the vector.
+ * @param x Data to be added.
+ *
+ * This is a typical stack operation. The function creates an element at
+ * the end of the vector and assigns the given data to it.
+ * Due to the nature of a vector this operation can be done in constant
+ * time if the vector has preallocated space available.
+ */
+ void
+ push_back(const _Tp& __x)
+ {
+ if (_M_finish != _M_end_of_storage) {
+ _Construct(_M_finish, __x);
+ ++_M_finish;
+ }
+ else
+ _M_insert_aux(end(), __x);
+ }
+
+#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()
+ {
+ if (_M_finish != _M_end_of_storage) {
+ _Construct(_M_finish);
+ ++_M_finish;
+ }
+ else
+ _M_insert_aux(end());
+ }
+#endif
+
+ void
+ swap(vector<_Tp, _Alloc>& __x)
+ {
+ std::swap(_M_start, __x._M_start);
+ std::swap(_M_finish, __x._M_finish);
+ std::swap(_M_end_of_storage, __x._M_end_of_storage);
+ }
+
+ /**
+ * @brief Inserts given value into vector at specified element.
+ * @param position An iterator that points to the element where data
+ * should be inserted.
+ * @param x Data to be inserted.
+ * @return An iterator that points to the inserted data.
+ *
+ * This function will insert the given value into the specified location.
+ * Note that this kind of operation could be expensive for a vector and if
+ * it is frequently used the user should consider using std::list.
+ */
+ iterator
+ insert(iterator __position, const _Tp& __x)
+ {
+ size_type __n = __position - begin();
+ if (_M_finish != _M_end_of_storage && __position == end()) {
+ _Construct(_M_finish, __x);
+ ++_M_finish;
+ }
+ else
+ _M_insert_aux(iterator(__position), __x);
+ return begin() + __n;
+ }
+
+ /**
+ * @brief Inserts an empty element into the vector.
+ * @param position An iterator that points to the element where empty
+ * element should be inserted.
+ * @param x Data to be inserted.
+ * @return An iterator that points to the inserted element.
+ *
+ * This function will insert an empty element into the specified location.
+ * Note that this kind of operation could be expensive for a vector and if
+ * it is frequently used the user should consider using std::list.
+ */
+ iterator
+ insert(iterator __position)
+ {
+ size_type __n = __position - begin();
+ if (_M_finish != _M_end_of_storage && __position == end()) {
+ _Construct(_M_finish);
+ ++_M_finish;
+ }
+ else
+ _M_insert_aux(iterator(__position));
+ return begin() + __n;
+ }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+ template<class _InputIterator>
+ void
+ insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+ {
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ _M_insert_dispatch(__pos, __first, __last, _Integral());
+ }
+
+ template <class _Integer>
+ void
+ _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type)
+ { _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<_Tp>(__val)); }
+
+ template<class _InputIterator>
+ void
+ _M_insert_dispatch(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ __false_type)
+ {
+ typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
+ _M_range_insert(__pos, __first, __last, _IterCategory());
+ }
+
+ /**
+ * @brief Inserts a number of copies of given data into the vector.
+ * @param position An iterator that points to the element where data
+ * should be inserted.
+ * @param n Amount of elements to be inserted.
+ * @param x Data to be inserted.
+ *
+ * This function will insert a specified number of copies of the given data
+ * into the specified location.
+ *
+ * Note that this kind of operation could be expensive for a vector and if
+ * it is frequently used the user should consider using std::list.
+ */
+ void insert (iterator __pos, size_type __n, const _Tp& __x)
+ { _M_fill_insert(__pos, __n, __x); }
+
+ void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
+
+ /**
+ * @brief Removes last element from vector.
+ *
+ * This is a typical stack operation. It allows us to shrink the vector by
+ * one.
+ *
+ * Note that no data is returned and if last element's data is needed it
+ * should be retrieved before pop_back() is called.
+ */
+ void pop_back() {
+ --_M_finish;
+ _Destroy(_M_finish);
+ }
+
+ /**
+ * @brief Remove element at given position
+ * @param position Iterator pointing to element to be erased.
+ * @return Doc Me! (Iterator pointing to new element at old location?)
+ *
+ * This function will erase the element at the given position and thus
+ * shorten the vector by one.
+ *
+ * Note This operation could be expensive and if it is frequently used the
+ * user should consider using std::list. The user is also cautioned that
+ * this function only erases the element, and that if the element is itself
+ * a pointer, the pointed-to memory is not touched in any way. Managing
+ * the pointer is the user's responsibilty.
+ */
+ iterator erase(iterator __position) {
+ if (__position + 1 != end())
+ copy(__position + 1, end(), __position);
+ --_M_finish;
+ _Destroy(_M_finish);
+ return __position;
+ }
+
+ /**
+ * @brief Remove a range of elements from a vector.
+ * @param first Iterator pointing to the first element to be erased.
+ * @param last Iterator pointing to the last element to be erased.
+ * @return Doc Me! (Iterator pointing to new element at old location?)
+ *
+ * This function will erase the elements in the given range and shorten the
+ * vector accordingly.
+ *
+ * Note This operation could be expensive and if it is frequently used the
+ * user should consider using std::list. The user is also cautioned that
+ * this function only erases the elements, and that if the elements
+ * themselves are pointers, the pointed-to memory is not touched in any
+ * way. Managing the pointer is the user's responsibilty.
+ */
+ iterator erase(iterator __first, iterator __last) {
+ iterator __i(copy(__last, end(), __first));
+ _Destroy(__i, end());
+ _M_finish = _M_finish - (__last - __first);
+ return __first;
+ }
+
+ /**
+ * @brief Resizes the vector to the specified number of elements.
+ * @param new_size Number of elements the vector should contain.
+ * @param x Data with which new elements should be populated.
+ *
+ * This function will resize the vector to the specified number of
+ * elements. If the number is smaller than the vector's current size the
+ * vector is truncated, otherwise the vector is extended and new elements
+ * are populated with given data.
+ */
+ void resize(size_type __new_size, const _Tp& __x) {
+ if (__new_size < size())
+ erase(begin() + __new_size, end());
+ else
+ insert(end(), __new_size - size(), __x);
+ }
+
+ /**
+ * @brief Resizes the vector to the specified number of elements.
+ * @param new_size Number of elements the vector should contain.
+ *
+ * This function will resize the vector to the specified number of
+ * elements. If the number is smaller than the vector's current size the
+ * vector is truncated, otherwise the vector is extended and new elements
+ * are left uninitialized.
+ */
+ void resize(size_type __new_size) { resize(__new_size, _Tp()); }
+
+ /**
+ * Erases all elements in vector. Note that this function only erases the
+ * elements, and that if the elements themselves are pointers, the
+ * pointed-to memory is not touched in any way. Managing the pointer is
+ * the user's responsibilty.
+ */
+ void clear() { erase(begin(), end()); }
+
+protected:
+
+ template <class _ForwardIterator>
+ pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ pointer __result = _M_allocate(__n);
+ try {
+ uninitialized_copy(__first, __last, __result);
+ return __result;
+ }
+ catch(...)
+ {
+ _M_deallocate(__result, __n);
+ __throw_exception_again;
+ }
+ }
+
+ template <class _InputIterator>
+ void _M_range_initialize(_InputIterator __first,
+ _InputIterator __last, input_iterator_tag)
+ {
+ for ( ; __first != __last; ++__first)
+ push_back(*__first);
+ }
+
+ // This function is only called by the constructor.
+ template <class _ForwardIterator>
+ void _M_range_initialize(_ForwardIterator __first,
+ _ForwardIterator __last, forward_iterator_tag)
+ {
+ size_type __n = distance(__first, __last);
+ _M_start = _M_allocate(__n);
+ _M_end_of_storage = _M_start + __n;
+ _M_finish = uninitialized_copy(__first, __last, _M_start);
+ }
+
+ template <class _InputIterator>
+ void _M_range_insert(iterator __pos,
+ _InputIterator __first, _InputIterator __last,
+ input_iterator_tag);
+
+ template <class _ForwardIterator>
+ void _M_range_insert(iterator __pos,
+ _ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag);
+};
+
+template <class _Tp, class _Alloc>
+inline bool
+operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
+{
+ return __x.size() == __y.size() &&
+ equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp, class _Alloc>
+inline bool
+operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
+{
+ return lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end());
+}
+
+template <class _Tp, class _Alloc>
+inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
+{
+ __x.swap(__y);
+}
+
+template <class _Tp, class _Alloc>
+inline bool
+operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
+ return !(__x == __y);
+}
+
+template <class _Tp, class _Alloc>
+inline bool
+operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
+ return __y < __x;
+}
+
+template <class _Tp, class _Alloc>
+inline bool
+operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
+ return !(__y < __x);
+}
+
+template <class _Tp, class _Alloc>
+inline bool
+operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
+ return !(__x < __y);
+}
+
+template <class _Tp, class _Alloc>
+vector<_Tp,_Alloc>&
+vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
+{
+ if (&__x != this) {
+ const size_type __xlen = __x.size();
+ if (__xlen > capacity()) {
+ pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
+ _Destroy(_M_start, _M_finish);
+ _M_deallocate(_M_start, _M_end_of_storage - _M_start);
+ _M_start = __tmp;
+ _M_end_of_storage = _M_start + __xlen;
+ }
+ else if (size() >= __xlen) {
+ iterator __i(copy(__x.begin(), __x.end(), begin()));
+ _Destroy(__i, end());
+ }
+ else {
+ copy(__x.begin(), __x.begin() + size(), _M_start);
+ uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
+ }
+ _M_finish = _M_start + __xlen;
+ }
+ return *this;
+}
+
+template <class _Tp, class _Alloc>
+void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val)
+{
+ if (__n > capacity()) {
+ vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
+ __tmp.swap(*this);
+ }
+ else if (__n > size()) {
+ fill(begin(), end(), __val);
+ _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
+ }
+ else
+ erase(fill_n(begin(), __n, __val), end());
+}
+
+template <class _Tp, class _Alloc> template <class _InputIter>
+void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
+ input_iterator_tag) {
+ iterator __cur(begin());
+ for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
+ *__cur = *__first;
+ if (__first == __last)
+ erase(__cur, end());
+ else
+ insert(end(), __first, __last);
+}
+
+template <class _Tp, class _Alloc> template <class _ForwardIter>
+void
+vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
+ forward_iterator_tag) {
+ size_type __len = distance(__first, __last);
+
+ if (__len > capacity()) {
+ pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
+ _Destroy(_M_start, _M_finish);
+ _M_deallocate(_M_start, _M_end_of_storage - _M_start);
+ _M_start = __tmp;
+ _M_end_of_storage = _M_finish = _M_start + __len;
+ }
+ else if (size() >= __len) {
+ iterator __new_finish(copy(__first, __last, _M_start));
+ _Destroy(__new_finish, end());
+ _M_finish = __new_finish.base();
+ }
+ else {
+ _ForwardIter __mid = __first;
+ advance(__mid, size());
+ copy(__first, __mid, _M_start);
+ _M_finish = uninitialized_copy(__mid, __last, _M_finish);
+ }
+}
+
+template <class _Tp, class _Alloc>
+void
+vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
+{
+ if (_M_finish != _M_end_of_storage) {
+ _Construct(_M_finish, *(_M_finish - 1));
+ ++_M_finish;
+ _Tp __x_copy = __x;
+ copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
+ *__position = __x_copy;
+ }
+ else {
+ const size_type __old_size = size();
+ const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
+ iterator __new_start(_M_allocate(__len));
+ iterator __new_finish(__new_start);
+ try {
+ __new_finish = uninitialized_copy(iterator(_M_start), __position,
+ __new_start);
+ _Construct(__new_finish.base(), __x);
+ ++__new_finish;
+ __new_finish = uninitialized_copy(__position, iterator(_M_finish),
+ __new_finish);
+ }
+ catch(...)
+ {
+ _Destroy(__new_start,__new_finish);
+ _M_deallocate(__new_start.base(),__len);
+ __throw_exception_again;
+ }
+ _Destroy(begin(), end());
+ _M_deallocate(_M_start, _M_end_of_storage - _M_start);
+ _M_start = __new_start.base();
+ _M_finish = __new_finish.base();
+ _M_end_of_storage = __new_start.base() + __len;
+ }
+}
+
+template <class _Tp, class _Alloc>
+void
+vector<_Tp, _Alloc>::_M_insert_aux(iterator __position)
+{
+ if (_M_finish != _M_end_of_storage) {
+ _Construct(_M_finish, *(_M_finish - 1));
+ ++_M_finish;
+ copy_backward(__position, iterator(_M_finish - 2),
+ iterator(_M_finish - 1));
+ *__position = _Tp();
+ }
+ else {
+ const size_type __old_size = size();
+ const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
+ pointer __new_start = _M_allocate(__len);
+ pointer __new_finish = __new_start;
+ try {
+ __new_finish = uninitialized_copy(iterator(_M_start), __position,
+ __new_start);
+ _Construct(__new_finish);
+ ++__new_finish;
+ __new_finish = uninitialized_copy(__position, iterator(_M_finish),
+ __new_finish);
+ }
+ catch(...)
+ {
+ _Destroy(__new_start,__new_finish);
+ _M_deallocate(__new_start,__len);
+ __throw_exception_again;
+ }
+ _Destroy(begin(), end());
+ _M_deallocate(_M_start, _M_end_of_storage - _M_start);
+ _M_start = __new_start;
+ _M_finish = __new_finish;
+ _M_end_of_storage = __new_start + __len;
+ }
+}
+
+template <class _Tp, class _Alloc>
+void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
+ const _Tp& __x)
+{
+ if (__n != 0) {
+ if (size_type(_M_end_of_storage - _M_finish) >= __n) {
+ _Tp __x_copy = __x;
+ const size_type __elems_after = end() - __position;
+ iterator __old_finish(_M_finish);
+ if (__elems_after > __n) {
+ uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
+ _M_finish += __n;
+ copy_backward(__position, __old_finish - __n, __old_finish);
+ fill(__position, __position + __n, __x_copy);
+ }
+ else {
+ uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
+ _M_finish += __n - __elems_after;
+ uninitialized_copy(__position, __old_finish, _M_finish);
+ _M_finish += __elems_after;
+ fill(__position, __old_finish, __x_copy);
+ }
+ }
+ else {
+ const size_type __old_size = size();
+ const size_type __len = __old_size + max(__old_size, __n);
+ iterator __new_start(_M_allocate(__len));
+ iterator __new_finish(__new_start);
+ try {
+ __new_finish = uninitialized_copy(begin(), __position, __new_start);
+ __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
+ __new_finish
+ = uninitialized_copy(__position, end(), __new_finish);
+ }
+ catch(...)
+ {
+ _Destroy(__new_start,__new_finish);
+ _M_deallocate(__new_start.base(),__len);
+ __throw_exception_again;
+ }
+ _Destroy(_M_start, _M_finish);
+ _M_deallocate(_M_start, _M_end_of_storage - _M_start);
+ _M_start = __new_start.base();
+ _M_finish = __new_finish.base();
+ _M_end_of_storage = __new_start.base() + __len;
+ }
+ }
+}
+
+template <class _Tp, class _Alloc> template <class _InputIterator>
+void
+vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
+ _InputIterator __first,
+ _InputIterator __last,
+ input_iterator_tag)
+{
+ for ( ; __first != __last; ++__first) {
+ __pos = insert(__pos, *__first);
+ ++__pos;
+ }
+}
+
+template <class _Tp, class _Alloc> template <class _ForwardIterator>
+void
+vector<_Tp, _Alloc>::_M_range_insert(iterator __position,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ forward_iterator_tag)
+{
+ if (__first != __last) {
+ size_type __n = distance(__first, __last);
+ if (size_type(_M_end_of_storage - _M_finish) >= __n) {
+ const size_type __elems_after = end() - __position;
+ iterator __old_finish(_M_finish);
+ if (__elems_after > __n) {
+ uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
+ _M_finish += __n;
+ copy_backward(__position, __old_finish - __n, __old_finish);
+ copy(__first, __last, __position);
+ }
+ else {
+ _ForwardIterator __mid = __first;
+ advance(__mid, __elems_after);
+ uninitialized_copy(__mid, __last, _M_finish);
+ _M_finish += __n - __elems_after;
+ uninitialized_copy(__position, __old_finish, _M_finish);
+ _M_finish += __elems_after;
+ copy(__first, __mid, __position);
+ }
+ }
+ else {
+ const size_type __old_size = size();
+ const size_type __len = __old_size + max(__old_size, __n);
+ iterator __new_start(_M_allocate(__len));
+ iterator __new_finish(__new_start);
+ try {
+ __new_finish = uninitialized_copy(iterator(_M_start),
+ __position, __new_start);
+ __new_finish = uninitialized_copy(__first, __last, __new_finish);
+ __new_finish
+ = uninitialized_copy(__position, iterator(_M_finish), __new_finish);
+ }
+ catch(...)
+ {
+ _Destroy(__new_start,__new_finish);
+ _M_deallocate(__new_start.base(), __len);
+ __throw_exception_again;
+ }
+ _Destroy(_M_start, _M_finish);
+ _M_deallocate(_M_start, _M_end_of_storage - _M_start);
+ _M_start = __new_start.base();
+ _M_finish = __new_finish.base();
+ _M_end_of_storage = __new_start.base() + __len;
+ }
+ }
+}
+
+} // namespace std
+
+#endif /* __GLIBCPP_INTERNAL_VECTOR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/stream_iterator.h b/contrib/libstdc++/include/bits/stream_iterator.h
new file mode 100644
index 0000000000000..4897fc36fefb4
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stream_iterator.h
@@ -0,0 +1,156 @@
+// Stream iterators
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file stream_iterator.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STREAM_ITERATOR_H
+#define _CPP_BITS_STREAM_ITERATOR_H 1
+
+#pragma GCC system_header
+
+namespace std
+{
+ template<typename _Tp, typename _CharT = char,
+ typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
+ class istream_iterator
+ : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
+ {
+ public:
+ typedef _CharT char_type;
+ typedef _Traits traits_type;
+ typedef basic_istream<_CharT, _Traits> istream_type;
+
+ private:
+ istream_type* _M_stream;
+ _Tp _M_value;
+ bool _M_ok;
+
+ public:
+ istream_iterator() : _M_stream(0), _M_ok(false) {}
+
+ istream_iterator(istream_type& __s) : _M_stream(&__s) { _M_read(); }
+
+ istream_iterator(const istream_iterator& __obj)
+ : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
+ _M_ok(__obj._M_ok)
+ { }
+
+ const _Tp&
+ operator*() const { return _M_value; }
+
+ const _Tp*
+ operator->() const { return &(operator*()); }
+
+ istream_iterator&
+ operator++()
+ { _M_read(); return *this; }
+
+ istream_iterator
+ operator++(int)
+ {
+ istream_iterator __tmp = *this;
+ _M_read();
+ return __tmp;
+ }
+
+ bool
+ _M_equal(const istream_iterator& __x) const
+ { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream);}
+
+ private:
+ void
+ _M_read()
+ {
+ _M_ok = (_M_stream && *_M_stream) ? true : false;
+ if (_M_ok)
+ {
+ *_M_stream >> _M_value;
+ _M_ok = *_M_stream ? true : false;
+ }
+ }
+ };
+
+ template<typename _Tp, typename _CharT, typename _Traits, typename _Dist>
+ inline bool
+ operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
+ const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
+ { return __x._M_equal(__y); }
+
+ template <class _Tp, class _CharT, class _Traits, class _Dist>
+ inline bool
+ operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
+ const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
+ { return !__x._M_equal(__y); }
+
+
+ template<typename _Tp, typename _CharT = char,
+ typename _Traits = char_traits<_CharT> >
+ class ostream_iterator
+ : public iterator<output_iterator_tag, void, void, void, void>
+ {
+ public:
+ typedef _CharT char_type;
+ typedef _Traits traits_type;
+ typedef basic_ostream<_CharT, _Traits> ostream_type;
+
+ private:
+ ostream_type* _M_stream;
+ const _CharT* _M_string;
+
+ public:
+ ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
+
+ ostream_iterator(ostream_type& __s, const _CharT* __c)
+ : _M_stream(&__s), _M_string(__c) { }
+
+ ostream_iterator(const ostream_iterator& __obj)
+ : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { }
+
+ ostream_iterator&
+ operator=(const _Tp& __value)
+ {
+ *_M_stream << __value;
+ if (_M_string) *_M_stream << _M_string;
+ return *this;
+ }
+
+ ostream_iterator&
+ operator*() { return *this; }
+
+ ostream_iterator&
+ operator++() { return *this; }
+
+ ostream_iterator&
+ operator++(int) { return *this; }
+ };
+} // namespace std
+#endif
diff --git a/contrib/libstdc++/include/bits/streambuf.tcc b/contrib/libstdc++/include/bits/streambuf.tcc
new file mode 100644
index 0000000000000..292999cfba318
--- /dev/null
+++ b/contrib/libstdc++/include/bits/streambuf.tcc
@@ -0,0 +1,250 @@
+// Stream buffer classes -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.5 Stream buffers
+//
+
+#ifndef _CPP_BITS_STREAMBUF_TCC
+#define _CPP_BITS_STREAMBUF_TCC 1
+
+#pragma GCC system_header
+
+namespace std
+{
+ template<typename _CharT, typename _Traits>
+ const typename basic_streambuf<_CharT, _Traits>::int_type
+ basic_streambuf<_CharT, _Traits>::_S_pback_size;
+
+ template<typename _CharT, typename _Traits>
+ typename basic_streambuf<_CharT, _Traits>::int_type
+ basic_streambuf<_CharT, _Traits>::
+ sbumpc()
+ {
+ int_type __ret;
+ if (_M_in_cur && _M_in_cur < _M_in_end)
+ {
+ char_type __c = *(this->gptr());
+ _M_in_cur_move(1);
+ __ret = traits_type::to_int_type(__c);
+ }
+ else
+ __ret = this->uflow();
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_streambuf<_CharT, _Traits>::int_type
+ basic_streambuf<_CharT, _Traits>::
+ sputbackc(char_type __c)
+ {
+ int_type __ret;
+ 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));
+ else
+ {
+ _M_in_cur_move(-1);
+ __ret = traits_type::to_int_type(*this->gptr());
+ }
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_streambuf<_CharT, _Traits>::int_type
+ basic_streambuf<_CharT, _Traits>::
+ sungetc()
+ {
+ int_type __ret;
+ if (_M_in_cur && _M_in_beg < _M_in_cur)
+ {
+ _M_in_cur_move(-1);
+ __ret = traits_type::to_int_type(*_M_in_cur);
+ }
+ else
+ __ret = this->pbackfail();
+ return __ret;
+ }
+
+ // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
+ // allocated space, and on certain (rare but entirely legal)
+ // situations, there will be no allocated space yet the internal
+ // buffers will still be valid. (This happens if setp is used to set
+ // the internal buffer to say some externally-allocated sequence.)
+ template<typename _CharT, typename _Traits>
+ typename basic_streambuf<_CharT, _Traits>::int_type
+ basic_streambuf<_CharT, _Traits>::
+ sputc(char_type __c)
+ {
+ int_type __ret;
+ if (_M_out_buf_size())
+ {
+ *_M_out_cur = __c;
+ _M_out_cur_move(1);
+ __ret = traits_type::to_int_type(__c);
+ }
+ else
+ __ret = this->overflow(traits_type::to_int_type(__c));
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ streamsize
+ basic_streambuf<_CharT, _Traits>::
+ xsgetn(char_type* __s, streamsize __n)
+ {
+ streamsize __ret = 0;
+ while (__ret < __n)
+ {
+ size_t __buf_len = _M_in_end - _M_in_cur;
+ if (__buf_len > 0)
+ {
+ size_t __remaining = __n - __ret;
+ size_t __len = min(__buf_len, __remaining);
+ traits_type::copy(__s, _M_in_cur, __len);
+ __ret += __len;
+ __s += __len;
+ _M_in_cur_move(__len);
+ }
+
+ if (__ret < __n)
+ {
+ int_type __c = this->uflow();
+ if (__c != traits_type::eof())
+ {
+ traits_type::assign(*__s++, traits_type::to_char_type(__c));
+ ++__ret;
+ }
+ else
+ break;
+ }
+ }
+ return __ret;
+ }
+
+ // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
+ // allocated space, and on certain (rare but entirely legal)
+ // situations, there will be no allocated space yet the internal
+ // buffers will still be valid. (This happens if setp is used to set
+ // the internal buffer to say some externally-allocated sequence.)
+ template<typename _CharT, typename _Traits>
+ streamsize
+ basic_streambuf<_CharT, _Traits>::
+ xsputn(const char_type* __s, streamsize __n)
+ {
+ streamsize __ret = 0;
+ while (__ret < __n)
+ {
+ off_type __buf_len = _M_out_buf_size();
+ if (__buf_len > 0)
+ {
+ off_type __remaining = __n - __ret;
+ off_type __len = min(__buf_len, __remaining);
+ traits_type::copy(_M_out_cur, __s, __len);
+ __ret += __len;
+ __s += __len;
+ _M_out_cur_move(__len);
+ }
+
+ if (__ret < __n)
+ {
+ int_type __c = this->overflow(traits_type::to_int_type(*__s));
+ if (__c != traits_type::eof())
+ {
+ ++__ret;
+ ++__s;
+ }
+ else
+ break;
+ }
+ }
+ return __ret;
+ }
+
+ // Conceivably, this could be used to implement buffer-to-buffer
+ // copies, if this was ever desired in an un-ambiguous way by the
+ // standard. If so, then checks for __ios being zero would be
+ // necessary.
+ template<typename _CharT, typename _Traits>
+ streamsize
+ __copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
+ basic_streambuf<_CharT, _Traits>* __sbin,
+ basic_streambuf<_CharT, _Traits>* __sbout)
+ {
+ typedef typename _Traits::int_type int_type;
+
+ streamsize __ret = 0;
+ streamsize __bufsize = __sbin->in_avail();
+ streamsize __xtrct;
+ bool __testput = __sbout->_M_mode & ios_base::out;
+ try
+ {
+ while (__testput && __bufsize != -1)
+ {
+ __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
+ __ret += __xtrct;
+ __sbin->_M_in_cur_move(__xtrct);
+ if (__xtrct == __bufsize)
+ {
+ if (__sbin->sgetc() == _Traits::eof())
+ break;
+ __bufsize = __sbin->in_avail();
+ }
+ else
+ break;
+ }
+ }
+ catch(exception& __fail)
+ {
+ __ios.setstate(ios_base::failbit);
+ if ((__ios.exceptions() & ios_base::failbit) != 0)
+ __throw_exception_again;
+ }
+ return __ret;
+ }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+ extern template class basic_streambuf<char>;
+ extern template
+ streamsize
+ __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
+ basic_streambuf<char>*);
+
+ extern template class basic_streambuf<wchar_t>;
+ extern template
+ streamsize
+ __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*,
+ basic_streambuf<wchar_t>*);
+} // namespace std
+
+#endif
diff --git a/contrib/libstdc++/include/bits/streambuf_iterator.h b/contrib/libstdc++/include/bits/streambuf_iterator.h
new file mode 100644
index 0000000000000..659caecb2aff2
--- /dev/null
+++ b/contrib/libstdc++/include/bits/streambuf_iterator.h
@@ -0,0 +1,201 @@
+// Streambuf iterators
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// XXX Should specialize copy, find algorithms for streambuf iterators.
+
+/** @file streambuf_iterator.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STREAMBUF_ITERATOR_H
+#define _CPP_BITS_STREAMBUF_ITERATOR_H 1
+
+#pragma GCC system_header
+
+namespace std
+{
+ // 24.5.3 Template class istreambuf_iterator
+ template<typename _CharT, typename _Traits>
+ class istreambuf_iterator
+ : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
+ _CharT*, _CharT&>
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _Traits traits_type;
+ typedef typename _Traits::int_type int_type;
+ typedef basic_streambuf<_CharT, _Traits> streambuf_type;
+ typedef basic_istream<_CharT, _Traits> istream_type;
+
+ private:
+ // 24.5.3 istreambuf_iterator
+ // p 1
+ // If the end of stream is reached (streambuf_type::sgetc()
+ // returns traits_type::eof()), the iterator becomes equal to
+ // the "end of stream" iterator value.
+ // NB: This implementation assumes the "end of stream" value
+ // is EOF, or -1.
+ mutable streambuf_type* _M_sbuf;
+ int_type _M_c;
+
+ public:
+ istreambuf_iterator() throw()
+ : _M_sbuf(0), _M_c(-2) { }
+
+ istreambuf_iterator(istream_type& __s) throw()
+ : _M_sbuf(__s.rdbuf()), _M_c(-2) { }
+
+ istreambuf_iterator(streambuf_type* __s) throw()
+ : _M_sbuf(__s), _M_c(-2) { }
+
+ // NB: The result of operator*() on an end of stream is undefined.
+ char_type
+ operator*() const
+ { return traits_type::to_char_type(_M_get()); }
+
+ istreambuf_iterator&
+ operator++()
+ {
+ if (_M_sbuf && _M_sbuf->sbumpc() == traits_type::eof())
+ _M_sbuf = 0;
+ else
+ _M_c = -2;
+ return *this;
+ }
+
+ istreambuf_iterator
+ operator++(int)
+ {
+ istreambuf_iterator __old = *this;
+ if (_M_sbuf && (__old._M_c = _M_sbuf->sbumpc()) == traits_type::eof())
+ _M_sbuf = 0;
+ else
+ _M_c = -2;
+ return __old;
+ }
+
+#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
+ {
+ const int_type __eof = traits_type::eof();
+ bool __thiseof = _M_get() == __eof;
+ bool __beof = __b._M_get() == __eof;
+ return (__thiseof && __beof || (!__thiseof && !__beof));
+ }
+#endif
+
+ private:
+ int_type
+ _M_get() const
+ {
+ int_type __ret = traits_type::eof();
+ if (_M_sbuf)
+ {
+ if (_M_c != static_cast<int_type>(-2))
+ __ret = _M_c;
+ else
+ if ((__ret = _M_sbuf->sgetc()) == traits_type::eof())
+ _M_sbuf = 0;
+ }
+ return __ret;
+ }
+ };
+
+ template<typename _CharT, typename _Traits>
+ inline bool
+ operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
+ const istreambuf_iterator<_CharT, _Traits>& __b)
+ { return __a.equal(__b); }
+
+ template<typename _CharT, typename _Traits>
+ inline bool
+ 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/contrib/libstdc++/include/bits/stringfwd.h b/contrib/libstdc++/include/bits/stringfwd.h
new file mode 100644
index 0000000000000..b7418a67a7ea1
--- /dev/null
+++ b/contrib/libstdc++/include/bits/stringfwd.h
@@ -0,0 +1,67 @@
+// String support -*- C++ -*-
+
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 21 Strings library
+//
+
+/** @file stringfwd.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_STRINGFWD_H
+#define _CPP_BITS_STRINGFWD_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+
+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<typename _CharT, typename _Traits = char_traits<_CharT>,
+ typename _Alloc = allocator<_CharT> >
+ class basic_string;
+
+ typedef basic_string<char> string;
+ typedef basic_string<wchar_t> wstring;
+} // namespace std
+
+#endif // _CPP_BITS_STRINGFWD_H
diff --git a/contrib/libstdc++/include/bits/type_traits.h b/contrib/libstdc++/include/bits/type_traits.h
new file mode 100644
index 0000000000000..61bc436927583
--- /dev/null
+++ b/contrib/libstdc++/include/bits/type_traits.h
@@ -0,0 +1,339 @@
+// Type traits implementation -*- C++ -*-
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ *
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file type_traits.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_TYPE_TRAITS_H
+#define _CPP_BITS_TYPE_TRAITS_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+
+/*
+This header file provides a framework for allowing compile time dispatch
+based on type attributes. This is useful when writing template code.
+For example, when making a copy of an array of an unknown type, it helps
+to know if the type has a trivial copy constructor or not, to help decide
+if a memcpy can be used.
+
+The class template __type_traits provides a series of typedefs each of
+which is either __true_type or __false_type. The argument to
+__type_traits can be any type. The typedefs within this template will
+attain their correct values by one of these means:
+ 1. The general instantiation contain conservative values which work
+ for all types.
+ 2. Specializations may be declared to make distinctions between types.
+ 3. Some compilers (such as the Silicon Graphics N32 and N64 compilers)
+ will automatically provide the appropriate specializations for all
+ types.
+
+EXAMPLE:
+
+//Copy an array of elements which have non-trivial copy constructors
+template <class _Tp> void
+ copy(_Tp* __source,_Tp* __destination,int __n,__false_type);
+//Copy an array of elements which have trivial copy constructors. Use memcpy.
+template <class _Tp> void
+ copy(_Tp* __source,_Tp* __destination,int __n,__true_type);
+
+//Copy an array of any type by using the most efficient copy mechanism
+template <class _Tp> inline void copy(_Tp* __source,_Tp* __destination,int __n) {
+ copy(__source,__destination,__n,
+ typename __type_traits<_Tp>::has_trivial_copy_constructor());
+}
+*/
+
+struct __true_type {};
+struct __false_type {};
+
+template <class _Tp>
+struct __type_traits {
+ typedef __true_type this_dummy_member_must_be_first;
+ /* Do not remove this member. It informs a compiler which
+ automatically specializes __type_traits that this
+ __type_traits template is special. It just makes sure that
+ things work if an implementation is using a template
+ called __type_traits for something unrelated. */
+
+ /* The following restrictions should be observed for the sake of
+ compilers which automatically produce type specific specializations
+ of this class:
+ - You may reorder the members below if you wish
+ - You may remove any of the members below if you wish
+ - You must not rename members without making the corresponding
+ name change in the compiler
+ - Members you add will be treated like regular members unless
+ you add the appropriate support in the compiler. */
+
+
+ typedef __false_type has_trivial_default_constructor;
+ typedef __false_type has_trivial_copy_constructor;
+ typedef __false_type has_trivial_assignment_operator;
+ typedef __false_type has_trivial_destructor;
+ typedef __false_type is_POD_type;
+};
+
+
+// Provide some specializations.
+
+template<> struct __type_traits<bool> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<char> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<signed char> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<unsigned char> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<wchar_t> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<short> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<unsigned short> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<int> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<unsigned int> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<long> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<unsigned long> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<long long> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<unsigned long long> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<float> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<double> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template<> struct __type_traits<long double> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+template <class _Tp>
+struct __type_traits<_Tp*> {
+ typedef __true_type has_trivial_default_constructor;
+ typedef __true_type has_trivial_copy_constructor;
+ typedef __true_type has_trivial_assignment_operator;
+ typedef __true_type has_trivial_destructor;
+ typedef __true_type is_POD_type;
+};
+
+
+// The following could be written in terms of numeric_limits.
+// We're doing it separately to reduce the number of dependencies.
+
+template <class _Tp> struct _Is_integer {
+ typedef __false_type _Integral;
+};
+
+template<> struct _Is_integer<bool> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<char> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<signed char> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<unsigned char> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<wchar_t> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<short> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<unsigned short> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<int> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<unsigned int> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<long> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<unsigned long> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<long long> {
+ typedef __true_type _Integral;
+};
+
+template<> struct _Is_integer<unsigned long long> {
+ typedef __true_type _Integral;
+};
+
+template<typename _Tp> struct _Is_normal_iterator {
+ typedef __false_type _Normal;
+};
+
+// Forward declaration hack, should really include this from somewhere.
+namespace __gnu_cxx
+{
+ template<typename _Iterator, typename _Container> class __normal_iterator;
+}
+
+template<typename _Iterator, typename _Container>
+struct _Is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, _Container> > {
+ typedef __true_type _Normal;
+};
+
+#endif /* _CPP_BITS_TYPE_TRAITS_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/contrib/libstdc++/include/bits/valarray_array.h b/contrib/libstdc++/include/bits/valarray_array.h
new file mode 100644
index 0000000000000..48dd2aa4d835f
--- /dev/null
+++ b/contrib/libstdc++/include/bits/valarray_array.h
@@ -0,0 +1,630 @@
+// The template and inlines for the -*- C++ -*- internal _Array helper class.
+
+// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+/** @file valarray_array.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_BITS_ARRAY_H
+#define _CPP_BITS_ARRAY_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#include <bits/cpp_type_traits.h>
+#include <cstdlib>
+#include <cstring>
+#include <new>
+
+namespace std
+{
+ //
+ // Helper functions on raw pointers
+ //
+
+ // We get memory by the old fashion way
+ inline void*
+ __valarray_get_memory(size_t __n)
+ { return operator new(__n); }
+
+ template<typename _Tp>
+ inline _Tp*__restrict__
+ __valarray_get_storage(size_t __n)
+ {
+ return static_cast<_Tp*__restrict__>
+ (__valarray_get_memory(__n * sizeof(_Tp)));
+ }
+
+ // Return memory to the system
+ inline void
+ __valarray_release_memory(void* __p)
+ { operator delete(__p); }
+
+ // Turn a raw-memory into an array of _Tp filled with _Tp()
+ // This is required in 'valarray<T> v(n);'
+ template<typename _Tp, bool>
+ struct _Array_default_ctor
+ {
+ // Please note that this isn't exception safe. But
+ // valarrays aren't required to be exception safe.
+ inline static void
+ _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
+ { while (__b != __e) new(__b++) _Tp(); }
+ };
+
+ template<typename _Tp>
+ struct _Array_default_ctor<_Tp, true>
+ {
+ // For fundamental types, it suffices to say 'memset()'
+ inline static void
+ _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
+ { memset(__b, 0, (__e - __b)*sizeof(_Tp)); }
+ };
+
+ template<typename _Tp>
+ inline void
+ __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
+ {
+ _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
+ _S_do_it(__b, __e);
+ }
+
+ // Turn a raw-memory into an array of _Tp filled with __t
+ // This is the required in valarray<T> v(n, t). Also
+ // used in valarray<>::resize().
+ template<typename _Tp, bool>
+ struct _Array_init_ctor
+ {
+ // Please note that this isn't exception safe. But
+ // valarrays aren't required to be exception safe.
+ inline static void
+ _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
+ { while (__b != __e) new(__b++) _Tp(__t); }
+ };
+
+ template<typename _Tp>
+ struct _Array_init_ctor<_Tp, true>
+ {
+ inline static void
+ _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
+ { while (__b != __e) *__b++ = __t; }
+ };
+
+ template<typename _Tp>
+ inline void
+ __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
+ const _Tp __t)
+ {
+ _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
+ _S_do_it(__b, __e, __t);
+ }
+
+ //
+ // copy-construct raw array [__o, *) from plain array [__b, __e)
+ // We can't just say 'memcpy()'
+ //
+ template<typename _Tp, bool>
+ struct _Array_copy_ctor
+ {
+ // Please note that this isn't exception safe. But
+ // valarrays aren't required to be exception safe.
+ inline static void
+ _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
+ _Tp* __restrict__ __o)
+ { while (__b != __e) new(__o++) _Tp(*__b++); }
+ };
+
+ template<typename _Tp>
+ struct _Array_copy_ctor<_Tp, true>
+ {
+ inline static void
+ _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
+ _Tp* __restrict__ __o)
+ { memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); }
+ };
+
+ template<typename _Tp>
+ inline void
+ __valarray_copy_construct(const _Tp* __restrict__ __b,
+ const _Tp* __restrict__ __e,
+ _Tp* __restrict__ __o)
+ {
+ _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
+ _S_do_it(__b, __e, __o);
+ }
+
+ // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
+ size_t __s, _Tp* __restrict__ __o)
+ {
+ if (__is_fundamental<_Tp>::_M_type)
+ while (__n--) { *__o++ = *__a; __a += __s; }
+ else
+ while (__n--) { new(__o++) _Tp(*__a); __a += __s; }
+ }
+
+ // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
+ template<typename _Tp>
+ inline void
+ __valarray_copy_construct (const _Tp* __restrict__ __a,
+ const size_t* __restrict__ __i,
+ _Tp* __restrict__ __o, size_t __n)
+ {
+ if (__is_fundamental<_Tp>::_M_type)
+ while (__n--) *__o++ = __a[*__i++];
+ else
+ while (__n--) new (__o++) _Tp(__a[*__i++]);
+ }
+
+ // Do the necessary cleanup when we're done with arrays.
+ template<typename _Tp>
+ inline void
+ __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
+ {
+ if (!__is_fundamental<_Tp>::_M_type)
+ while (__b != __e) { __b->~_Tp(); ++__b; }
+ }
+
+ // Fill a plain array __a[<__n>] with __t
+ template<typename _Tp>
+ inline void
+ __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
+ { while (__n--) *__a++ = __t; }
+
+ // fill strided array __a[<__n-1 : __s>] with __t
+ template<typename _Tp>
+ inline void
+ __valarray_fill (_Tp* __restrict__ __a, size_t __n,
+ size_t __s, const _Tp& __t)
+ { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; }
+
+ // fill indir ect array __a[__i[<__n>]] with __i
+ template<typename _Tp>
+ inline void
+ __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
+ size_t __n, const _Tp& __t)
+ { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; }
+
+ // copy plain array __a[<__n>] in __b[<__n>]
+ // For non-fundamental types, it is wrong to say 'memcpy()'
+ template<typename _Tp, bool>
+ struct _Array_copier
+ {
+ inline static void
+ _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
+ { while (__n--) *__b++ = *__a++; }
+ };
+
+ template<typename _Tp>
+ struct _Array_copier<_Tp, true>
+ {
+ inline static void
+ _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
+ { memcpy (__b, __a, __n * sizeof (_Tp)); }
+ };
+
+ // Copy a plain array __a[<__n>] into a play array __b[<>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
+ _Tp* __restrict__ __b)
+ {
+ _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>::
+ _S_do_it(__a, __n, __b);
+ }
+
+ // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
+ _Tp* __restrict__ __b)
+ { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; }
+
+ // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
+ size_t __n, size_t __s)
+ { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; }
+
+ // Copy strided array __src[<__n : __s1>] into another
+ // strided array __dst[< : __s2>]. Their sizes must match.
+ template<typename _Tp>
+ inline void
+ __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
+ _Tp* __restrict__ __dst, size_t __s2)
+ {
+ for (size_t __i = 0; __i < __n; ++__i)
+ __dst[__i * __s2] = __src [ __i * __s1];
+ }
+
+
+ // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy (const _Tp* __restrict__ __a,
+ const size_t* __restrict__ __i,
+ _Tp* __restrict__ __b, size_t __n)
+ { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; }
+
+ // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
+ template<typename _Tp>
+ inline void
+ __valarray_copy (const _Tp* __restrict__ __a, size_t __n,
+ _Tp* __restrict__ __b, const size_t* __restrict__ __i)
+ { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; }
+
+ // Copy the __n first elements of an indexed array __src[<__i>] into
+ // another indexed array __dst[<__j>].
+ template<typename _Tp>
+ inline void
+ __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
+ const size_t* __restrict__ __i,
+ _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
+ {
+ for (size_t __k = 0; __k < __n; ++__k)
+ __dst[*__j++] = __src[*__i++];
+ }
+
+ //
+ // Compute the sum of elements in range [__f, __l)
+ // This is a naive algorithm. It suffers from cancelling.
+ // In the future try to specialize
+ // for _Tp = float, double, long double using a more accurate
+ // algorithm.
+ //
+ template<typename _Tp>
+ inline _Tp
+ __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l)
+ {
+ _Tp __r = _Tp();
+ while (__f != __l) __r += *__f++;
+ return __r;
+ }
+
+ // Compute the product of all elements in range [__f, __l)
+ template<typename _Tp>
+ inline _Tp
+ __valarray_product(const _Tp* __restrict__ __f,
+ const _Tp* __restrict__ __l)
+ {
+ _Tp __r = _Tp(1);
+ while (__f != __l) __r = __r * *__f++;
+ return __r;
+ }
+
+ // Compute the min/max of an array-expression
+ template<typename _Ta>
+ inline typename _Ta::value_type
+ __valarray_min(const _Ta& __a)
+ {
+ size_t __s = __a.size();
+ typedef typename _Ta::value_type _Value_type;
+ _Value_type __r = __s == 0 ? _Value_type() : __a[0];
+ for (size_t __i = 1; __i < __s; ++__i)
+ {
+ _Value_type __t = __a[__i];
+ if (__t < __r)
+ __r = __t;
+ }
+ return __r;
+ }
+
+ template<typename _Ta>
+ inline typename _Ta::value_type
+ __valarray_max(const _Ta& __a)
+ {
+ size_t __s = __a.size();
+ typedef typename _Ta::value_type _Value_type;
+ _Value_type __r = __s == 0 ? _Value_type() : __a[0];
+ for (size_t __i = 1; __i < __s; ++__i)
+ {
+ _Value_type __t = __a[__i];
+ if (__t > __r)
+ __r = __t;
+ }
+ return __r;
+ }
+
+ //
+ // Helper class _Array, first layer of valarray abstraction.
+ // All operations on valarray should be forwarded to this class
+ // whenever possible. -- gdr
+ //
+
+ template<typename _Tp>
+ struct _Array
+ {
+ explicit _Array (size_t);
+ explicit _Array (_Tp* const __restrict__);
+ explicit _Array (const valarray<_Tp>&);
+ _Array (const _Tp* __restrict__, size_t);
+
+ _Tp* begin () const;
+
+ _Tp* const __restrict__ _M_data;
+ };
+
+ template<typename _Tp>
+ inline void
+ __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
+ { __valarray_fill (__a._M_data, __n, __t); }
+
+ template<typename _Tp>
+ inline void
+ __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
+ { __valarray_fill (__a._M_data, __n, __s, __t); }
+
+ template<typename _Tp>
+ inline void
+ __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i,
+ size_t __n, const _Tp& __t)
+ { __valarray_fill (__a._M_data, __i._M_data, __n, __t); }
+
+ // Copy a plain array __a[<__n>] into a play array __b[<>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
+ { __valarray_copy(__a._M_data, __n, __b._M_data); }
+
+ // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
+ { __valarray_copy(__a._M_data, __n, __s, __b._M_data); }
+
+ // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
+ { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
+
+ // Copy strided array __src[<__n : __s1>] into another
+ // strided array __dst[< : __s2>]. Their sizes must match.
+ template<typename _Tp>
+ inline void
+ __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
+ _Array<_Tp> __b, size_t __s2)
+ { __valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
+
+
+ // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
+ _Array<_Tp> __b, size_t __n)
+ { __valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
+
+ // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
+ template<typename _Tp>
+ inline void
+ __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
+ _Array<size_t> __i)
+ { __valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
+
+ // Copy the __n first elements of an indexed array __src[<__i>] into
+ // another indexed array __dst[<__j>].
+ template<typename _Tp>
+ inline void
+ __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
+ _Array<_Tp> __dst, _Array<size_t> __j)
+ {
+ __valarray_copy(__src._M_data, __n, __i._M_data,
+ __dst._M_data, __j._M_data);
+ }
+
+ template<typename _Tp>
+ inline
+ _Array<_Tp>::_Array (size_t __n)
+ : _M_data(__valarray_get_storage<_Tp>(__n))
+ { __valarray_default_construct(_M_data, _M_data + __n); }
+
+ template<typename _Tp>
+ inline
+ _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {}
+
+ template<typename _Tp>
+ inline _Array<_Tp>::_Array (const valarray<_Tp>& __v)
+ : _M_data (__v._M_data) {}
+
+ template<typename _Tp>
+ inline
+ _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s)
+ : _M_data(__valarray_get_storage<_Tp>(__s))
+ { __valarray_copy_construct(__b, __s, _M_data); }
+
+ template<typename _Tp>
+ inline _Tp*
+ _Array<_Tp>::begin () const
+ { return _M_data; }
+
+#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \
+template<typename _Tp> \
+inline void \
+_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \
+{ \
+ for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \
+ *__p _Op##= __t; \
+} \
+ \
+template<typename _Tp> \
+inline void \
+_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
+{ \
+ _Tp* __p = __a._M_data; \
+ for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \
+ *__p _Op##= *__q; \
+} \
+ \
+template<typename _Tp, class _Dom> \
+void \
+_Array_augmented_##_Name (_Array<_Tp> __a, \
+ const _Expr<_Dom,_Tp>& __e, size_t __n) \
+{ \
+ _Tp* __p (__a._M_data); \
+ for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \
+} \
+ \
+template<typename _Tp> \
+inline void \
+_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \
+ _Array<_Tp> __b) \
+{ \
+ _Tp* __q (__b._M_data); \
+ for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \
+ *__p _Op##= *__q; \
+} \
+ \
+template<typename _Tp> \
+inline void \
+_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \
+ size_t __n, size_t __s) \
+{ \
+ _Tp* __q (__b._M_data); \
+ for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \
+ *__p _Op##= *__q; \
+} \
+ \
+template<typename _Tp, class _Dom> \
+void \
+_Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \
+ const _Expr<_Dom,_Tp>& __e, size_t __n) \
+{ \
+ _Tp* __p (__a._M_data); \
+ for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \
+} \
+ \
+template<typename _Tp> \
+inline void \
+_Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \
+ _Array<_Tp> __b, size_t __n) \
+{ \
+ _Tp* __q (__b._M_data); \
+ for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \
+ __a._M_data[*__j] _Op##= *__q; \
+} \
+ \
+template<typename _Tp> \
+inline void \
+_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \
+ _Array<_Tp> __b, _Array<size_t> __i) \
+{ \
+ _Tp* __p (__a._M_data); \
+ for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \
+ *__p _Op##= __b._M_data[*__j]; \
+} \
+ \
+template<typename _Tp, class _Dom> \
+void \
+_Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \
+ const _Expr<_Dom, _Tp>& __e, size_t __n) \
+{ \
+ size_t* __j (__i._M_data); \
+ for (size_t __k=0; __k<__n; ++__k, ++__j) \
+ __a._M_data[*__j] _Op##= __e[__k]; \
+} \
+ \
+template<typename _Tp> \
+void \
+_Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \
+ _Array<_Tp> __b, size_t __n) \
+{ \
+ bool* ok (__m._M_data); \
+ _Tp* __p (__a._M_data); \
+ for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \
+ while (! *ok) { \
+ ++ok; \
+ ++__p; \
+ } \
+ *__p _Op##= *__q; \
+ } \
+} \
+ \
+template<typename _Tp> \
+void \
+_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \
+ _Array<_Tp> __b, _Array<bool> __m) \
+{ \
+ bool* ok (__m._M_data); \
+ _Tp* __q (__b._M_data); \
+ for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \
+ while (! *ok) { \
+ ++ok; \
+ ++__q; \
+ } \
+ *__p _Op##= *__q; \
+ } \
+} \
+ \
+template<typename _Tp, class _Dom> \
+void \
+_Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \
+ const _Expr<_Dom, _Tp>& __e, size_t __n) \
+{ \
+ bool* ok(__m._M_data); \
+ _Tp* __p (__a._M_data); \
+ for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \
+ while (! *ok) { \
+ ++ok; \
+ ++__p; \
+ } \
+ *__p _Op##= __e[__i]; \
+ } \
+}
+
+ _DEFINE_ARRAY_FUNCTION(+, plus)
+ _DEFINE_ARRAY_FUNCTION(-, minus)
+ _DEFINE_ARRAY_FUNCTION(*, multiplies)
+ _DEFINE_ARRAY_FUNCTION(/, divides)
+ _DEFINE_ARRAY_FUNCTION(%, modulus)
+ _DEFINE_ARRAY_FUNCTION(^, xor)
+ _DEFINE_ARRAY_FUNCTION(|, or)
+ _DEFINE_ARRAY_FUNCTION(&, and)
+ _DEFINE_ARRAY_FUNCTION(<<, shift_left)
+ _DEFINE_ARRAY_FUNCTION(>>, shift_right)
+
+#undef _DEFINE_VALARRAY_FUNCTION
+
+} // std::
+
+#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
+# define export
+# include <bits/valarray_array.tcc>
+#endif
+
+#endif /* _CPP_BITS_ARRAY_H */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/valarray_array.tcc b/contrib/libstdc++/include/bits/valarray_array.tcc
new file mode 100644
index 0000000000000..ba4b0830a47ef
--- /dev/null
+++ b/contrib/libstdc++/include/bits/valarray_array.tcc
@@ -0,0 +1,161 @@
+// The template and inlines for the -*- C++ -*- internal _Array helper class.
+
+// Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
+
+#ifndef _CPP_BITS_VALARRAY_ARRAY_TCC
+#define _CPP_BITS_VALARRAY_ARRAY_TCC 1
+
+namespace std
+{
+
+export template<typename _Tp>
+void
+__valarray_fill (_Array<_Tp> __a, size_t __n, _Array<bool> __m, const _Tp& __t)
+{
+ _Tp* __p = __a._M_data;
+ bool* __ok (__m._M_data);
+ for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) {
+ while (! *__ok) {
+ ++__ok;
+ ++__p;
+ }
+ *__p = __t;
+ }
+}
+
+export template<typename _Tp>
+void
+__valarray_copy (_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b, size_t __n)
+{
+ _Tp* __p (__a._M_data);
+ bool* __ok (__m._M_data);
+ for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++__ok, ++__p) {
+ while (! *__ok) {
+ ++__ok;
+ ++__p;
+ }
+ *__q = *__p;
+ }
+}
+
+export template<typename _Tp>
+void
+__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, _Array<bool> __m)
+{
+ _Tp* __q (__b._M_data);
+ bool* __ok (__m._M_data);
+ for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++__ok, ++__q) {
+ while (! *__ok) {
+ ++__ok;
+ ++__q;
+ }
+ *__q = *__p;
+ }
+}
+
+export template<typename _Tp, class _Dom>
+void
+__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a)
+{
+ _Tp* __p (__a._M_data);
+ for (size_t __i=0; __i<__n; ++__i, ++__p) *__p = __e[__i];
+}
+
+export template<typename _Tp, class _Dom>
+void
+__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n,
+ _Array<_Tp> __a, size_t __s)
+{
+ _Tp* __p (__a._M_data);
+ for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p = __e[__i];
+}
+
+export template<typename _Tp, class _Dom>
+void
+__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n,
+ _Array<_Tp> __a, _Array<size_t> __i)
+{
+ size_t* __j (__i._M_data);
+ for (size_t __k=0; __k<__n; ++__k, ++__j) __a._M_data[*__j] = __e[__k];
+}
+
+export template<typename _Tp, class _Dom>
+void
+__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n,
+ _Array<_Tp> __a, _Array<bool> __m)
+{
+ bool* __ok (__m._M_data);
+ _Tp* __p (__a._M_data);
+ for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) {
+ while (! *__ok) {
+ ++__ok;
+ ++__p;
+ }
+ *__p = __e[__i];
+ }
+}
+
+
+export template<typename _Tp, class _Dom>
+void
+__valarray_copy_construct (const _Expr<_Dom, _Tp>& __e, size_t __n,
+ _Array<_Tp> __a)
+{
+ _Tp* __p (__a._M_data);
+ for (size_t __i=0; __i<__n; ++__i, ++__p) new (__p) _Tp(__e[__i]);
+}
+
+
+export template<typename _Tp>
+void
+__valarray_copy_construct (_Array<_Tp> __a, _Array<bool> __m,
+ _Array<_Tp> __b, size_t __n)
+{
+ _Tp* __p (__a._M_data);
+ bool* __ok (__m._M_data);
+ for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++__ok, ++__p) {
+ while (! *__ok) {
+ ++__ok;
+ ++__p;
+ }
+ new (__q) _Tp(*__p);
+ }
+}
+
+
+
+
+} // std::
+
+#endif /* _CPP_BITS_VALARRAY_ARRAY_TCC */
+
+// Local Variables:
+// mode:c++
+// End:
diff --git a/contrib/libstdc++/include/bits/valarray_meta.h b/contrib/libstdc++/include/bits/valarray_meta.h
new file mode 100644
index 0000000000000..f2926c0903535
--- /dev/null
+++ b/contrib/libstdc++/include/bits/valarray_meta.h
@@ -0,0 +1,1075 @@
+// The template and inlines for the -*- C++ -*- internal _Meta class.
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
+
+/** @file valarray_meta.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _CPP_VALARRAY_META_H
+#define _CPP_VALARRAY_META_H 1
+
+#pragma GCC system_header
+
+namespace std
+{
+
+ //
+ // Implementing a loosened valarray return value is tricky.
+ // First we need to meet 26.3.1/3: we should not add more than
+ // two levels of template nesting. Therefore we resort to template
+ // template to "flatten" loosened return value types.
+ // At some point we use partial specialization to remove one level
+ // template nesting due to _Expr<>
+ //
+
+
+ // This class is NOT defined. It doesn't need to.
+ template<typename _Tp1, typename _Tp2> class _Constant;
+
+ //
+ // Unary function application closure.
+ //
+ template<class _Dom> class _UnFunBase {
+ public:
+ typedef typename _Dom::value_type value_type;
+ typedef value_type _Vt;
+
+ _UnFunBase (const _Dom& __e, _Vt __f(_Vt))
+ : _M_expr(__e), _M_func(__f) {}
+
+ _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); }
+ size_t size () const { return _M_expr.size(); }
+
+ private:
+ const _Dom& _M_expr;
+ _Vt (*_M_func)(_Vt);
+ };
+
+ template<template<class, class> class _Meta, class _Dom>
+ class _UnFunClos;
+
+ template<class _Dom>
+ struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> {
+ typedef _UnFunBase<_Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _UnFunClos (const _Dom& __e, value_type __f(value_type))
+ : _Base (__e, __f) {}
+ };
+
+ template<typename _Tp>
+ struct _UnFunClos<_ValArray,_Tp> : _UnFunBase<valarray<_Tp> > {
+ typedef _UnFunBase<valarray<_Tp> > _Base;
+ typedef typename _Base::value_type value_type;
+
+ _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
+ : _Base (__v, __f) {}
+ };
+
+ //
+ // Binary function application closure.
+ //
+ template<template<class, class> class _Meta1,
+ template<class, class> class Meta2,
+ class _Dom1, class _Dom2> class _BinFunClos;
+
+ template<class _Dom1, class _Dom2> class _BinFunBase {
+ public:
+ typedef typename _Dom1::value_type value_type;
+ typedef value_type _Vt;
+
+ _BinFunBase (const _Dom1& __e1, const _Dom2& __e2,
+ _Vt __f (_Vt, _Vt))
+ : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {}
+
+ value_type operator[] (size_t __i) const
+ { return _M_func (_M_expr1[__i], _M_expr2[__i]); }
+ size_t size () const { return _M_expr1.size (); }
+
+ private:
+ const _Dom1& _M_expr1;
+ const _Dom2& _M_expr2;
+ _Vt (*_M_func)(_Vt, _Vt);
+ };
+
+ template<class _Dom> class _BinFunBase1 {
+ public:
+ typedef typename _Dom::value_type value_type ;
+ typedef value_type _Vt;
+
+ _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt))
+ : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {}
+
+ value_type operator[] (size_t __i) const
+ { return _M_func (_M_expr1, _M_expr2[__i]); }
+ size_t size () const { return _M_expr2.size (); }
+
+ private:
+ const _Vt& _M_expr1;
+ const _Dom& _M_expr2;
+ _Vt (*_M_func)(_Vt, _Vt);
+ };
+
+ template<class _Dom> class _BinFunBase2 {
+ public:
+ typedef typename _Dom::value_type value_type;
+ typedef value_type _Vt;
+
+ _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt))
+ : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {}
+
+ value_type operator[] (size_t __i) const
+ { return _M_func (_M_expr1[__i], _M_expr2); }
+ size_t size () const { return _M_expr1.size (); }
+
+ private:
+ const _Dom& _M_expr1;
+ const _Vt& _M_expr2;
+ _Vt (*_M_func)(_Vt, _Vt);
+ };
+
+ template<class _Dom1, class _Dom2>
+ struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> {
+ typedef _BinFunBase<_Dom1,_Dom2> _Base;
+ typedef typename _Base::value_type value_type;
+ typedef value_type _Tp;
+
+ _BinFunClos (const _Dom1& __e1, const _Dom2& __e2,
+ _Tp __f(_Tp, _Tp))
+ : _Base (__e1, __e2, __f) {}
+ };
+
+ template<typename _Tp>
+ struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp>
+ : _BinFunBase<valarray<_Tp>, valarray<_Tp> > {
+ typedef _BinFunBase<valarray<_Tp>, valarray<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w,
+ _Tp __f(_Tp, _Tp))
+ : _Base (__v, __w, __f) {}
+ };
+
+ template<class _Dom>
+ struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>
+ : _BinFunBase<_Dom,valarray<typename _Dom::value_type> > {
+ typedef typename _Dom::value_type _Tp;
+ typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v,
+ _Tp __f(_Tp, _Tp))
+ : _Base (__e, __v, __f) {}
+ };
+
+ template<class _Dom>
+ struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>
+ : _BinFunBase<valarray<typename _Dom::value_type>,_Dom> {
+ typedef typename _Dom::value_type _Tp;
+ typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e,
+ _Tp __f(_Tp, _Tp))
+ : _Base (__v, __e, __f) {}
+ };
+
+ template<class _Dom>
+ struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>
+ : _BinFunBase2<_Dom> {
+ typedef typename _Dom::value_type _Tp;
+ typedef _Tp value_type;
+ typedef _BinFunBase2<_Dom> _Base;
+
+ _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp))
+ : _Base (__e, __t, __f) {}
+ };
+
+ template<class _Dom>
+ struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type>
+ : _BinFunBase1<_Dom> {
+ typedef typename _Dom::value_type _Tp;
+ typedef _Tp value_type;
+ typedef _BinFunBase1<_Dom> _Base;
+
+ _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp))
+ : _Base (__t, __e, __f) {}
+ };
+
+ template<typename _Tp>
+ struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp>
+ : _BinFunBase2<valarray<_Tp> > {
+ typedef _BinFunBase2<valarray<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t,
+ _Tp __f(_Tp, _Tp))
+ : _Base (__v, __t, __f) {}
+ };
+
+ template<typename _Tp>
+ struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp>
+ : _BinFunBase1<valarray<_Tp> > {
+ typedef _BinFunBase1<valarray<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v,
+ _Tp __f (_Tp, _Tp))
+ : _Base (__t, __v, __f) {}
+ };
+
+ //
+ // Apply function taking a value/const reference closure
+ //
+
+ template<typename _Dom, typename _Arg> class _FunBase {
+ public:
+ typedef typename _Dom::value_type value_type;
+
+ _FunBase (const _Dom& __e, value_type __f(_Arg))
+ : _M_expr (__e), _M_func (__f) {}
+
+ value_type operator[] (size_t __i) const
+ { return _M_func (_M_expr[__i]); }
+ size_t size() const { return _M_expr.size ();}
+
+ private:
+ const _Dom& _M_expr;
+ value_type (*_M_func)(_Arg);
+ };
+
+ template<class _Dom>
+ struct _ValFunClos<_Expr,_Dom>
+ : _FunBase<_Dom, typename _Dom::value_type> {
+ typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
+ typedef typename _Base::value_type value_type;
+ typedef value_type _Tp;
+
+ _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {}
+ };
+
+ template<typename _Tp>
+ struct _ValFunClos<_ValArray,_Tp>
+ : _FunBase<valarray<_Tp>, _Tp> {
+ typedef _FunBase<valarray<_Tp>, _Tp> _Base;
+ typedef _Tp value_type;
+
+ _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
+ : _Base (__v, __f) {}
+ };
+
+ template<class _Dom>
+ struct _RefFunClos<_Expr,_Dom> :
+ _FunBase<_Dom, const typename _Dom::value_type&> {
+ typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
+ typedef typename _Base::value_type value_type;
+ typedef value_type _Tp;
+
+ _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&))
+ : _Base (__e, __f) {}
+ };
+
+ template<typename _Tp>
+ struct _RefFunClos<_ValArray,_Tp>
+ : _FunBase<valarray<_Tp>, const _Tp&> {
+ typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
+ typedef _Tp value_type;
+
+ _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&))
+ : _Base (__v, __f) {}
+ };
+
+ //
+ // Unary expression closure.
+ //
+
+ template<template<class> class _Oper, typename _Arg>
+ class _UnBase {
+ public:
+ typedef _Oper<typename _Arg::value_type> _Op;
+ typedef typename _Op::result_type value_type;
+
+ _UnBase (const _Arg& __e) : _M_expr(__e) {}
+ value_type operator[] (size_t) const;
+ size_t size () const { return _M_expr.size (); }
+
+ private:
+ const _Arg& _M_expr;
+ };
+
+ template<template<class> class _Oper, typename _Arg>
+ inline typename _UnBase<_Oper, _Arg>::value_type
+ _UnBase<_Oper, _Arg>::operator[] (size_t __i) const
+ { return _Op() (_M_expr[__i]); }
+
+ template<template<class> class _Oper, class _Dom>
+ struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> {
+ typedef _Dom _Arg;
+ typedef _UnBase<_Oper, _Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _UnClos (const _Arg& __e) : _Base(__e) {}
+ };
+
+ template<template<class> class _Oper, typename _Tp>
+ struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > {
+ typedef valarray<_Tp> _Arg;
+ typedef _UnBase<_Oper, valarray<_Tp> > _Base;
+ typedef typename _Base::value_type value_type;
+
+ _UnClos (const _Arg& __e) : _Base(__e) {}
+ };
+
+
+ //
+ // Binary expression closure.
+ //
+
+ template<template<class> class _Oper,
+ typename _FirstArg, typename _SecondArg>
+ class _BinBase {
+ public:
+ typedef _Oper<typename _FirstArg::value_type> _Op;
+ typedef typename _Op::result_type value_type;
+
+ _BinBase (const _FirstArg& __e1, const _SecondArg& __e2)
+ : _M_expr1 (__e1), _M_expr2 (__e2) {}
+ value_type operator[] (size_t) const;
+ size_t size () const { return _M_expr1.size (); }
+
+ private:
+ const _FirstArg& _M_expr1;
+ const _SecondArg& _M_expr2;
+ };
+
+ template<template<class> class _Oper,
+ typename _FirstArg, typename _SecondArg>
+ inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type
+ _BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const
+ { return _Op() (_M_expr1[__i], _M_expr2[__i]); }
+
+
+ template<template<class> class _Oper, class _Clos>
+ class _BinBase2 {
+ public:
+ typedef typename _Clos::value_type _Vt;
+ typedef _Oper<_Vt> _Op;
+ typedef typename _Op::result_type value_type;
+
+ _BinBase2 (const _Clos& __e, const _Vt& __t)
+ : _M_expr1 (__e), _M_expr2 (__t) {}
+ value_type operator[] (size_t) const;
+ size_t size () const { return _M_expr1.size (); }
+
+ private:
+ const _Clos& _M_expr1;
+ const _Vt& _M_expr2;
+ };
+
+ template<template<class> class _Oper, class _Clos>
+ inline typename _BinBase2<_Oper,_Clos>::value_type
+ _BinBase2<_Oper,_Clos>::operator[] (size_t __i) const
+ { return _Op() (_M_expr1[__i], _M_expr2); }
+
+
+ template<template<class> class _Oper, class _Clos>
+ class _BinBase1 {
+ public:
+ typedef typename _Clos::value_type _Vt;
+ typedef _Oper<_Vt> _Op;
+ typedef typename _Op::result_type value_type;
+
+ _BinBase1 (const _Vt& __t, const _Clos& __e)
+ : _M_expr1 (__t), _M_expr2 (__e) {}
+ value_type operator[] (size_t) const;
+ size_t size () const { return _M_expr2.size (); }
+
+ private:
+ const _Vt& _M_expr1;
+ const _Clos& _M_expr2;
+ };
+
+ template<template<class> class _Oper, class _Clos>
+ inline typename
+ _BinBase1<_Oper,_Clos>::value_type
+ _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const
+ { return _Op() (_M_expr1, _M_expr2[__i]); }
+
+
+ template<template<class> class _Oper, class _Dom1, class _Dom2>
+ struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
+ : _BinBase<_Oper,_Dom1,_Dom2> {
+ typedef _BinBase<_Oper,_Dom1,_Dom2> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
+ };
+
+ template<template<class> class _Oper, typename _Tp>
+ struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp>
+ : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > {
+ typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w)
+ : _Base (__v, __w) {}
+ };
+
+ template<template<class> class _Oper, class _Dom>
+ struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type>
+ : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > {
+ typedef typename _Dom::value_type _Tp;
+ typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
+ typedef typename _Base::value_type value_type;
+
+ _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
+ : _Base (__e1, __e2) {}
+ };
+
+ template<template<class> class _Oper, class _Dom>
+ struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom>
+ : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> {
+ typedef typename _Dom::value_type _Tp;
+ typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2)
+ : _Base (__e1, __e2) {}
+ };
+
+ template<template<class> class _Oper, class _Dom>
+ struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type>
+ : _BinBase2<_Oper,_Dom> {
+ typedef typename _Dom::value_type _Tp;
+ typedef _BinBase2<_Oper,_Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {}
+ };
+
+ template<template<class> class _Oper, class _Dom>
+ struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom>
+ : _BinBase1<_Oper,_Dom> {
+ typedef typename _Dom::value_type _Tp;
+ typedef _BinBase1<_Oper,_Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {}
+ };
+
+ template<template<class> class _Oper, typename _Tp>
+ struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp>
+ : _BinBase2<_Oper,valarray<_Tp> > {
+ typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
+ typedef typename _Base::value_type value_type;
+
+ _BinClos (const valarray<_Tp>& __v, const _Tp& __t)
+ : _Base (__v, __t) {}
+ };
+
+ template<template<class> class _Oper, typename _Tp>
+ struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp>
+ : _BinBase1<_Oper,valarray<_Tp> > {
+ typedef _BinBase1<_Oper,valarray<_Tp> > _Base;
+ typedef typename _Base::value_type value_type;
+
+ _BinClos (const _Tp& __t, const valarray<_Tp>& __v)
+ : _Base (__t, __v) {}
+ };
+
+
+ //
+ // slice_array closure.
+ //
+ template<typename _Dom> class _SBase {
+ public:
+ typedef typename _Dom::value_type value_type;
+
+ _SBase (const _Dom& __e, const slice& __s)
+ : _M_expr (__e), _M_slice (__s) {}
+ value_type operator[] (size_t __i) const
+ { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
+ size_t size() const { return _M_slice.size (); }
+
+ private:
+ const _Dom& _M_expr;
+ const slice& _M_slice;
+ };
+
+ template<typename _Tp> class _SBase<_Array<_Tp> > {
+ public:
+ typedef _Tp value_type;
+
+ _SBase (_Array<_Tp> __a, const slice& __s)
+ : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
+ _M_stride (__s.stride()) {}
+ value_type operator[] (size_t __i) const
+ { return _M_array._M_data[__i * _M_stride]; }
+ size_t size() const { return _M_size; }
+
+ private:
+ const _Array<_Tp> _M_array;
+ const size_t _M_size;
+ const size_t _M_stride;
+ };
+
+ template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> {
+ typedef _SBase<_Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
+ };
+
+ template<typename _Tp>
+ struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
+ typedef _SBase<_Array<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
+ };
+
+ //
+ // gslice_array closure.
+ //
+ template<class _Dom> class _GBase {
+ public:
+ typedef typename _Dom::value_type value_type;
+
+ _GBase (const _Dom& __e, const valarray<size_t>& __i)
+ : _M_expr (__e), _M_index(__i) {}
+ value_type operator[] (size_t __i) const
+ { return _M_expr[_M_index[__i]]; }
+ size_t size () const { return _M_index.size(); }
+
+ private:
+ const _Dom& _M_expr;
+ const valarray<size_t>& _M_index;
+ };
+
+ template<typename _Tp> class _GBase<_Array<_Tp> > {
+ public:
+ typedef _Tp value_type;
+
+ _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
+ : _M_array (__a), _M_index(__i) {}
+ value_type operator[] (size_t __i) const
+ { return _M_array._M_data[_M_index[__i]]; }
+ size_t size () const { return _M_index.size(); }
+
+ private:
+ const _Array<_Tp> _M_array;
+ const valarray<size_t>& _M_index;
+ };
+
+ template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
+ typedef _GBase<_Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _GClos (const _Dom& __e, const valarray<size_t>& __i)
+ : _Base (__e, __i) {}
+ };
+
+ template<typename _Tp>
+ struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > {
+ typedef _GBase<_Array<_Tp> > _Base;
+ typedef typename _Base::value_type value_type;
+
+ _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
+ : _Base (__a, __i) {}
+ };
+
+ //
+ // indirect_array closure
+ //
+
+ template<class _Dom> class _IBase {
+ public:
+ typedef typename _Dom::value_type value_type;
+
+ _IBase (const _Dom& __e, const valarray<size_t>& __i)
+ : _M_expr (__e), _M_index (__i) {}
+ value_type operator[] (size_t __i) const
+ { return _M_expr[_M_index[__i]]; }
+ size_t size() const { return _M_index.size(); }
+
+ private:
+ const _Dom& _M_expr;
+ const valarray<size_t>& _M_index;
+ };
+
+ template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
+ typedef _IBase<_Dom> _Base;
+ typedef typename _Base::value_type value_type;
+
+ _IClos (const _Dom& __e, const valarray<size_t>& __i)
+ : _Base (__e, __i) {}
+ };
+
+ template<typename _Tp>
+ struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > {
+ typedef _IBase<valarray<_Tp> > _Base;
+ typedef _Tp value_type;
+
+ _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
+ : _Base (__a, __i) {}
+ };
+
+ //
+ // class _Expr
+ //
+ template<class _Clos, typename _Tp> class _Expr {
+ public:
+ typedef _Tp value_type;
+
+ _Expr (const _Clos&);
+
+ const _Clos& operator() () const;
+
+ value_type operator[] (size_t) const;
+ valarray<value_type> operator[] (slice) const;
+ valarray<value_type> operator[] (const gslice&) const;
+ valarray<value_type> operator[] (const valarray<bool>&) const;
+ valarray<value_type> operator[] (const valarray<size_t>&) const;
+
+ _Expr<_UnClos<_Unary_plus,std::_Expr,_Clos>, value_type>
+ operator+ () const;
+
+ _Expr<_UnClos<negate,std::_Expr,_Clos>, value_type>
+ operator- () const;
+
+ _Expr<_UnClos<_Bitwise_not,std::_Expr,_Clos>, value_type>
+ operator~ () const;
+
+ _Expr<_UnClos<logical_not,std::_Expr,_Clos>, bool>
+ operator! () const;
+
+ size_t size () const;
+ value_type sum () const;
+
+ valarray<value_type> shift (int) const;
+ valarray<value_type> cshift (int) const;
+
+ value_type min() const;
+ value_type max() const;
+
+ valarray<value_type> apply(value_type (*) (const value_type&)) const;
+ valarray<value_type> apply(value_type (*) (value_type)) const;
+
+ private:
+ const _Clos _M_closure;
+ };
+
+ template<class _Clos, typename _Tp>
+ inline
+ _Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {}
+
+ template<class _Clos, typename _Tp>
+ inline const _Clos&
+ _Expr<_Clos,_Tp>::operator() () const
+ { return _M_closure; }
+
+ template<class _Clos, typename _Tp>
+ inline _Tp
+ _Expr<_Clos,_Tp>::operator[] (size_t __i) const
+ { return _M_closure[__i]; }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos,_Tp>::operator[] (slice __s) const
+ { return _M_closure[__s]; }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const
+ { return _M_closure[__gs]; }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos,_Tp>::operator[] (const valarray<bool>& __m) const
+ { return _M_closure[__m]; }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos,_Tp>::operator[] (const valarray<size_t>& __i) const
+ { return _M_closure[__i]; }
+
+ template<class _Clos, typename _Tp>
+ inline size_t
+ _Expr<_Clos,_Tp>::size () const { return _M_closure.size (); }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos, _Tp>::shift(int __n) const
+ { return valarray<_Tp>(_M_closure).shift(__n); }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos, _Tp>::cshift(int __n) const
+ { return valarray<_Tp>(_M_closure).cshift(__n); }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
+ { return valarray<_Tp>(_M_closure).apply(__f); }
+
+ template<class _Clos, typename _Tp>
+ inline valarray<_Tp>
+ _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
+ { return valarray<_Tp>(_M_closure).apply(__f); }
+
+ // XXX: replace this with a more robust summation algorithm.
+ template<class _Clos, typename _Tp>
+ inline _Tp
+ _Expr<_Clos,_Tp>::sum () const
+ {
+ size_t __n = _M_closure.size();
+ if (__n == 0) return _Tp();
+ else {
+ _Tp __s = _M_closure[--__n];
+ while (__n != 0) __s += _M_closure[--__n];
+ return __s;
+ }
+ }
+
+ template<class _Clos, typename _Tp>
+ inline _Tp
+ _Expr<_Clos, _Tp>::min() const
+ { return __valarray_min(_M_closure); }
+
+ template<class _Clos, typename _Tp>
+ inline _Tp
+ _Expr<_Clos, _Tp>::max() const
+ { return __valarray_max(_M_closure); }
+
+ template<class _Dom, typename _Tp>
+ inline _Expr<_UnClos<logical_not,_Expr,_Dom>, bool>
+ _Expr<_Dom,_Tp>::operator! () const
+ {
+ typedef _UnClos<logical_not,std::_Expr,_Dom> _Closure;
+ return _Expr<_Closure,_Tp> (_Closure(this->_M_closure));
+ }
+
+#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
+template<class _Dom, typename _Tp> \
+inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \
+_Expr<_Dom,_Tp>::operator _Op () const \
+{ \
+ typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
+ return _Expr<_Closure,_Tp> (_Closure (this->_M_closure)); \
+}
+
+ _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus)
+ _DEFINE_EXPR_UNARY_OPERATOR(-, negate)
+ _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not)
+
+#undef _DEFINE_EXPR_UNARY_OPERATOR
+
+
+#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
+template<class _Dom1, class _Dom2> \
+inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \
+ typename _Name<typename _Dom1::value_type>::result_type> \
+operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
+ const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
+{ \
+ typedef typename _Dom1::value_type _Arg; \
+ typedef typename _Name<_Arg>::result_type _Value; \
+ typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
+ return _Expr<_Closure,_Value> (_Closure (__v (), __w ())); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
+ typename _Name<typename _Dom::value_type>::result_type> \
+operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
+ const typename _Dom::value_type& __t) \
+{ \
+ typedef typename _Dom::value_type _Arg; \
+ typedef typename _Name<_Arg>::result_type _Value; \
+ typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
+ return _Expr<_Closure,_Value> (_Closure (__v (), __t)); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
+ typename _Name<typename _Dom::value_type>::result_type> \
+operator _Op (const typename _Dom::value_type& __t, \
+ const _Expr<_Dom,typename _Dom::value_type>& __v) \
+{ \
+ typedef typename _Dom::value_type _Arg; \
+ typedef typename _Name<_Arg>::result_type _Value; \
+ typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
+ return _Expr<_Closure,_Value> (_Closure (__t, __v ())); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
+ typename _Name<typename _Dom::value_type>::result_type> \
+operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
+ const valarray<typename _Dom::value_type>& __v) \
+{ \
+ typedef typename _Dom::value_type _Arg; \
+ typedef typename _Name<_Arg>::result_type _Value; \
+ typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \
+ return _Expr<_Closure,_Value> (_Closure (__e (), __v)); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
+ typename _Name<typename _Dom::value_type>::result_type> \
+operator _Op (const valarray<typename _Dom::value_type>& __v, \
+ const _Expr<_Dom,typename _Dom::value_type>& __e) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef typename _Name<_Tp>::result_type _Value; \
+ typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
+ return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \
+}
+
+ _DEFINE_EXPR_BINARY_OPERATOR(+, plus)
+ _DEFINE_EXPR_BINARY_OPERATOR(-, minus)
+ _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies)
+ _DEFINE_EXPR_BINARY_OPERATOR(/, divides)
+ _DEFINE_EXPR_BINARY_OPERATOR(%, modulus)
+ _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor)
+ _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and)
+ _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or)
+ _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left)
+ _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right)
+
+#undef _DEFINE_EXPR_BINARY_OPERATOR
+
+#define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name) \
+template<class _Dom1, class _Dom2> \
+inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool> \
+operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
+ const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
+{ \
+ typedef typename _Dom1::value_type _Arg; \
+ typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
+ return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
+ bool> \
+operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
+ const typename _Dom::value_type& __t) \
+{ \
+ typedef typename _Dom::value_type _Arg; \
+ typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
+ return _Expr<_Closure,bool> (_Closure (__v (), __t)); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
+ bool> \
+operator _Op (const typename _Dom::value_type& __t, \
+ const _Expr<_Dom,typename _Dom::value_type>& __v) \
+{ \
+ typedef typename _Dom::value_type _Arg; \
+ typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
+ return _Expr<_Closure,bool> (_Closure (__t, __v ())); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
+ bool> \
+operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
+ const valarray<typename _Dom::value_type>& __v) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \
+ return _Expr<_Closure,bool> (_Closure (__e (), __v)); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
+ bool> \
+operator _Op (const valarray<typename _Dom::value_type>& __v, \
+ const _Expr<_Dom,typename _Dom::value_type>& __e) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
+ return _Expr<_Closure,bool> (_Closure (__v, __e ())); \
+}
+
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and)
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or)
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to)
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to)
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less)
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater)
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal)
+ _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal)
+
+#undef _DEFINE_EXPR_RELATIONAL_OPERATOR
+
+
+
+#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \
+template<class _Dom> \
+inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type> \
+_Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef _UnFunClos<_Expr,_Dom> _Closure; \
+ return _Expr<_Closure,_Tp>(_Closure(__e(), (_Tp(*)(_Tp))(&_Name))); \
+} \
+ \
+template<typename _Tp> \
+inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp> \
+_Name(const valarray<_Tp>& __v) \
+{ \
+ typedef _UnFunClos<_ValArray,_Tp> _Closure; \
+ return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \
+}
+
+
+ _DEFINE_EXPR_UNARY_FUNCTION(abs)
+ _DEFINE_EXPR_UNARY_FUNCTION(cos)
+ _DEFINE_EXPR_UNARY_FUNCTION(acos)
+ _DEFINE_EXPR_UNARY_FUNCTION(cosh)
+ _DEFINE_EXPR_UNARY_FUNCTION(sin)
+ _DEFINE_EXPR_UNARY_FUNCTION(asin)
+ _DEFINE_EXPR_UNARY_FUNCTION(sinh)
+ _DEFINE_EXPR_UNARY_FUNCTION(tan)
+ _DEFINE_EXPR_UNARY_FUNCTION(tanh)
+ _DEFINE_EXPR_UNARY_FUNCTION(atan)
+ _DEFINE_EXPR_UNARY_FUNCTION(exp)
+ _DEFINE_EXPR_UNARY_FUNCTION(log)
+ _DEFINE_EXPR_UNARY_FUNCTION(log10)
+ _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
+
+#undef _DEFINE_EXPR_UNARY_FUNCTION
+
+
+#define _DEFINE_EXPR_BINARY_FUNCTION(_Name) \
+template<class _Dom1, class _Dom2> \
+inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\
+_Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \
+ const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \
+{ \
+ typedef typename _Dom1::value_type _Tp; \
+ typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
+ typename _Dom::value_type> \
+_Name (const _Expr<_Dom,typename _Dom::value_type>& __e, \
+ const valarray<typename _Dom::value_type>& __v) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name))); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
+ typename _Dom::value_type> \
+_Name (const valarray<typename _Dom::valarray>& __v, \
+ const _Expr<_Dom,typename _Dom::value_type>& __e) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \
+ typename _Dom::value_type> \
+_Name (const _Expr<_Dom, typename _Dom::value_type>& __e, \
+ const typename _Dom::value_type& __t) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name))); \
+} \
+ \
+template<class _Dom> \
+inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \
+ typename _Dom::value_type> \
+_Name (const typename _Dom::value_type& __t, \
+ const _Expr<_Dom,typename _Dom::value_type>& __e) \
+{ \
+ typedef typename _Dom::value_type _Tp; \
+ typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
+} \
+ \
+template<typename _Tp> \
+inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
+_Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
+{ \
+ typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \
+} \
+ \
+template<typename _Tp> \
+inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \
+_Name (const valarray<_Tp>& __v, const _Tp& __t) \
+{ \
+ typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \
+} \
+ \
+template<typename _Tp> \
+inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \
+_Name (const _Tp& __t, const valarray<_Tp>& __v) \
+{ \
+ typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \
+ return _Expr<_Closure,_Tp> \
+ (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \
+}
+
+_DEFINE_EXPR_BINARY_FUNCTION(atan2)
+_DEFINE_EXPR_BINARY_FUNCTION(pow)
+
+#undef _DEFINE_EXPR_BINARY_FUNCTION
+
+} // std::
+
+
+#endif /* _CPP_VALARRAY_META_H */
+
+// Local Variables:
+// mode:c++
+// End: