summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>2009-10-03 02:17:41 +0000
committerrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>2009-10-03 02:17:41 +0000
commitc55dc904bf82da75f1a76a6523c4e8ff16352b4f (patch)
tree4ee10967bd743d512cc41a7b4610019f4ca6adfb /libstdc++-v3/include
parentfb5d6a4fa9aec18d9dda9b4d568d0e2be87a34ef (diff)
downloadgcc-c55dc904bf82da75f1a76a6523c4e8ff16352b4f.tar.gz
merge branch profile-stdlib
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152431 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/Makefile.am52
-rw-r--r--libstdc++-v3/include/Makefile.in53
-rw-r--r--libstdc++-v3/include/backward/hash_map4
-rw-r--r--libstdc++-v3/include/backward/hash_set4
-rw-r--r--libstdc++-v3/include/bits/c++config40
-rw-r--r--libstdc++-v3/include/profile/base.h68
-rw-r--r--libstdc++-v3/include/profile/bitset345
-rw-r--r--libstdc++-v3/include/profile/deque420
-rw-r--r--libstdc++-v3/include/profile/hashtable.h1151
-rw-r--r--libstdc++-v3/include/profile/impl/profiler.h326
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_container_size.h250
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hash_func.h192
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hashtable_size.h115
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h305
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_node.h172
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_state.h107
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_trace.h564
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_size.h112
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_to_list.h318
-rw-r--r--libstdc++-v3/include/profile/list520
-rw-r--r--libstdc++-v3/include/profile/map41
-rw-r--r--libstdc++-v3/include/profile/map.h489
-rw-r--r--libstdc++-v3/include/profile/multimap.h363
-rw-r--r--libstdc++-v3/include/profile/multiset.h363
-rw-r--r--libstdc++-v3/include/profile/set41
-rw-r--r--libstdc++-v3/include/profile/set.h367
-rw-r--r--libstdc++-v3/include/profile/unordered_map498
-rw-r--r--libstdc++-v3/include/profile/unordered_set480
-rw-r--r--libstdc++-v3/include/profile/vector369
-rw-r--r--libstdc++-v3/include/std/bitset4
-rw-r--r--libstdc++-v3/include/std/deque4
-rw-r--r--libstdc++-v3/include/std/list4
-rw-r--r--libstdc++-v3/include/std/map4
-rw-r--r--libstdc++-v3/include/std/set4
-rw-r--r--libstdc++-v3/include/std/unordered_map6
-rw-r--r--libstdc++-v3/include/std/unordered_set5
-rw-r--r--libstdc++-v3/include/std/vector6
-rw-r--r--libstdc++-v3/include/tr1_impl/hashtable3
38 files changed, 8159 insertions, 10 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 55d02364d11..f3dcd19b79f 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1,4 +1,4 @@
-## Makefile for the include subdirectory of the GNU C++ Standard library.
+#o# Makefile for the include subdirectory of the GNU C++ Standard library.
##
## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
## Free Software Foundation, Inc.
@@ -771,6 +771,37 @@ else
parallel_headers =
endif
+# Profile mode headers
+profile_srcdir = ${glibcxx_srcdir}/include/profile
+profile_builddir = ./profile
+profile_headers = \
+ ${profile_srcdir}/base.h \
+ ${profile_srcdir}/unordered_map \
+ ${profile_srcdir}/unordered_set \
+ ${profile_srcdir}/vector \
+ ${profile_srcdir}/bitset \
+ ${profile_srcdir}/deque \
+ ${profile_srcdir}/list \
+ ${profile_srcdir}/map \
+ ${profile_srcdir}/map.h \
+ ${profile_srcdir}/multimap.h \
+ ${profile_srcdir}/multiset.h \
+ ${profile_srcdir}/set \
+ ${profile_srcdir}/set.h \
+ ${profile_srcdir}/hashtable.h
+profile_impl_srcdir = ${glibcxx_srcdir}/include/profile/impl
+profile_impl_builddir = ./profile/impl
+profile_impl_headers = \
+ ${profile_impl_srcdir}/profiler.h \
+ ${profile_impl_srcdir}/profiler_container_size.h \
+ ${profile_impl_srcdir}/profiler_hash_func.h \
+ ${profile_impl_srcdir}/profiler_hashtable_size.h \
+ ${profile_impl_srcdir}/profiler_map_to_unordered_map.h \
+ ${profile_impl_srcdir}/profiler_node.h \
+ ${profile_impl_srcdir}/profiler_state.h \
+ ${profile_impl_srcdir}/profiler_trace.h \
+ ${profile_impl_srcdir}/profiler_vector_size.h \
+ ${profile_impl_srcdir}/profiler_vector_to_list.h
# Some of the different "C" header models need extra files.
# Some "C" header schemes require the "C" compatibility headers.
@@ -865,7 +896,8 @@ endif
allstamped = \
stamp-std stamp-bits stamp-c_base stamp-c_base_extra \
stamp-c_compatibility stamp-backward stamp-ext stamp-pb \
- stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host
+ stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host \
+ stamp-profile stamp-profile-impl
# List of all files that are created by explicit building, editing, or
# catenation.
@@ -989,6 +1021,16 @@ stamp-parallel: ${parallel_headers}
@-cd ${parallel_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-parallel
+stamp-profile: ${profile_headers}
+ @-mkdir -p ${profile_builddir}
+ @-cd ${profile_builddir} && $(LN_S) $? . 2>/dev/null
+ @$(STAMP) stamp-profile
+
+stamp-profile-impl: ${profile_impl_headers}
+ @-mkdir -p ${profile_impl_builddir}
+ @-cd ${profile_impl_builddir} && $(LN_S) $? . 2>/dev/null
+ @$(STAMP) stamp-profile-impl
+
stamp-${host_alias}:
@-mkdir -p ${host_builddir}
@$(STAMP) stamp-${host_alias}
@@ -1217,6 +1259,12 @@ install-headers:
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${parallel_builddir};\
for file in $$parallel_headers_install; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${parallel_builddir}; done
+ $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_builddir}
+ for file in ${profile_headers}; do \
+ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_builddir}; done
+ $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}
+ for file in ${profile_impl_headers}; do \
+ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}; done
$(mkinstalldirs) $(DESTDIR)${host_installdir}
for file in ${host_headers} ${host_headers_extra} \
${thread_host_headers}; do \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 47995ef7d8f..4c69a2be288 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -1001,6 +1001,39 @@ parallel_builddir = ./parallel
@ENABLE_PARALLEL_TRUE@ ${parallel_srcdir}/unique_copy.h \
@ENABLE_PARALLEL_TRUE@ ${parallel_srcdir}/workstealing.h
+
+# Profile mode headers
+profile_srcdir = ${glibcxx_srcdir}/include/profile
+profile_builddir = ./profile
+profile_headers = \
+ ${profile_srcdir}/base.h \
+ ${profile_srcdir}/unordered_map \
+ ${profile_srcdir}/unordered_set \
+ ${profile_srcdir}/vector \
+ ${profile_srcdir}/bitset \
+ ${profile_srcdir}/deque \
+ ${profile_srcdir}/list \
+ ${profile_srcdir}/map \
+ ${profile_srcdir}/map.h \
+ ${profile_srcdir}/multimap.h \
+ ${profile_srcdir}/multiset.h \
+ ${profile_srcdir}/set \
+ ${profile_srcdir}/set.h \
+ ${profile_srcdir}/hashtable.h
+profile_impl_srcdir = ${glibcxx_srcdir}/include/profile/impl
+profile_impl_builddir = ./profile/impl
+profile_impl_headers = \
+ ${profile_impl_srcdir}/profiler.h \
+ ${profile_impl_srcdir}/profiler_container_size.h \
+ ${profile_impl_srcdir}/profiler_hash_func.h \
+ ${profile_impl_srcdir}/profiler_hashtable_size.h \
+ ${profile_impl_srcdir}/profiler_map_to_unordered_map.h \
+ ${profile_impl_srcdir}/profiler_node.h \
+ ${profile_impl_srcdir}/profiler_state.h \
+ ${profile_impl_srcdir}/profiler_trace.h \
+ ${profile_impl_srcdir}/profiler_vector_size.h \
+ ${profile_impl_srcdir}/profiler_vector_to_list.h
+
@GLIBCXX_C_HEADERS_EXTRA_FALSE@c_base_headers_extra =
# Some of the different "C" header models need extra files.
@@ -1083,7 +1116,8 @@ PCHFLAGS = -x c++-header $(CXXFLAGS)
allstamped = \
stamp-std stamp-bits stamp-c_base stamp-c_base_extra \
stamp-c_compatibility stamp-backward stamp-ext stamp-pb \
- stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host
+ stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host \
+ stamp-profile stamp-profile-impl
# List of all files that are created by explicit building, editing, or
@@ -1400,6 +1434,16 @@ stamp-parallel: ${parallel_headers}
@-cd ${parallel_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-parallel
+stamp-profile: ${profile_headers}
+ @-mkdir -p ${profile_builddir}
+ @-cd ${profile_builddir} && $(LN_S) $? . 2>/dev/null
+ @$(STAMP) stamp-profile
+
+stamp-profile-impl: ${profile_impl_headers}
+ @-mkdir -p ${profile_impl_builddir}
+ @-cd ${profile_impl_builddir} && $(LN_S) $? . 2>/dev/null
+ @$(STAMP) stamp-profile-impl
+
stamp-${host_alias}:
@-mkdir -p ${host_builddir}
@$(STAMP) stamp-${host_alias}
@@ -1616,6 +1660,13 @@ install-headers:
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${parallel_builddir};\
for file in $$parallel_headers_install; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${parallel_builddir}; done
+ $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_builddir} \
+ $(DESTDIR)${gxx_include_dir}/${profile_builddir}/impl
+ for file in ${profile_headers}; do \
+ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_builddir}; done
+ $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}
+ for file in ${profile_impl_headers}; do \
+ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${profile_impl_builddir}; done
$(mkinstalldirs) $(DESTDIR)${host_installdir}
for file in ${host_headers} ${host_headers_extra} \
${thread_host_headers}; do \
diff --git a/libstdc++-v3/include/backward/hash_map b/libstdc++-v3/include/backward/hash_map
index 469429ccc24..cb31687c008 100644
--- a/libstdc++-v3/include/backward/hash_map
+++ b/libstdc++-v3/include/backward/hash_map
@@ -58,7 +58,11 @@
#include "backward_warning.h"
#include <bits/c++config.h>
+#ifdef _GLIBCXX_PROFILE
+#include <profile/hashtable.h>
+#else
#include <backward/hashtable.h>
+#endif
#include <bits/concept_check.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
diff --git a/libstdc++-v3/include/backward/hash_set b/libstdc++-v3/include/backward/hash_set
index 32fa2205eea..d2bd03bb0b3 100644
--- a/libstdc++-v3/include/backward/hash_set
+++ b/libstdc++-v3/include/backward/hash_set
@@ -58,7 +58,11 @@
#include "backward_warning.h"
#include <bits/c++config.h>
+#ifdef _GLIBCXX_PROFILE
+#include <profile/hashtable.h>
+#else
#include <backward/hashtable.h>
+#endif
#include <bits/concept_check.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index d5babc31959..724f373ebae 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -85,11 +85,17 @@
# define _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL 1
#endif
+// Namespace association for profile
+#ifdef _GLIBCXX_PROFILE
+# define _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE 1
+#endif
+
#define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
// Defined if any namespace association modes are active.
#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG \
|| _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL \
+ || _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE \
|| _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
# define _GLIBCXX_USE_NAMESPACE_ASSOCIATION 1
#endif
@@ -108,6 +114,7 @@
#ifndef _GLIBCXX_USE_NAMESPACE_ASSOCIATION
# define _GLIBCXX_STD_D _GLIBCXX_STD
# define _GLIBCXX_STD_P _GLIBCXX_STD
+# define _GLIBCXX_STD_PR _GLIBCXX_STD
# define _GLIBCXX_STD std
# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) _GLIBCXX_BEGIN_NAMESPACE(X)
# define _GLIBCXX_END_NESTED_NAMESPACE _GLIBCXX_END_NAMESPACE
@@ -124,7 +131,7 @@
# endif
// debug
-# if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
# define _GLIBCXX_STD_D __norm
# define _GLIBCXX_STD_P _GLIBCXX_STD
# define _GLIBCXX_STD __cxx1998
@@ -134,7 +141,7 @@
# endif
// parallel
-# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && !_GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && !_GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
# define _GLIBCXX_STD_D _GLIBCXX_STD
# define _GLIBCXX_STD_P __norm
# define _GLIBCXX_STD __cxx1998
@@ -144,7 +151,7 @@
# endif
// debug + parallel
-# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
# define _GLIBCXX_STD_D __norm
# define _GLIBCXX_STD_P __norm
# define _GLIBCXX_STD __cxx1998
@@ -153,6 +160,21 @@
# define _GLIBCXX_EXTERN_TEMPLATE -1
# endif
+// profile
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL || _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
+# error Cannot use -D_GLIBCXX_PROFILE with -D_GLIBCXX_DEBUG or \
+ -D_GLIBCXX_PARALLEL
+# endif
+# define _GLIBCXX_STD_D __norm
+# define _GLIBCXX_STD_P _GLIBCXX_STD
+# define _GLIBCXX_STD_PR __norm
+# define _GLIBCXX_STD __cxx1998
+# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY_ATTR(default) {
+# define _GLIBCXX_END_NAMESPACE }
+# define _GLIBCXX_EXTERN_TEMPLATE -1
+# endif
+
# if __NO_INLINE__ && !__GXX_WEAK__
# warning currently using namespace associated mode which may fail \
without inlining due to lack of weak symbols
@@ -163,7 +185,7 @@
#endif
// Namespace associations for debug mode.
-#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
+#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
namespace std
{
namespace __norm { }
@@ -182,6 +204,16 @@ namespace std
}
#endif
+// Namespace associations for profile mode
+#if _GLIBCXX_NAMESPACE_ASSOCIATION_PROFILE
+namespace std
+{
+ namespace __norm { }
+ inline namespace __profile { }
+ inline namespace __cxx1998 { }
+}
+#endif
+
// Namespace associations for versioning mode.
#if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
namespace std
diff --git a/libstdc++-v3/include/profile/base.h b/libstdc++-v3/include/profile/base.h
new file mode 100644
index 00000000000..de7bfe9a56f
--- /dev/null
+++ b/libstdc++-v3/include/profile/base.h
@@ -0,0 +1,68 @@
+// -*- C++ -*-
+
+// Copyright (C) 2009 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 profile/base.h
+ * @brief Sequential helper functions.
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+// Written by Lixia Liu
+
+#ifndef _GLIBCXX_PROFILE_BASE_H
+#define _GLIBCXX_PROFILE_BASE_H 1
+
+#include <cstdio>
+#include <functional>
+#include <bits/c++config.h>
+#include <profile/impl/profiler.h>
+
+// Profiling mode namespaces.
+
+/**
+ * @namespace std::__profile
+ * @brief GNU profile code, replaces standard behavior with profile behavior.
+ */
+namespace std
+{
+ namespace __profile { }
+}
+
+/**
+ * @namespace __gnu_profile
+ * @brief GNU profile code for public use.
+ */
+namespace __gnu_profile
+{
+ // Import all the profile versions of components in namespace std.
+ using namespace std::__profile;
+}
+
+
+#endif /* _GLIBCXX_PROFILE_BASE_H */
diff --git a/libstdc++-v3/include/profile/bitset b/libstdc++-v3/include/profile/bitset
new file mode 100644
index 00000000000..96a59ea4ad9
--- /dev/null
+++ b/libstdc++-v3/include/profile/bitset
@@ -0,0 +1,345 @@
+// Profiling bitset implementation -*- C++ -*-
+
+// Copyright (C) 2009 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 3, 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/bitset
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_BITSET
+#define _GLIBCXX_PROFILE_BITSET
+
+#include <bitset>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Bitset wrapper with performance instrumentation. */
+ template<size_t _Nb>
+ class bitset
+ : public _GLIBCXX_STD_D::bitset<_Nb>
+ {
+ typedef _GLIBCXX_STD_D::bitset<_Nb> _Base;
+
+ public:
+ // bit reference:
+ class reference
+ : private _Base::reference
+ {
+ typedef typename _Base::reference _Base_ref;
+
+ friend class bitset;
+ reference();
+
+ reference(const _Base_ref& __base, bitset* __seq)
+ : _Base_ref(__base)
+ { }
+
+ public:
+ reference(const reference& __x)
+ : _Base_ref(__x)
+ { }
+
+ reference&
+ operator=(bool __x)
+ {
+ *static_cast<_Base_ref*>(this) = __x;
+ return *this;
+ }
+
+ reference&
+ operator=(const reference& __x)
+ {
+ *static_cast<_Base_ref*>(this) = __x;
+ return *this;
+ }
+
+ bool
+ operator~() const
+ {
+ return ~(*static_cast<const _Base_ref*>(this));
+ }
+
+ operator bool() const
+ {
+ return *static_cast<const _Base_ref*>(this);
+ }
+
+ reference&
+ flip()
+ {
+ _Base_ref::flip();
+ return *this;
+ }
+ };
+
+ // 23.3.5.1 constructors:
+ bitset() : _Base() { }
+
+ bitset(unsigned long __val) : _Base(__val) { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ explicit
+ bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
+ typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
+ __pos = 0,
+ typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
+ __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
+ : _Base(__str, __pos, __n) { }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 396. what are characters zero and one.
+ template<class _CharT, class _Traits, class _Alloc>
+ bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
+ typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
+ __pos,
+ typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
+ __n,
+ _CharT __zero, _CharT __one = _CharT('1'))
+ : _Base(__str, __pos, __n, __zero, __one) { }
+
+ bitset(const _Base& __x) : _Base(__x) { }
+
+ // 23.3.5.2 bitset operations:
+ bitset<_Nb>&
+ operator&=(const bitset<_Nb>& __rhs)
+ {
+ _M_base() &= __rhs;
+ return *this;
+ }
+
+ bitset<_Nb>&
+ operator|=(const bitset<_Nb>& __rhs)
+ {
+ _M_base() |= __rhs;
+ return *this;
+ }
+
+ bitset<_Nb>&
+ operator^=(const bitset<_Nb>& __rhs)
+ {
+ _M_base() ^= __rhs;
+ return *this;
+ }
+
+ bitset<_Nb>&
+ operator<<=(size_t __pos)
+ {
+ _M_base() <<= __pos;
+ return *this;
+ }
+
+ bitset<_Nb>&
+ operator>>=(size_t __pos)
+ {
+ _M_base() >>= __pos;
+ return *this;
+ }
+
+ bitset<_Nb>&
+ set()
+ {
+ _Base::set();
+ return *this;
+ }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 186. bitset::set() second parameter should be bool
+ bitset<_Nb>&
+ set(size_t __pos, bool __val = true)
+ {
+ _Base::set(__pos, __val);
+ return *this;
+ }
+
+ bitset<_Nb>&
+ reset()
+ {
+ _Base::reset();
+ return *this;
+ }
+
+ bitset<_Nb>&
+ reset(size_t __pos)
+ {
+ _Base::reset(__pos);
+ return *this;
+ }
+
+ bitset<_Nb> operator~() const { return bitset(~_M_base()); }
+
+ bitset<_Nb>&
+ flip()
+ {
+ _Base::flip();
+ return *this;
+ }
+
+ bitset<_Nb>&
+ flip(size_t __pos)
+ {
+ _Base::flip(__pos);
+ return *this;
+ }
+
+ // element access:
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 11. Bitset minor problems
+ reference
+ operator[](size_t __pos)
+ {
+ return reference(_M_base()[__pos], this);
+ }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 11. Bitset minor problems
+ bool
+ operator[](size_t __pos) const
+ {
+ return _M_base()[__pos];
+ }
+
+ using _Base::to_ulong;
+
+ template <typename _CharT, typename _Traits, typename _Alloc>
+ std::basic_string<_CharT, _Traits, _Alloc>
+ to_string() const
+ { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 396. what are characters zero and one.
+ template<class _CharT, class _Traits, class _Alloc>
+ std::basic_string<_CharT, _Traits, _Alloc>
+ to_string(_CharT __zero, _CharT __one = _CharT('1')) const
+ {
+ return _M_base().template
+ to_string<_CharT, _Traits, _Alloc>(__zero, __one);
+ }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 434. bitset::to_string() hard to use.
+ template<typename _CharT, typename _Traits>
+ std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
+ to_string() const
+ { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 853. to_string needs updating with zero and one.
+ template<class _CharT, class _Traits>
+ std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
+ to_string(_CharT __zero, _CharT __one = _CharT('1')) const
+ { return to_string<_CharT, _Traits,
+ std::allocator<_CharT> >(__zero, __one); }
+
+ template<typename _CharT>
+ std::basic_string<_CharT, std::char_traits<_CharT>,
+ std::allocator<_CharT> >
+ to_string() const
+ {
+ return to_string<_CharT, std::char_traits<_CharT>,
+ std::allocator<_CharT> >();
+ }
+
+ template<class _CharT>
+ std::basic_string<_CharT, std::char_traits<_CharT>,
+ std::allocator<_CharT> >
+ to_string(_CharT __zero, _CharT __one = _CharT('1')) const
+ {
+ return to_string<_CharT, std::char_traits<_CharT>,
+ std::allocator<_CharT> >(__zero, __one);
+ }
+
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >
+ to_string() const
+ {
+ return to_string<char,std::char_traits<char>,std::allocator<char> >();
+ }
+
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >
+ to_string(char __zero, char __one = '1') const
+ {
+ return to_string<char, std::char_traits<char>,
+ std::allocator<char> >(__zero, __one);
+ }
+
+ using _Base::count;
+ using _Base::size;
+
+ bool
+ operator==(const bitset<_Nb>& __rhs) const
+ { return _M_base() == __rhs; }
+
+ bool
+ operator!=(const bitset<_Nb>& __rhs) const
+ { return _M_base() != __rhs; }
+
+ using _Base::test;
+ using _Base::all;
+ using _Base::any;
+ using _Base::none;
+
+ bitset<_Nb>
+ operator<<(size_t __pos) const
+ { return bitset<_Nb>(_M_base() << __pos); }
+
+ bitset<_Nb>
+ operator>>(size_t __pos) const
+ { return bitset<_Nb>(_M_base() >> __pos); }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+ };
+
+ template<size_t _Nb>
+ bitset<_Nb>
+ operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
+ { return bitset<_Nb>(__x) &= __y; }
+
+ template<size_t _Nb>
+ bitset<_Nb>
+ operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
+ { return bitset<_Nb>(__x) |= __y; }
+
+ template<size_t _Nb>
+ bitset<_Nb>
+ operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
+ { return bitset<_Nb>(__x) ^= __y; }
+
+ template<typename _CharT, typename _Traits, size_t _Nb>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
+ { return __is >> __x._M_base(); }
+
+ template<typename _CharT, typename _Traits, size_t _Nb>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const bitset<_Nb>& __x)
+ { return __os << __x._M_base(); }
+} // namespace __profile
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/profile/deque b/libstdc++-v3/include/profile/deque
new file mode 100644
index 00000000000..6ba3679e0c6
--- /dev/null
+++ b/libstdc++-v3/include/profile/deque
@@ -0,0 +1,420 @@
+// Profiling deque implementation -*- C++ -*-
+
+// Copyright (C) 2009 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 3, 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/deque
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_DEQUE
+#define _GLIBCXX_PROFILE_DEQUE 1
+
+#include <deque>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Deque wrapper with performance instrumentation. */
+ template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
+ class deque
+ : public _GLIBCXX_STD_D::deque<_Tp, _Allocator>
+ {
+ typedef _GLIBCXX_STD_D::deque<_Tp, _Allocator> _Base;
+
+ public:
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef typename _Base::reverse_iterator reverse_iterator;
+ typedef typename _Base::const_reverse_iterator const_reverse_iterator;
+
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::difference_type difference_type;
+
+ typedef _Tp value_type;
+ typedef _Allocator allocator_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Base::const_pointer const_pointer;
+
+ // 23.2.1.1 construct/copy/destroy:
+ explicit deque(const _Allocator& __a = _Allocator())
+ : _Base(__a) { }
+
+ explicit deque(size_type __n, const _Tp& __value = _Tp(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__n, __value, __a) { }
+
+ template<class _InputIterator>
+ deque(_InputIterator __first, _InputIterator __last,
+ const _Allocator& __a = _Allocator())
+ : _Base(__first, __last, __a)
+ { }
+
+ deque(const deque& __x)
+ : _Base(__x) { }
+
+ deque(const _Base& __x)
+ : _Base(__x) { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ deque(deque&& __x)
+ : _Base(std::forward<deque>(__x))
+ { }
+
+ deque(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __a) { }
+#endif
+
+ ~deque() { }
+
+ deque&
+ operator=(const deque& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ deque&
+ operator=(deque&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ deque&
+ operator=(initializer_list<value_type> __l)
+ {
+ *static_cast<_Base*>(this) = __l;
+ return *this;
+ }
+#endif
+
+ template<class _InputIterator>
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
+ _Base::assign(__first, __last);
+ }
+
+ void
+ assign(size_type __n, const _Tp& __t)
+ {
+ _Base::assign(__n, __t);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ assign(initializer_list<value_type> __l)
+ {
+ _Base::assign(__l);
+ }
+#endif
+
+ using _Base::get_allocator;
+
+ // iterators:
+ iterator
+ begin()
+ { return iterator(_Base::begin()); }
+
+ const_iterator
+ begin() const
+ { return const_iterator(_Base::begin()); }
+
+ iterator
+ end()
+ { return iterator(_Base::end()); }
+
+ const_iterator
+ end() const
+ { return const_iterator(_Base::end()); }
+
+ 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()); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const_iterator
+ cbegin() const
+ { return const_iterator(_Base::begin()); }
+
+ const_iterator
+ cend() const
+ { return const_iterator(_Base::end()); }
+
+ const_reverse_iterator
+ crbegin() const
+ { return const_reverse_iterator(end()); }
+
+ const_reverse_iterator
+ crend() const
+ { return const_reverse_iterator(begin()); }
+#endif
+
+ // 23.2.1.2 capacity:
+ using _Base::size;
+ using _Base::max_size;
+
+ void
+ resize(size_type __sz, _Tp __c = _Tp())
+ {
+ _Base::resize(__sz, __c);
+ }
+
+ using _Base::empty;
+
+ // element access:
+ reference
+ operator[](size_type __n)
+ {
+ return _M_base()[__n];
+ }
+
+ const_reference
+ operator[](size_type __n) const
+ {
+ return _M_base()[__n];
+ }
+
+ using _Base::at;
+
+ reference
+ front()
+ {
+ return _Base::front();
+ }
+
+ const_reference
+ front() const
+ {
+ return _Base::front();
+ }
+
+ reference
+ back()
+ {
+ return _Base::back();
+ }
+
+ const_reference
+ back() const
+ {
+ return _Base::back();
+ }
+
+ // 23.2.1.3 modifiers:
+ void
+ push_front(const _Tp& __x)
+ {
+ _Base::push_front(__x);
+ }
+
+ void
+ push_back(const _Tp& __x)
+ {
+ _Base::push_back(__x);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ push_front(_Tp&& __x)
+ { emplace_front(std::move(__x)); }
+
+ void
+ push_back(_Tp&& __x)
+ { emplace_back(std::move(__x)); }
+
+ template<typename... _Args>
+ void
+ emplace_front(_Args&&... __args)
+ {
+ _Base::emplace_front(std::forward<_Args>(__args)...);
+ }
+
+ template<typename... _Args>
+ void
+ emplace_back(_Args&&... __args)
+ {
+ _Base::emplace_back(std::forward<_Args>(__args)...);
+ }
+
+ template<typename... _Args>
+ iterator
+ emplace(iterator __position, _Args&&... __args)
+ {
+ typename _Base::iterator __res = _Base::emplace(__position,
+ std::forward<_Args>(__args)...);
+ return iterator(__res);
+ }
+#endif
+
+ iterator
+ insert(iterator __position, const _Tp& __x)
+ {
+ typename _Base::iterator __res = _Base::insert(__position, __x);
+ return iterator(__res);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ iterator
+ insert(iterator __position, _Tp&& __x)
+ { return emplace(__position, std::move(__x)); }
+
+ void
+ insert(iterator __p, initializer_list<value_type> __l)
+ {
+ _Base::insert(__p, __l);
+ }
+#endif
+
+ void
+ insert(iterator __position, size_type __n, const _Tp& __x)
+ {
+ _Base::insert(__position, __n, __x);
+ }
+
+ template<class _InputIterator>
+ void
+ insert(iterator __position,
+ _InputIterator __first, _InputIterator __last)
+ {
+ _Base::insert(__position, __first, __last);
+ }
+
+ void
+ pop_front()
+ {
+ _Base::pop_front();
+ }
+
+ void
+ pop_back()
+ {
+ _Base::pop_back();
+ }
+
+ iterator
+ erase(iterator __position)
+ {
+ if (__position == begin() || __position == end()-1)
+ {
+ return iterator(_Base::erase(__position));
+ }
+ else
+ {
+ typename _Base::iterator __res = _Base::erase(__position);
+ return iterator(__res);
+ }
+ }
+
+ iterator
+ erase(iterator __first, iterator __last)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 151. can't currently clear() empty container
+ return iterator(_Base::erase(__first, __last));
+ }
+
+ void
+ swap(deque& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ {
+ _Base::clear();
+ }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+ };
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator==(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() == __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator!=(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() != __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() < __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<=(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() <= __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>=(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() >= __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() > __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+} // namespace __profile
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/profile/hashtable.h b/libstdc++-v3/include/profile/hashtable.h
new file mode 100644
index 00000000000..20891877121
--- /dev/null
+++ b/libstdc++-v3/include/profile/hashtable.h
@@ -0,0 +1,1151 @@
+// Hashtable implementation used by containers -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+// 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// 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 profile/hashtable.h copied from backward/hashtable.h
+ * This file is a GNU extension to the Standard C++ Library (possibly
+ * containing extensions from the HP/SGI STL subset).
+ */
+
+#ifndef _HASHTABLE_H
+#define _HASHTABLE_H 1
+
+// Hashtable class, used to implement the hashed associative containers
+// hash_set, hash_map, hash_multiset, and hash_multimap.
+// Skip instrumentation on vector.
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <bits/stl_function.h>
+#include <backward/hash_fun.h>
+#include <profile/base.h>
+
+_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+
+ using std::size_t;
+ using std::ptrdiff_t;
+ using std::forward_iterator_tag;
+ using std::input_iterator_tag;
+ using std::_Construct;
+ using std::_Destroy;
+ using std::distance;
+ using std::_GLIBCXX_STD_D::vector;
+ using std::pair;
+ using std::__iterator_category;
+
+ template<class _Val>
+ struct _Hashtable_node
+ {
+ _Hashtable_node* _M_next;
+ _Val _M_val;
+ };
+
+ template<class _Val, class _Key, class _HashFcn, class _ExtractKey,
+ class _EqualKey, class _Alloc = std::allocator<_Val> >
+ class hashtable;
+
+ template<class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+ struct _Hashtable_iterator;
+
+ template<class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+ struct _Hashtable_const_iterator;
+
+ template<class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+ struct _Hashtable_iterator
+ {
+ typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
+ _Hashtable;
+ typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
+ _ExtractKey, _EqualKey, _Alloc>
+ iterator;
+ typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
+ _ExtractKey, _EqualKey, _Alloc>
+ const_iterator;
+ typedef _Hashtable_node<_Val> _Node;
+ typedef forward_iterator_tag iterator_category;
+ typedef _Val value_type;
+ typedef ptrdiff_t difference_type;
+ typedef size_t size_type;
+ typedef _Val& reference;
+ typedef _Val* pointer;
+
+ _Node* _M_cur;
+ _Hashtable* _M_ht;
+
+ _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
+ : _M_cur(__n), _M_ht(__tab) { }
+
+ _Hashtable_iterator() { }
+
+ reference
+ operator*() const
+ { return _M_cur->_M_val; }
+
+ pointer
+ operator->() const
+ { return &(operator*()); }
+
+ iterator&
+ operator++();
+
+ iterator
+ operator++(int);
+
+ bool
+ operator==(const iterator& __it) const
+ { return _M_cur == __it._M_cur; }
+
+ bool
+ operator!=(const iterator& __it) const
+ { return _M_cur != __it._M_cur; }
+ };
+
+ template<class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+ struct _Hashtable_const_iterator
+ {
+ typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
+ _Hashtable;
+ typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
+ _ExtractKey,_EqualKey,_Alloc>
+ iterator;
+ typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
+ _ExtractKey, _EqualKey, _Alloc>
+ const_iterator;
+ typedef _Hashtable_node<_Val> _Node;
+
+ typedef forward_iterator_tag iterator_category;
+ typedef _Val value_type;
+ typedef ptrdiff_t difference_type;
+ typedef size_t size_type;
+ typedef const _Val& reference;
+ typedef const _Val* pointer;
+
+ const _Node* _M_cur;
+ const _Hashtable* _M_ht;
+
+ _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
+ : _M_cur(__n), _M_ht(__tab) { }
+
+ _Hashtable_const_iterator() { }
+
+ _Hashtable_const_iterator(const iterator& __it)
+ : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { }
+
+ reference
+ operator*() const
+ { return _M_cur->_M_val; }
+
+ pointer
+ operator->() const
+ { return &(operator*()); }
+
+ const_iterator&
+ operator++();
+
+ const_iterator
+ operator++(int);
+
+ bool
+ operator==(const const_iterator& __it) const
+ { return _M_cur == __it._M_cur; }
+
+ bool
+ operator!=(const const_iterator& __it) const
+ { return _M_cur != __it._M_cur; }
+ };
+
+ // Note: assumes long is at least 32 bits.
+ enum { _S_num_primes = 28 };
+
+ static const unsigned long __stl_prime_list[_S_num_primes] =
+ {
+ 53ul, 97ul, 193ul, 389ul, 769ul,
+ 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
+ 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
+ 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
+ 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
+ 1610612741ul, 3221225473ul, 4294967291ul
+ };
+
+ inline unsigned long
+ __stl_next_prime(unsigned long __n)
+ {
+ const unsigned long* __first = __stl_prime_list;
+ const unsigned long* __last = __stl_prime_list + (int)_S_num_primes;
+ const unsigned long* pos = std::lower_bound(__first, __last, __n);
+ return pos == __last ? *(__last - 1) : *pos;
+ }
+
+ // Forward declaration of operator==.
+ template<class _Val, class _Key, class _HF, class _Ex,
+ class _Eq, class _All>
+ class hashtable;
+
+ template<class _Val, class _Key, class _HF, class _Ex,
+ class _Eq, class _All>
+ bool
+ operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
+ const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
+
+ // Hashtables handle allocators a bit differently than other
+ // containers do. If we're using standard-conforming allocators, then
+ // a hashtable unconditionally has a member variable to hold its
+ // allocator, even if it so happens that all instances of the
+ // allocator type are identical. This is because, for hashtables,
+ // this extra storage is negligible. Additionally, a base class
+ // wouldn't serve any other purposes; it wouldn't, for example,
+ // simplify the exception-handling code.
+ template<class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+ class hashtable
+ {
+ public:
+ typedef _Key key_type;
+ typedef _Val value_type;
+ typedef _HashFcn hasher;
+ typedef _EqualKey key_equal;
+
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ hasher
+ hash_funct() const
+ { return _M_hash; }
+
+ key_equal
+ key_eq() const
+ { return _M_equals; }
+
+ private:
+ typedef _Hashtable_node<_Val> _Node;
+
+ public:
+ typedef typename _Alloc::template rebind<value_type>::other allocator_type;
+ allocator_type
+ get_allocator() const
+ { return _M_node_allocator; }
+
+ private:
+ typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
+ typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
+ typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
+
+ _Node_Alloc _M_node_allocator;
+
+ _Node*
+ _M_get_node()
+ { return _M_node_allocator.allocate(1); }
+
+ void
+ _M_put_node(_Node* __p)
+ { _M_node_allocator.deallocate(__p, 1); }
+
+ private:
+ hasher _M_hash;
+ key_equal _M_equals;
+ _ExtractKey _M_get_key;
+ _Vector_type _M_buckets;
+ size_type _M_num_elements;
+
+ public:
+ typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
+ _EqualKey, _Alloc>
+ iterator;
+ typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
+ _EqualKey, _Alloc>
+ const_iterator;
+
+ friend struct
+ _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;
+
+ friend struct
+ _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
+ _EqualKey, _Alloc>;
+
+ public:
+ hashtable(size_type __n, const _HashFcn& __hf,
+ const _EqualKey& __eql, const _ExtractKey& __ext,
+ const allocator_type& __a = allocator_type())
+ : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
+ _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
+ { _M_initialize_buckets(__n); }
+
+ hashtable(size_type __n, const _HashFcn& __hf,
+ const _EqualKey& __eql,
+ const allocator_type& __a = allocator_type())
+ : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
+ _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
+ { _M_initialize_buckets(__n); }
+
+ hashtable(const hashtable& __ht)
+ : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
+ _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
+ _M_buckets(__ht.get_allocator()), _M_num_elements(0)
+ { _M_copy_from(__ht); }
+
+ hashtable&
+ operator= (const hashtable& __ht)
+ {
+ if (&__ht != this)
+ {
+ clear();
+ _M_hash = __ht._M_hash;
+ _M_equals = __ht._M_equals;
+ _M_get_key = __ht._M_get_key;
+ _M_copy_from(__ht);
+ }
+ return *this;
+ }
+
+ ~hashtable()
+ { clear(); }
+
+ size_type
+ size() const
+ { return _M_num_elements; }
+
+ size_type
+ max_size() const
+ { return size_type(-1); }
+
+ bool
+ empty() const
+ { return size() == 0; }
+
+ void
+ swap(hashtable& __ht)
+ {
+ std::swap(_M_hash, __ht._M_hash);
+ std::swap(_M_equals, __ht._M_equals);
+ std::swap(_M_get_key, __ht._M_get_key);
+ _M_buckets.swap(__ht._M_buckets);
+ std::swap(_M_num_elements, __ht._M_num_elements);
+ }
+
+ iterator
+ begin()
+ {
+ for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
+ if (_M_buckets[__n])
+ return iterator(_M_buckets[__n], this);
+ return end();
+ }
+
+ iterator
+ end()
+ { return iterator(0, this); }
+
+ const_iterator
+ begin() const
+ {
+ for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
+ if (_M_buckets[__n])
+ return const_iterator(_M_buckets[__n], this);
+ return end();
+ }
+
+ const_iterator
+ end() const
+ { return const_iterator(0, this); }
+
+ template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq,
+ class _Al>
+ friend bool
+ operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
+ const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
+
+ public:
+ size_type
+ bucket_count() const
+ { return _M_buckets.size(); }
+
+ size_type
+ max_bucket_count() const
+ { return __stl_prime_list[(int)_S_num_primes - 1]; }
+
+ size_type
+ elems_in_bucket(size_type __bucket) const
+ {
+ size_type __result = 0;
+ for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
+ __result += 1;
+ return __result;
+ }
+
+ pair<iterator, bool>
+ insert_unique(const value_type& __obj)
+ {
+ resize(_M_num_elements + 1);
+ return insert_unique_noresize(__obj);
+ }
+
+ iterator
+ insert_equal(const value_type& __obj)
+ {
+ resize(_M_num_elements + 1);
+ return insert_equal_noresize(__obj);
+ }
+
+ pair<iterator, bool>
+ insert_unique_noresize(const value_type& __obj);
+
+ iterator
+ insert_equal_noresize(const value_type& __obj);
+
+ template<class _InputIterator>
+ void
+ insert_unique(_InputIterator __f, _InputIterator __l)
+ { insert_unique(__f, __l, __iterator_category(__f)); }
+
+ template<class _InputIterator>
+ void
+ insert_equal(_InputIterator __f, _InputIterator __l)
+ { insert_equal(__f, __l, __iterator_category(__f)); }
+
+ template<class _InputIterator>
+ void
+ insert_unique(_InputIterator __f, _InputIterator __l,
+ input_iterator_tag)
+ {
+ for ( ; __f != __l; ++__f)
+ insert_unique(*__f);
+ }
+
+ template<class _InputIterator>
+ void
+ insert_equal(_InputIterator __f, _InputIterator __l,
+ input_iterator_tag)
+ {
+ for ( ; __f != __l; ++__f)
+ insert_equal(*__f);
+ }
+
+ template<class _ForwardIterator>
+ void
+ insert_unique(_ForwardIterator __f, _ForwardIterator __l,
+ forward_iterator_tag)
+ {
+ size_type __n = distance(__f, __l);
+ resize(_M_num_elements + __n);
+ for ( ; __n > 0; --__n, ++__f)
+ insert_unique_noresize(*__f);
+ }
+
+ template<class _ForwardIterator>
+ void
+ insert_equal(_ForwardIterator __f, _ForwardIterator __l,
+ forward_iterator_tag)
+ {
+ size_type __n = distance(__f, __l);
+ resize(_M_num_elements + __n);
+ for ( ; __n > 0; --__n, ++__f)
+ insert_equal_noresize(*__f);
+ }
+
+ reference
+ find_or_insert(const value_type& __obj);
+
+ iterator
+ find(const key_type& __key)
+ {
+ size_type __n = _M_bkt_num_key(__key);
+ _Node* __first;
+ for (__first = _M_buckets[__n];
+ __first && !_M_equals(_M_get_key(__first->_M_val), __key);
+ __first = __first->_M_next)
+ { }
+ return iterator(__first, this);
+ }
+
+ const_iterator
+ find(const key_type& __key) const
+ {
+ size_type __n = _M_bkt_num_key(__key);
+ const _Node* __first;
+ for (__first = _M_buckets[__n];
+ __first && !_M_equals(_M_get_key(__first->_M_val), __key);
+ __first = __first->_M_next)
+ { }
+ return const_iterator(__first, this);
+ }
+
+ size_type
+ count(const key_type& __key) const
+ {
+ const size_type __n = _M_bkt_num_key(__key);
+ size_type __result = 0;
+
+ for (const _Node* __cur = _M_buckets[__n]; __cur;
+ __cur = __cur->_M_next)
+ if (_M_equals(_M_get_key(__cur->_M_val), __key))
+ ++__result;
+ return __result;
+ }
+
+ pair<iterator, iterator>
+ equal_range(const key_type& __key);
+
+ pair<const_iterator, const_iterator>
+ equal_range(const key_type& __key) const;
+
+ size_type
+ erase(const key_type& __key);
+
+ void
+ erase(const iterator& __it);
+
+ void
+ erase(iterator __first, iterator __last);
+
+ void
+ erase(const const_iterator& __it);
+
+ void
+ erase(const_iterator __first, const_iterator __last);
+
+ void
+ resize(size_type __num_elements_hint);
+
+ void
+ clear();
+
+ private:
+ size_type
+ _M_next_size(size_type __n) const
+ { return __stl_next_prime(__n); }
+
+ void
+ _M_initialize_buckets(size_type __n)
+ {
+ const size_type __n_buckets = _M_next_size(__n);
+ _M_buckets.reserve(__n_buckets);
+ _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
+ _M_num_elements = 0;
+ __profcxx_hashtable_construct(this, __n_buckets);
+ __profcxx_hashtable_construct2(this);
+ }
+
+ size_type
+ _M_bkt_num_key(const key_type& __key) const
+ { return _M_bkt_num_key(__key, _M_buckets.size()); }
+
+ size_type
+ _M_bkt_num(const value_type& __obj) const
+ { return _M_bkt_num_key(_M_get_key(__obj)); }
+
+ size_type
+ _M_bkt_num_key(const key_type& __key, size_t __n) const
+ { return _M_hash(__key) % __n; }
+
+ size_type
+ _M_bkt_num(const value_type& __obj, size_t __n) const
+ { return _M_bkt_num_key(_M_get_key(__obj), __n); }
+
+ _Node*
+ _M_new_node(const value_type& __obj)
+ {
+ _Node* __n = _M_get_node();
+ __n->_M_next = 0;
+ try
+ {
+ this->get_allocator().construct(&__n->_M_val, __obj);
+ return __n;
+ }
+ catch(...)
+ {
+ _M_put_node(__n);
+ __throw_exception_again;
+ }
+ }
+
+ void
+ _M_delete_node(_Node* __n)
+ {
+ this->get_allocator().destroy(&__n->_M_val);
+ _M_put_node(__n);
+ }
+
+ void
+ _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
+
+ void
+ _M_erase_bucket(const size_type __n, _Node* __last);
+
+ void
+ _M_copy_from(const hashtable& __ht);
+ };
+
+ template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+ _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
+ _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
+ operator++()
+ {
+ const _Node* __old = _M_cur;
+ _M_cur = _M_cur->_M_next;
+ if (!_M_cur)
+ {
+ size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
+ while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
+ _M_cur = _M_ht->_M_buckets[__bucket];
+ }
+ return *this;
+ }
+
+ template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+ inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
+ _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
+ operator++(int)
+ {
+ iterator __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+ _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
+ _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
+ operator++()
+ {
+ const _Node* __old = _M_cur;
+ _M_cur = _M_cur->_M_next;
+ if (!_M_cur)
+ {
+ size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
+ while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
+ _M_cur = _M_ht->_M_buckets[__bucket];
+ }
+ return *this;
+ }
+
+ template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+ inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
+ _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
+ operator++(int)
+ {
+ const_iterator __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ bool
+ operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
+ const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
+ {
+ typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
+
+ if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
+ return false;
+
+ for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
+ {
+ _Node* __cur1 = __ht1._M_buckets[__n];
+ _Node* __cur2 = __ht2._M_buckets[__n];
+ // Check same length of lists
+ for (; __cur1 && __cur2;
+ __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
+ { }
+ if (__cur1 || __cur2)
+ return false;
+ // Now check one's elements are in the other
+ for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
+ __cur1 = __cur1->_M_next)
+ {
+ bool _found__cur1 = false;
+ for (__cur2 = __ht2._M_buckets[__n];
+ __cur2; __cur2 = __cur2->_M_next)
+ {
+ if (__cur1->_M_val == __cur2->_M_val)
+ {
+ _found__cur1 = true;
+ break;
+ }
+ }
+ if (!_found__cur1)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ inline bool
+ operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
+ const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
+ { return !(__ht1 == __ht2); }
+
+ template<class _Val, class _Key, class _HF, class _Extract, class _EqKey,
+ class _All>
+ inline void
+ swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
+ hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
+ { __ht1.swap(__ht2); }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ insert_unique_noresize(const value_type& __obj)
+ {
+ const size_type __n = _M_bkt_num(__obj);
+ _Node* __first = _M_buckets[__n];
+
+ for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
+ if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
+ return pair<iterator, bool>(iterator(__cur, this), false);
+
+ _Node* __tmp = _M_new_node(__obj);
+ __tmp->_M_next = __first;
+ _M_buckets[__n] = __tmp;
+ ++_M_num_elements;
+ return pair<iterator, bool>(iterator(__tmp, this), true);
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ insert_equal_noresize(const value_type& __obj)
+ {
+ const size_type __n = _M_bkt_num(__obj);
+ _Node* __first = _M_buckets[__n];
+
+ for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
+ if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
+ {
+ _Node* __tmp = _M_new_node(__obj);
+ __tmp->_M_next = __cur->_M_next;
+ __cur->_M_next = __tmp;
+ ++_M_num_elements;
+ return iterator(__tmp, this);
+ }
+
+ _Node* __tmp = _M_new_node(__obj);
+ __tmp->_M_next = __first;
+ _M_buckets[__n] = __tmp;
+ ++_M_num_elements;
+ return iterator(__tmp, this);
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ find_or_insert(const value_type& __obj)
+ {
+ resize(_M_num_elements + 1);
+
+ size_type __n = _M_bkt_num(__obj);
+ _Node* __first = _M_buckets[__n];
+
+ for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
+ if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
+ return __cur->_M_val;
+
+ _Node* __tmp = _M_new_node(__obj);
+ __tmp->_M_next = __first;
+ _M_buckets[__n] = __tmp;
+ ++_M_num_elements;
+ return __tmp->_M_val;
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
+ typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ equal_range(const key_type& __key)
+ {
+ typedef pair<iterator, iterator> _Pii;
+ const size_type __n = _M_bkt_num_key(__key);
+
+ for (_Node* __first = _M_buckets[__n]; __first;
+ __first = __first->_M_next)
+ if (_M_equals(_M_get_key(__first->_M_val), __key))
+ {
+ for (_Node* __cur = __first->_M_next; __cur;
+ __cur = __cur->_M_next)
+ if (!_M_equals(_M_get_key(__cur->_M_val), __key))
+ return _Pii(iterator(__first, this), iterator(__cur, this));
+ for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
+ if (_M_buckets[__m])
+ return _Pii(iterator(__first, this),
+ iterator(_M_buckets[__m], this));
+ return _Pii(iterator(__first, this), end());
+ }
+ return _Pii(end(), end());
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
+ typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ equal_range(const key_type& __key) const
+ {
+ typedef pair<const_iterator, const_iterator> _Pii;
+ const size_type __n = _M_bkt_num_key(__key);
+
+ for (const _Node* __first = _M_buckets[__n]; __first;
+ __first = __first->_M_next)
+ {
+ if (_M_equals(_M_get_key(__first->_M_val), __key))
+ {
+ for (const _Node* __cur = __first->_M_next; __cur;
+ __cur = __cur->_M_next)
+ if (!_M_equals(_M_get_key(__cur->_M_val), __key))
+ return _Pii(const_iterator(__first, this),
+ const_iterator(__cur, this));
+ for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
+ if (_M_buckets[__m])
+ return _Pii(const_iterator(__first, this),
+ const_iterator(_M_buckets[__m], this));
+ return _Pii(const_iterator(__first, this), end());
+ }
+ }
+ return _Pii(end(), end());
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ erase(const key_type& __key)
+ {
+ const size_type __n = _M_bkt_num_key(__key);
+ _Node* __first = _M_buckets[__n];
+ size_type __erased = 0;
+
+ if (__first)
+ {
+ _Node* __cur = __first;
+ _Node* __next = __cur->_M_next;
+ while (__next)
+ {
+ if (_M_equals(_M_get_key(__next->_M_val), __key))
+ {
+ __cur->_M_next = __next->_M_next;
+ _M_delete_node(__next);
+ __next = __cur->_M_next;
+ ++__erased;
+ --_M_num_elements;
+ }
+ else
+ {
+ __cur = __next;
+ __next = __cur->_M_next;
+ }
+ }
+ if (_M_equals(_M_get_key(__first->_M_val), __key))
+ {
+ _M_buckets[__n] = __first->_M_next;
+ _M_delete_node(__first);
+ ++__erased;
+ --_M_num_elements;
+ }
+ }
+ return __erased;
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ erase(const iterator& __it)
+ {
+ _Node* __p = __it._M_cur;
+ if (__p)
+ {
+ const size_type __n = _M_bkt_num(__p->_M_val);
+ _Node* __cur = _M_buckets[__n];
+
+ if (__cur == __p)
+ {
+ _M_buckets[__n] = __cur->_M_next;
+ _M_delete_node(__cur);
+ --_M_num_elements;
+ }
+ else
+ {
+ _Node* __next = __cur->_M_next;
+ while (__next)
+ {
+ if (__next == __p)
+ {
+ __cur->_M_next = __next->_M_next;
+ _M_delete_node(__next);
+ --_M_num_elements;
+ break;
+ }
+ else
+ {
+ __cur = __next;
+ __next = __cur->_M_next;
+ }
+ }
+ }
+ }
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ erase(iterator __first, iterator __last)
+ {
+ size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
+ : _M_buckets.size();
+
+ size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
+ : _M_buckets.size();
+
+ if (__first._M_cur == __last._M_cur)
+ return;
+ else if (__f_bucket == __l_bucket)
+ _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
+ else
+ {
+ _M_erase_bucket(__f_bucket, __first._M_cur, 0);
+ for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
+ _M_erase_bucket(__n, 0);
+ if (__l_bucket != _M_buckets.size())
+ _M_erase_bucket(__l_bucket, __last._M_cur);
+ }
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ inline void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ erase(const_iterator __first, const_iterator __last)
+ {
+ erase(iterator(const_cast<_Node*>(__first._M_cur),
+ const_cast<hashtable*>(__first._M_ht)),
+ iterator(const_cast<_Node*>(__last._M_cur),
+ const_cast<hashtable*>(__last._M_ht)));
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ inline void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ erase(const const_iterator& __it)
+ { erase(iterator(const_cast<_Node*>(__it._M_cur),
+ const_cast<hashtable*>(__it._M_ht))); }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ resize(size_type __num_elements_hint)
+ {
+ const size_type __old_n = _M_buckets.size();
+ if (__num_elements_hint > __old_n)
+ {
+ const size_type __n = _M_next_size(__num_elements_hint);
+ if (__n > __old_n)
+ {
+ _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
+ try
+ {
+ for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
+ {
+ _Node* __first = _M_buckets[__bucket];
+ while (__first)
+ {
+ size_type __new_bucket = _M_bkt_num(__first->_M_val,
+ __n);
+ _M_buckets[__bucket] = __first->_M_next;
+ __first->_M_next = __tmp[__new_bucket];
+ __tmp[__new_bucket] = __first;
+ __first = _M_buckets[__bucket];
+ }
+ }
+ _M_buckets.swap(__tmp);
+ }
+ catch(...)
+ {
+ for (size_type __bucket = 0; __bucket < __tmp.size();
+ ++__bucket)
+ {
+ while (__tmp[__bucket])
+ {
+ _Node* __next = __tmp[__bucket]->_M_next;
+ _M_delete_node(__tmp[__bucket]);
+ __tmp[__bucket] = __next;
+ }
+ }
+ __throw_exception_again;
+ }
+ __profcxx_hashtable_resize(this, __num_elements_hint, __n);
+ }
+ }
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
+ {
+ _Node* __cur = _M_buckets[__n];
+ if (__cur == __first)
+ _M_erase_bucket(__n, __last);
+ else
+ {
+ _Node* __next;
+ for (__next = __cur->_M_next;
+ __next != __first;
+ __cur = __next, __next = __cur->_M_next)
+ ;
+ while (__next != __last)
+ {
+ __cur->_M_next = __next->_M_next;
+ _M_delete_node(__next);
+ __next = __cur->_M_next;
+ --_M_num_elements;
+ }
+ }
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ _M_erase_bucket(const size_type __n, _Node* __last)
+ {
+ _Node* __cur = _M_buckets[__n];
+ while (__cur != __last)
+ {
+ _Node* __next = __cur->_M_next;
+ _M_delete_node(__cur);
+ __cur = __next;
+ _M_buckets[__n] = __cur;
+ --_M_num_elements;
+ }
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ clear()
+ {
+ size_type __hops=0, __lc = 0, __chain = 0;
+ if (_M_num_elements != 0)
+ __profcxx_hashtable_destruct(this, _M_buckets.size(), _M_num_elements);
+
+ for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
+ {
+ _Node* __cur = _M_buckets[__i];
+ while (__cur != 0)
+ {
+ _Node* __next = __cur->_M_next;
+ _M_delete_node(__cur);
+ __cur = __next;
+
+ // Compute the longest chain count.
+ __chain++;
+ }
+ _M_buckets[__i] = 0;
+
+ // Collect number of hops.
+ if (__chain > 1) {
+ __lc = __lc > __chain ? __lc : __chain;
+ __hops += (__chain-1) * __chain / 2;
+ }
+ __chain = 0;
+ }
+ if (_M_num_elements) {
+ __profcxx_hashtable_destruct2(this, __lc, _M_num_elements, __hops);
+ }
+ _M_num_elements = 0;
+ }
+
+ template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+ void
+ hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
+ _M_copy_from(const hashtable& __ht)
+ {
+ _M_buckets.clear();
+ _M_buckets.reserve(__ht._M_buckets.size());
+ _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
+ try
+ {
+ for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
+ const _Node* __cur = __ht._M_buckets[__i];
+ if (__cur)
+ {
+ _Node* __local_copy = _M_new_node(__cur->_M_val);
+ _M_buckets[__i] = __local_copy;
+
+ for (_Node* __next = __cur->_M_next;
+ __next;
+ __cur = __next, __next = __cur->_M_next)
+ {
+ __local_copy->_M_next = _M_new_node(__next->_M_val);
+ __local_copy = __local_copy->_M_next;
+ }
+ }
+ }
+ _M_num_elements = __ht._M_num_elements;
+ }
+ catch(...)
+ {
+ clear();
+ __throw_exception_again;
+ }
+ }
+
+_GLIBCXX_END_NAMESPACE
+
+#endif
diff --git a/libstdc++-v3/include/profile/impl/profiler.h b/libstdc++-v3/include/profile/impl/profiler.h
new file mode 100644
index 00000000000..f86920344fc
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler.h
@@ -0,0 +1,326 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler.h
+ * @brief Interface of the profiling runtime library.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_H__
+#define PROFCXX_PROFILER_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+/**
+ * @namespace std::__cxxprof_guard
+ * @brief Mechanism to protect all __cxxprof_impl operations against
+ * multithreaded and exception reentrance.
+ */
+namespace __cxxprof_guard
+{
+
+/** @brief Reentrance guard.
+ *
+ * Mechanism to protect all __cxxprof_impl operations against recursion,
+ * multithreaded and exception reentrance.
+ */
+template <int _Unused=0>
+class __reentrance_guard
+{
+ public:
+ static __thread bool __inside_cxxprof_impl;
+ static bool __get_in();
+ __reentrance_guard() {}
+ ~__reentrance_guard() { __inside_cxxprof_impl = false; }
+};
+
+template <int _Unused>
+__thread bool __reentrance_guard<_Unused>::__inside_cxxprof_impl = false;
+
+template <int _Unused>
+bool __reentrance_guard<_Unused>::__get_in()
+{
+ if (__inside_cxxprof_impl) {
+ return false;
+ } else {
+ __inside_cxxprof_impl = true;
+ return true;
+ }
+}
+
+} // namespace __cxxprof_guard
+
+#define _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__x...) \
+ { \
+ if (__cxxprof_guard::__reentrance_guard<0>::__get_in()) \
+ { \
+ __cxxprof_guard::__reentrance_guard<0> __auto_get_out; \
+ __x; \
+ } \
+ }
+
+/**
+ * @namespace std::__cxxprof_impl
+ * @brief Implementation of profile extension.
+ */
+namespace __cxxprof_impl
+{
+// Forward declarations of implementation functions.
+// Don't use any __cxxprof_impl:: in user code.
+// Instead, use the __profcxx... macros, which offer guarded access.
+void __turn_on();
+void __turn_off();
+bool __is_invalid();
+bool __is_on();
+bool __is_off();
+void __report(void);
+void __trace_hashtable_size_resize(const void*, size_t, size_t);
+void __trace_hashtable_size_destruct(const void*, size_t, size_t);
+void __trace_hashtable_size_construct(const void*, size_t);
+void __trace_vector_size_resize(const void*, size_t, size_t);
+void __trace_vector_size_destruct(const void*, size_t, size_t);
+void __trace_vector_size_construct(const void*, size_t);
+void __trace_hash_func_destruct(const void*, size_t, size_t, size_t);
+void __trace_hash_func_construct(const void*);
+void __trace_vector_to_list_destruct(const void*);
+void __trace_vector_to_list_construct(const void*);
+void __trace_vector_to_list_insert(const void*, size_t, size_t);
+void __trace_vector_to_list_iterate(const void*, size_t);
+void __trace_vector_to_list_invalid_operator(const void*);
+void __trace_vector_to_list_resize(const void*, size_t, size_t);
+void __trace_map_to_unordered_map_construct(const void*);
+void __trace_map_to_unordered_map_invalidate(const void*);
+void __trace_map_to_unordered_map_insert(const void*, size_t, size_t);
+void __trace_map_to_unordered_map_erase(const void*, size_t, size_t);
+void __trace_map_to_unordered_map_iterate(const void*, size_t);
+void __trace_map_to_unordered_map_find(const void*, size_t);
+void __trace_map_to_unordered_map_destruct(const void*);
+} // namespace __cxxprof_impl
+
+// Master switch turns on all diagnostics.
+#ifdef _GLIBCXX_PROFILE
+#define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
+#define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
+#define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
+#define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
+#define _GLIBCXX_PROFILE_INEFFICIENT_HASH
+#define _GLIBCXX_PROFILE_VECTOR_TO_LIST
+#define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
+#endif
+
+// Expose global management routines to user code.
+#ifdef _GLIBCXX_PROFILE
+#define __profcxx_report() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__report())
+#define __profcxx_turn_on() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__turn_on())
+#define __profcxx_turn_off() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__turn_off())
+#define __profcxx_is_invalid() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_invalid())
+#define __profcxx_is_on() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_on())
+#define __profcxx__is_off() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_off())
+#else
+#define __profcxx_report()
+#define __profcxx_turn_on()
+#define __profcxx_turn_off()
+#define __profcxx_is_invalid()
+#define __profcxx_is_on()
+#define __profcxx_is_off()
+#endif
+
+// Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE.
+#if ((defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \
+ && !defined(_NO_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL)) \
+ || (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE) \
+ && !defined(_NO_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE)))
+#define __profcxx_hashtable_resize(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hashtable_size_resize(__x))
+#define __profcxx_hashtable_destruct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hashtable_size_destruct(__x))
+#define __profcxx_hashtable_construct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hashtable_size_construct(__x))
+#else
+#define __profcxx_hashtable_resize(__x...)
+#define __profcxx_hashtable_destruct(__x...)
+#define __profcxx_hashtable_construct(__x...)
+#endif
+
+// Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE.
+#if ((defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
+ && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TOO_SMALL)) \
+ || (defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE) \
+ && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TOO_LARGE)))
+#define __profcxx_vector_resize(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_size_resize(__x))
+#define __profcxx_vector_destruct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_size_destruct(__x))
+#define __profcxx_vector_construct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_size_construct(__x))
+#else
+#define __profcxx_vector_resize(__x...)
+#define __profcxx_vector_destruct(__x...)
+#define __profcxx_vector_construct(__x...)
+#endif
+
+// Turn on/off instrumentation for INEFFICIENT_HASH.
+#if (defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH) \
+ && !defined(_NO_GLIBCXX_PROFILE_INEFFICIENT_HASH))
+#define __profcxx_hashtable_construct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hash_func_construct(__x))
+#define __profcxx_hashtable_destruct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hash_func_destruct(__x))
+#else
+#define __profcxx_hashtable_destruct2(__x...)
+#define __profcxx_hashtable_construct2(__x...)
+#endif
+
+// Turn on/off instrumentation for VECTOR_TO_LIST.
+#if (defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST) \
+ && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TO_LIST))
+#define __profcxx_vector_construct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_construct(__x))
+#define __profcxx_vector_destruct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_destruct(__x))
+#define __profcxx_vector_insert(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_insert(__x))
+#define __profcxx_vector_iterate(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_iterate(__x))
+#define __profcxx_vector_invalid_operator(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_invalid_operator(__x))
+#define __profcxx_vector_resize2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_resize(__x))
+#else
+#define __profcxx_vector_destruct2(__x...)
+#define __profcxx_vector_construct2(__x...)
+#define __profcxx_vector_insert(__x...)
+#define __profcxx_vector_iterate(__x...)
+#define __profcxx_vector_invalid_operator(__x...)
+#define __profcxx_vector_resize2(__x...)
+#endif
+
+// Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
+#if (defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP) \
+ && !defined(_NO_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP))
+#define __profcxx_map_to_unordered_map_construct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_construct(__x))
+#define __profcxx_map_to_unordered_map_destruct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_destruct(__x))
+#define __profcxx_map_to_unordered_map_insert(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_insert(__x))
+#define __profcxx_map_to_unordered_map_erase(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_erase(__x))
+#define __profcxx_map_to_unordered_map_iterate(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_iterate(__x))
+#define __profcxx_map_to_unordered_map_invalidate(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_invalidate(__x))
+#define __profcxx_map_to_unordered_map_find(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_find(__x))
+#else
+#define __profcxx_map_to_unordered_map_construct(__x...) \
+
+#define __profcxx_map_to_unordered_map_destruct(__x...)
+#define __profcxx_map_to_unordered_map_insert(__x...)
+#define __profcxx_map_to_unordered_map_erase(__x...)
+#define __profcxx_map_to_unordered_map_iterate(__x...)
+#define __profcxx_map_to_unordered_map_invalidate(__x...)
+#define __profcxx_map_to_unordered_map_find(__x...)
+#endif
+
+// Run multithreaded unless instructed not to do so.
+#ifndef _GLIBCXX_PROFILE_NOTHREADS
+#define _GLIBCXX_PROFILE_THREADS
+#endif
+
+// Set default values for compile-time customizable variables.
+#ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT
+#define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile"
+#endif
+#ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR
+#define _GLIBCXX_PROFILE_TRACE_ENV_VAR "GLIBCXX_PROFILE_TRACE_PATH_ROOT"
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
+#define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
+ "GLIBCXX_PROFILE_MAX_WARN_COUNT"
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
+#define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH
+#define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
+#define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
+ "GLIBCXX_PROFILE_MAX_STACK_DEPTH"
+#endif
+#ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC
+#define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC 2 << 27
+#endif
+#ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR
+#define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \
+ "GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
+#endif
+
+// Instrumentation hook implementations.
+#include "profile/impl/profiler_hash_func.h"
+#include "profile/impl/profiler_hashtable_size.h"
+#include "profile/impl/profiler_map_to_unordered_map.h"
+#include "profile/impl/profiler_vector_size.h"
+#include "profile/impl/profiler_vector_to_list.h"
+
+#endif // PROFCXX_PROFILER_H__
diff --git a/libstdc++-v3/include/profile/impl/profiler_container_size.h b/libstdc++-v3/include/profile/impl/profiler_container_size.h
new file mode 100644
index 00000000000..330afc5ba79
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_container_size.h
@@ -0,0 +1,250 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_trace.h
+ * @brief Diagnostics for container sizes.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_CONTAINER_SIZE_H__
+#define PROFCXX_PROFILER_CONTAINER_SIZE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+/** @brief A container size instrumentation line in the object table. */
+class __container_size_info: public __object_info_base
+{
+ public:
+ __container_size_info();
+ __container_size_info(const __container_size_info& __o);
+ __container_size_info(__stack_t __stack, size_t __num);
+ virtual ~__container_size_info() {}
+
+ void __write(FILE* f) const;
+ float __magnitude() const { return static_cast<float>(_M_cost); }
+ const char* __advice() const;
+
+ void __merge(const __container_size_info& __o);
+ // Call if a container is destructed or cleaned.
+ void __destruct(size_t __num, size_t __inum);
+ // Estimate the cost of resize/rehash.
+ float __resize_cost(size_t __from, size_t __to) { return __from; }
+ // Call if container is resized.
+ void __resize(size_t __from, size_t __to);
+
+ private:
+ size_t _M_init;
+ size_t _M_max; // range of # buckets
+ size_t _M_min;
+ size_t _M_total;
+ size_t _M_item_min; // range of # items
+ size_t _M_item_max;
+ size_t _M_item_total;
+ size_t _M_count;
+ size_t _M_resize;
+ size_t _M_cost;
+};
+
+inline const char* __container_size_info::__advice() const
+{
+ const size_t __max_chars_size_t_printed = 20;
+ const char* __message_pattern =
+ "change initial container size from %d to %d";
+ size_t __message_size = (strlen(__message_pattern)
+ + 2 * __max_chars_size_t_printed
+ - 2 * 2);
+ char* __message = new char[__message_size + 1];
+
+ if (_M_init < _M_item_max)
+ snprintf(__message, __message_size, __message_pattern, _M_init,
+ _M_item_max);
+ else
+ snprintf(__message, __message_size, __message_pattern, _M_init,
+ _M_item_max);
+
+ return __message;
+}
+
+inline void __container_size_info::__destruct(size_t __num, size_t __inum)
+{
+ _M_max = __max(_M_max, __num);
+ _M_item_max = __max(_M_item_max, __inum);
+ if (_M_min == 0) {
+ _M_min = __num;
+ _M_item_min = __inum;
+ } else {
+ _M_min = __min(_M_min, __num);
+ _M_item_min = __min(_M_item_min, __inum);
+ }
+ _M_total += __num;
+ _M_item_total += __inum;
+ _M_count += 1;
+}
+
+inline void __container_size_info::__resize(size_t __from, size_t __to)
+{
+ _M_cost += this->__resize_cost(__from, __to);
+ _M_resize += 1;
+ _M_max = __max(_M_max, __to);
+}
+
+inline __container_size_info::__container_size_info(__stack_t __stack,
+ size_t __num)
+ : __object_info_base(__stack), _M_init(0), _M_max(0), _M_item_max(0),
+ _M_min(0), _M_item_min(0), _M_total(0), _M_item_total(0), _M_cost(0),
+ _M_count(0), _M_resize(0)
+{
+ _M_init = _M_max = __num;
+ _M_item_min = _M_item_max = _M_item_total = _M_total = 0;
+ _M_min = 0;
+ _M_count = 0;
+ _M_resize = 0;
+}
+
+inline void __container_size_info::__merge(const __container_size_info& __o)
+{
+ _M_init = __max(_M_init, __o._M_init);
+ _M_max = __max(_M_max, __o._M_max);
+ _M_item_max = __max(_M_item_max, __o._M_item_max);
+ _M_min = __min(_M_min, __o._M_min);
+ _M_item_min = __min(_M_item_min, __o._M_item_min);
+ _M_total += __o._M_total;
+ _M_item_total += __o._M_item_total;
+ _M_count += __o._M_count;
+ _M_cost += __o._M_cost;
+ _M_resize += __o._M_resize;
+}
+
+inline __container_size_info::__container_size_info()
+ : _M_init(0), _M_max(0), _M_item_max(0), _M_min(0), _M_item_min(0),
+ _M_total(0), _M_item_total(0), _M_cost(0), _M_count(0), _M_resize(0)
+{
+}
+
+inline __container_size_info::__container_size_info(
+ const __container_size_info& __o)
+ : __object_info_base(__o)
+{
+ _M_init = __o._M_init;
+ _M_max = __o._M_max;
+ _M_item_max = __o._M_item_max;
+ _M_min = __o._M_min;
+ _M_item_min = __o._M_item_min;
+ _M_total = __o._M_total;
+ _M_item_total = __o._M_item_total;
+ _M_cost = __o._M_cost;
+ _M_count = __o._M_count;
+ _M_resize = __o._M_resize;
+}
+
+/** @brief A container size instrumentation line in the stack table. */
+class __container_size_stack_info: public __container_size_info
+{
+ public:
+ __container_size_stack_info(const __container_size_info& __o)
+ : __container_size_info(__o) {}
+};
+
+/** @brief Container size instrumentation trace producer. */
+class __trace_container_size
+ : public __trace_base<__container_size_info, __container_size_stack_info>
+{
+ public:
+ ~__trace_container_size() {}
+ __trace_container_size()
+ : __trace_base<__container_size_info, __container_size_stack_info>() {};
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void __insert(const __object_t __obj, __stack_t __stack, size_t __num);
+ // Call at destruction/clean to set container final size.
+ void __destruct(const void* __obj, size_t __num, size_t __inum);
+ void __construct(const void* __obj, size_t __inum);
+ // Call at resize to set resize/cost information.
+ void __resize(const void* __obj, int __from, int __to);
+};
+
+inline void __trace_container_size::__insert(const __object_t __obj,
+ __stack_t __stack, size_t __num)
+{
+ __add_object(__obj, __container_size_info(__stack, __num));
+}
+
+inline void __container_size_info::__write(FILE* __f) const
+{
+ fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n",
+ _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max, _M_total,
+ _M_item_min, _M_item_max, _M_item_total);
+}
+
+inline void __trace_container_size::__destruct(const void* __obj,
+ size_t __num, size_t __inum)
+{
+ if (!__is_on()) return;
+
+ __object_t __obj_handle = static_cast<__object_t>(__obj);
+
+ __container_size_info* __object_info = __get_object_info(__obj_handle);
+ if (!__object_info)
+ return;
+
+ __object_info->__destruct(__num, __inum);
+ __retire_object(__obj_handle);
+}
+
+inline void __trace_container_size::__resize(const void* __obj, int __from,
+ int __to)
+{
+ if (!__is_on()) return;
+
+ __container_size_info* __object_info = __get_object_info(__obj);
+ if (!__object_info)
+ return;
+
+ __object_info->__resize(__from, __to);
+}
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_PROFILER_CONTAINER_SIZE_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_hash_func.h b/libstdc++-v3/include/profile/impl/profiler_hash_func.h
new file mode 100644
index 00000000000..cf639545163
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_hash_func.h
@@ -0,0 +1,192 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_trace.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_HASH_FUNC_H__
+#define PROFCXX_PROFILER_HASH_FUNC_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+/** @brief A hash performance instrumentation line in the object table. */
+class __hashfunc_info: public __object_info_base
+{
+ public:
+ __hashfunc_info()
+ :_M_longest_chain(0), _M_accesses(0), _M_hops(0) {}
+ __hashfunc_info(const __hashfunc_info& o);
+ __hashfunc_info(__stack_t __stack)
+ : __object_info_base(__stack),
+ _M_longest_chain(0), _M_accesses(0), _M_hops(0){}
+ virtual ~__hashfunc_info() {}
+
+ void __merge(const __hashfunc_info& __o);
+ void __destruct(size_t __chain, size_t __accesses, size_t __hops);
+ void __write(FILE* __f) const;
+ float __magnitude() const { return static_cast<float>(_M_hops); }
+ const char* __advice() const { return "change hash function"; }
+
+private:
+ size_t _M_longest_chain;
+ size_t _M_accesses;
+ size_t _M_hops;
+};
+
+inline __hashfunc_info::__hashfunc_info(const __hashfunc_info& __o)
+ : __object_info_base(__o)
+{
+ _M_longest_chain = __o._M_longest_chain;
+ _M_accesses = __o._M_accesses;
+ _M_hops = __o._M_hops;
+}
+
+inline void __hashfunc_info::__merge(const __hashfunc_info& __o)
+{
+ _M_longest_chain = __max(_M_longest_chain, __o._M_longest_chain);
+ _M_accesses += __o._M_accesses;
+ _M_hops += __o._M_hops;
+}
+
+inline void __hashfunc_info::__destruct(size_t __chain, size_t __accesses,
+ size_t __hops)
+{
+ _M_longest_chain = __max(_M_longest_chain, __chain);
+ _M_accesses += __accesses;
+ _M_hops += __hops;
+}
+
+/** @brief A hash performance instrumentation line in the stack table. */
+class __hashfunc_stack_info: public __hashfunc_info {
+ public:
+ __hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) {}
+};
+
+/** @brief Hash performance instrumentation producer. */
+class __trace_hash_func
+ : public __trace_base<__hashfunc_info, __hashfunc_stack_info>
+{
+ public:
+ __trace_hash_func();
+ ~__trace_hash_func() {}
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void __insert(__object_t __obj, __stack_t __stack);
+ // Call at destruction/clean to set container final size.
+ void __destruct(const void* __obj, size_t __chain,
+ size_t __accesses, size_t __hops);
+};
+
+inline __trace_hash_func::__trace_hash_func()
+ : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
+{
+ __id = "hash-distr";
+}
+
+inline void __trace_hash_func::__insert(__object_t __obj, __stack_t __stack)
+{
+ __add_object(__obj, __hashfunc_info(__stack));
+}
+
+inline void __hashfunc_info::__write(FILE* __f) const
+{
+ fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain);
+}
+
+inline void __trace_hash_func::__destruct(const void* __obj, size_t __chain,
+ size_t __accesses, size_t __hops)
+{
+ if (!__is_on()) return;
+
+ // First find the item from the live objects and update the informations.
+ __hashfunc_info* __objs = __get_object_info(__obj);
+ if (!__objs)
+ return;
+
+ __objs->__destruct(__chain, __accesses, __hops);
+ __retire_object(__obj);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hash_func_init()
+{
+ __tables<0>::_S_hash_func = new __trace_hash_func();
+}
+
+inline void __trace_hash_func_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_hash_func) {
+ __tables<0>::_S_hash_func->__collect_warnings(__warnings);
+ __tables<0>::_S_hash_func->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hash_func_construct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hash_func->__insert(__obj, __get_stack());
+}
+
+inline void __trace_hash_func_destruct(const void* __obj, size_t __chain,
+ size_t __accesses, size_t __hops)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hash_func->__destruct(__obj, __chain, __accesses, __hops);
+}
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_PROFILER_HASH_FUNC_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h b/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
new file mode 100644
index 00000000000..2192879325e
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
@@ -0,0 +1,115 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_hashtable_size.cc
+ * @brief Collection of hashtable size traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_HASHTABLE_SIZE_H__
+#define PROFCXX_PROFILER_HASHTABLE_SIZE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+#include "profile/impl/profiler_state.h"
+#include "profile/impl/profiler_container_size.h"
+
+namespace __cxxprof_impl
+{
+
+/** @brief Hashtable size instrumentation trace producer. */
+class __trace_hashtable_size : public __trace_container_size
+{
+ public:
+ __trace_hashtable_size() : __trace_container_size()
+ {
+ __id = "hashtable-size";
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hashtable_size_init()
+{
+ __tables<0>::_S_hashtable_size = new __trace_hashtable_size();
+}
+
+inline void __trace_hashtable_size_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_hashtable_size) {
+ __tables<0>::_S_hashtable_size->__collect_warnings(__warnings);
+ __tables<0>::_S_hashtable_size->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hashtable_size_construct(const void* __obj, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hashtable_size->__insert(__obj, __get_stack(), __num);
+}
+
+inline void __trace_hashtable_size_destruct(const void* __obj, size_t __num,
+ size_t __inum)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hashtable_size->__destruct(__obj, __num, __inum);
+}
+
+inline void __trace_hashtable_size_resize(const void* __obj, size_t __from,
+ size_t __to)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hashtable_size->__resize(__obj, __from, __to);
+}
+
+} // namespace __cxxprof_impl
+
+#endif /* PROFCXX_PROFILER_HASHTABLE_SIZE_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h b/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
new file mode 100644
index 00000000000..cdb88a86bcb
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
@@ -0,0 +1,305 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_map_to_unordered_map.h
+ * @brief Diagnostics for map to unordered_map.
+ */
+
+// Written by Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__
+#define PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+// Cost model. XXX: this must be taken from the machine model instead.
+// Map operations:
+// - insert: 1.5 * log(size)
+// - erase: 1.5 * log(size)
+// - find: log(size)
+// - iterate: 2.3
+// Unordered map operations:
+// - insert: 12
+// - erase: 12
+// - find: 10
+// - iterate: 1.7
+
+const float __map_insert_cost_factor = 1.5;
+const float __map_erase_cost_factor = 1.5;
+const float __map_find_cost_factor = 1;
+const float __map_iterate_cost = 2.3;
+
+const float __umap_insert_cost = 12.0;
+const float __umap_erase_cost = 12.0;
+const float __umap_find_cost = 10.0;
+const float __umap_iterate_cost = 1.7;
+
+inline int __log2(size_t __size)
+{
+ for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0; --__bit_count) {
+ if ((2 << __bit_count) & __size) {
+ return __bit_count;
+ }
+ }
+ return 0;
+}
+
+inline float __map_insert_cost(size_t __size)
+{
+ return __map_insert_cost_factor * static_cast<float>(__log2(__size));
+}
+
+inline float __map_erase_cost(size_t __size)
+{
+ return __map_erase_cost_factor * static_cast<float>(__log2(__size));
+}
+
+inline float __map_find_cost(size_t __size)
+{
+ return __map_find_cost_factor * static_cast<float>(__log2(__size));
+}
+
+/** @brief A map-to-unordered_map instrumentation line in the object table. */
+class __map2umap_info: public __object_info_base
+{
+ public:
+ __map2umap_info()
+ : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
+ _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {}
+ __map2umap_info(__stack_t __stack)
+ : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
+ _M_iterate(0), _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {}
+ virtual ~__map2umap_info() {}
+ __map2umap_info(const __map2umap_info& o);
+ void __merge(const __map2umap_info& o);
+ void __write(FILE* __f) const;
+ float __magnitude() const { return _M_map_cost - _M_umap_cost; }
+ const char* __advice() const;
+
+ void __record_insert(size_t __size, size_t __count);
+ void __record_erase(size_t __size, size_t __count);
+ void __record_find(size_t __size);
+ void __record_iterate(size_t __count);
+ void __record_invalidate();
+
+ private:
+ size_t _M_insert;
+ size_t _M_erase;
+ size_t _M_find;
+ size_t _M_iterate;
+ float _M_umap_cost;
+ float _M_map_cost;
+ bool _M_valid;
+};
+
+inline const char* __map2umap_info::__advice() const
+{
+ return "change std::map to std::unordered_map";
+}
+
+inline __map2umap_info::__map2umap_info(const __map2umap_info& __o)
+ : __object_info_base(__o),
+ _M_insert(__o._M_insert),
+ _M_erase(__o._M_erase),
+ _M_find(__o._M_find),
+ _M_iterate(__o._M_iterate),
+ _M_map_cost(__o._M_map_cost),
+ _M_umap_cost(__o._M_umap_cost),
+ _M_valid(__o._M_valid)
+{}
+
+inline void __map2umap_info::__merge(const __map2umap_info& __o)
+{
+ _M_insert += __o._M_insert;
+ _M_erase += __o._M_erase;
+ _M_find += __o._M_find;
+ _M_map_cost += __o._M_map_cost;
+ _M_umap_cost += __o._M_umap_cost;
+ _M_valid &= __o._M_valid;
+}
+
+inline void __map2umap_info:: __record_insert(size_t __size, size_t __count)
+{
+ _M_insert += __count;
+ _M_map_cost += __count * __map_insert_cost(__size);
+ _M_umap_cost += __count * __umap_insert_cost;
+}
+
+inline void __map2umap_info:: __record_erase(size_t __size, size_t __count)
+{
+ _M_erase += __count;
+ _M_map_cost += __count * __map_erase_cost(__size);
+ _M_umap_cost += __count * __umap_erase_cost;
+}
+
+inline void __map2umap_info:: __record_find(size_t __size)
+{
+ _M_find += 1;
+ _M_map_cost += __map_find_cost(__size);
+ _M_umap_cost += __umap_find_cost;
+}
+
+inline void __map2umap_info:: __record_iterate(size_t __count)
+{
+ _M_iterate += __count;
+ _M_map_cost += __count * __map_iterate_cost;
+ _M_umap_cost += __count * __umap_iterate_cost;
+}
+
+inline void __map2umap_info:: __record_invalidate()
+{
+ _M_valid = false;
+}
+
+inline void __map2umap_info::__write(FILE* __f) const
+{
+ fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
+ _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost, _M_umap_cost,
+ _M_valid ? "valid" : "invalid");
+}
+
+/** @brief A map-to-unordered_map instrumentation line in the stack table. */
+class __map2umap_stack_info: public __map2umap_info
+{
+ public:
+ __map2umap_stack_info(const __map2umap_info& o) : __map2umap_info(o) {}
+};
+
+/** @brief Map-to-unordered_map instrumentation producer. */
+class __trace_map2umap
+ : public __trace_base<__map2umap_info, __map2umap_stack_info>
+{
+ public:
+ __trace_map2umap();
+};
+
+inline __trace_map2umap::__trace_map2umap()
+ : __trace_base<__map2umap_info, __map2umap_stack_info>()
+{
+ __id = "map-to-unordered-map";
+}
+
+inline void __trace_map_to_unordered_map_init()
+{
+ __tables<0>::_S_map2umap = new __trace_map2umap();
+}
+
+inline void __trace_map_to_unordered_map_report(
+ FILE* __f, __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_map2umap) {
+ __tables<0>::_S_map2umap->__collect_warnings(__warnings);
+ __tables<0>::_S_map2umap->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_map_to_unordered_map_construct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_map2umap->__add_object(__obj,
+ __map2umap_info(__get_stack()));
+}
+
+inline void __trace_map_to_unordered_map_destruct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_map2umap->__retire_object(__obj);
+}
+
+inline void __trace_map_to_unordered_map_insert(const void* __obj,
+ size_t __size, size_t __count)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_insert(__size, __count);
+}
+
+inline void __trace_map_to_unordered_map_erase(const void* __obj,
+ size_t __size, size_t __count)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_erase(__size, __count);
+}
+
+inline void __trace_map_to_unordered_map_find(const void* __obj, size_t __size)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_find(__size);
+}
+
+inline void __trace_map_to_unordered_map_iterate(const void* __obj,
+ size_t __count)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_iterate(__count);
+}
+
+inline void __trace_map_to_unordered_map_invalidate(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_invalidate();
+}
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_node.h b/libstdc++-v3/include/profile/impl/profiler_node.h
new file mode 100644
index 00000000000..cd2b9ab2016
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_node.h
@@ -0,0 +1,172 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_node.h
+ * @brief Data structures to represent a single profiling event.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_NODE_H__
+#define PROFCXX_PROFILER_NODE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#include <cstdint>
+#include <cstring>
+#else
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#endif
+#include <vector>
+#if defined HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+namespace __cxxprof_impl
+{
+typedef const void* __object_t;
+typedef void* __instruction_address_t;
+typedef std::_GLIBCXX_STD_PR::vector<__instruction_address_t> __stack_npt;
+typedef __stack_npt* __stack_t;
+
+size_t __stack_max_depth();
+
+inline __stack_t __get_stack()
+{
+#if defined HAVE_EXECINFO_H
+ size_t __max_depth = __stack_max_depth();
+ if (__max_depth == 0)
+ return NULL;
+ __stack_npt __buffer(__max_depth);
+ int __depth = backtrace(&__buffer[0], __max_depth);
+ __stack_t __stack = new __stack_npt(__depth);
+ memcpy(&(*__stack)[0], &__buffer[0], __depth * sizeof(__object_t));
+ return __stack;
+#else
+ return NULL;
+#endif
+}
+
+inline __size(const __stack_t& __stack)
+{
+ if (!__stack) {
+ return 0;
+ } else {
+ return __stack->size();
+ }
+}
+
+inline void __write(FILE* __f, const __stack_t __stack)
+{
+ if (!__stack) {
+ return;
+ }
+
+ __stack_npt::const_iterator __it;
+ for (__it = __stack->begin(); __it != __stack->end(); ++__it) {
+ fprintf(__f, "%p ", *__it);
+ }
+}
+
+/** @brief Hash function for summary trace using call stack as index. */
+class __stack_hash
+{
+ public:
+ size_t operator()(const __stack_t __s) const
+ {
+ if (!__s) {
+ return 0;
+ }
+
+ uintptr_t __index = 0;
+ __stack_npt::const_iterator __it;
+ for (__it = __s->begin(); __it != __s->end(); ++__it) {
+ __index += reinterpret_cast<uintptr_t>(*__it);
+ }
+ return __index;
+ }
+
+ bool operator() (const __stack_t __stack1, const __stack_t __stack2) const
+ {
+ if (!__stack1 && !__stack2) return true;
+ if (!__stack1 || !__stack2) return false;
+ if (__stack1->size() != __stack2->size()) return false;
+
+ size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type);
+ return memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 0;
+ }
+};
+
+/** @brief Base class for a line in the object table. */
+class __object_info_base
+{
+ public:
+ __object_info_base() {}
+ __object_info_base(__stack_t __stack);
+ __object_info_base(const __object_info_base& o);
+ virtual ~__object_info_base() {}
+ bool __is_valid() const { return _M_valid; }
+ __stack_t __stack() const { return _M_stack; }
+ virtual void __write(FILE* f) const = 0;
+
+ protected:
+ __stack_t _M_stack;
+ bool _M_valid;
+};
+
+inline __object_info_base::__object_info_base(__stack_t __stack)
+{
+ _M_stack = __stack;
+ _M_valid = true;
+}
+
+inline __object_info_base::__object_info_base(const __object_info_base& __o)
+{
+ _M_stack = __o._M_stack;
+ _M_valid = __o._M_valid;
+}
+
+/** @brief Base class for a line in the stack table. */
+template<typename __object_info>
+class __stack_info_base
+{
+ public:
+ __stack_info_base() {}
+ __stack_info_base(const __object_info& __info) = 0;
+ virtual ~__stack_info_base() {}
+ void __merge(const __object_info& __info) = 0;
+ virtual float __magnitude() const = 0;
+ virtual const char* __get_id() const = 0;
+};
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_PROFILER_NODE_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_state.h b/libstdc++-v3/include/profile/impl/profiler_state.h
new file mode 100644
index 00000000000..64c10db616c
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_state.h
@@ -0,0 +1,107 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_state.cc
+ * @brief Global profiler state.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_STATE_H__
+#define PROFCXX_PROFILER_STATE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+
+namespace __cxxprof_impl
+{
+
+/** @brief Profiling mode on/off state. */
+template <int _Unused=0>
+class __state
+{
+ public:
+
+ static __state<_Unused>* _S_diag_state;
+
+ __state() : _M_state(__INVALID) {}
+ ~__state() {}
+
+ bool __is_on() { return _M_state == __ON; }
+ bool __is_off() { return _M_state == __OFF; }
+ bool __is_invalid() { return _M_state == __INVALID; }
+ void __turn_on() { _M_state = __ON; }
+ void __turn_off() { _M_state = __OFF; }
+
+ private:
+ enum __state_type { __ON, __OFF, __INVALID };
+ __state_type _M_state;
+};
+
+template <int _Unused>
+__state<_Unused>* __state<_Unused>::_S_diag_state = NULL;
+
+inline bool __is_on()
+{
+ return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_on();
+}
+
+inline bool __is_off()
+{
+ return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_off();
+}
+
+inline bool __is_invalid()
+{
+ return (!__state<0>::_S_diag_state
+ || __state<0>::_S_diag_state->__is_invalid());
+}
+
+inline void __turn_on()
+{
+ if (!__state<0>::_S_diag_state) {
+ __state<0>::_S_diag_state = new __state<0>();
+ }
+ __state<0>::_S_diag_state->__turn_on();
+}
+
+inline void __turn_off()
+{
+ if (!__state<0>::_S_diag_state) {
+ __state<0>::_S_diag_state = new __state<0>();
+ }
+ __state<0>::_S_diag_state->__turn_off();
+}
+
+} // end namespace __cxxprof_impl
+#endif /* PROFCXX_PROFILER_STATE_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_trace.h b/libstdc++-v3/include/profile/impl/profiler_trace.h
new file mode 100644
index 00000000000..37bcb6436e5
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_trace.h
@@ -0,0 +1,564 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_trace.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_TRACE_H__
+#define PROFCXX_PROFILER_TRACE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cerrno>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_PR::unordered_map
+#include <unordered_map>
+#else
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <tr1/unordered_map>
+#define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map
+#endif
+
+#include <algorithm>
+#include <utility>
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+#include <pthread.h>
+#endif
+
+#include "profile/impl/profiler_state.h"
+#include "profile/impl/profiler_node.h"
+
+namespace __cxxprof_impl
+{
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+#define _GLIBCXX_IMPL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+typedef pthread_mutex_t __mutex_t;
+/** @brief Pthread mutex wrapper. */
+template <int _Unused=0>
+class __mutex {
+ public:
+ static __mutex_t __global_lock;
+ static void __lock(__mutex_t& __m) { pthread_mutex_lock(&__m); }
+ static void __unlock(__mutex_t& __m) { pthread_mutex_unlock(&__m); }
+};
+#else
+#define _GLIBCXX_IMPL_MUTEX_INITIALIZER 0
+typedef int __mutex_t;
+/** @brief Mock mutex interface. */
+template <int _Unused=0>
+class __mutex {
+ public:
+ static __mutex_t __global_lock;
+ static void __lock(__mutex_t& __m) {}
+ static void __unlock(__mutex_t& __m) {}
+};
+#endif
+
+template <int _Unused>
+__mutex_t __mutex<_Unused>::__global_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
+
+/** @brief Representation of a warning. */
+struct __warning_data
+{
+ float __magnitude;
+ __stack_t __context;
+ const char* __warning_id;
+ const char* __warning_message;
+ __warning_data();
+ __warning_data(float __m, __stack_t __c, const char* __id,
+ const char* __msg);
+ bool operator>(const struct __warning_data& other) const;
+};
+
+inline __warning_data::__warning_data()
+ : __magnitude(0.0), __context(NULL), __warning_id(NULL),
+ __warning_message(NULL)
+{
+}
+
+inline __warning_data::__warning_data(float __m, __stack_t __c,
+ const char* __id, const char* __msg)
+ : __magnitude(__m), __context(__c), __warning_id(__id),
+ __warning_message(__msg)
+{
+}
+
+inline bool __warning_data::operator>(const struct __warning_data& other) const
+{
+ return __magnitude > other.__magnitude;
+}
+
+typedef std::_GLIBCXX_STD_PR::vector<__warning_data> __warning_vector_t;
+
+// Defined in profiler_<diagnostic name>.h.
+class __trace_hash_func;
+class __trace_hashtable_size;
+class __trace_map2umap;
+class __trace_vector_size;
+class __trace_vector_to_list;
+void __trace_vector_size_init();
+void __trace_hashtable_size_init();
+void __trace_hash_func_init();
+void __trace_vector_to_list_init();
+void __trace_map_to_unordered_map_init();
+void __trace_vector_size_report(FILE*, __warning_vector_t&);
+void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
+void __trace_hash_func_report(FILE*, __warning_vector_t&);
+void __trace_vector_to_list_report(FILE*, __warning_vector_t&);
+void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);
+
+// Utility functions.
+inline size_t __max(size_t __a, size_t __b)
+{
+ return __a >= __b ? __a : __b;
+}
+
+inline size_t __min(size_t __a, size_t __b)
+{
+ return __a <= __b ? __a : __b;
+}
+
+/** @brief Storage for diagnostic table entries. Has only static fields. */
+template <int _Unused=0>
+class __tables
+{
+ public:
+ static __trace_hash_func* _S_hash_func;
+ static __trace_hashtable_size* _S_hashtable_size;
+ static __trace_map2umap* _S_map2umap;
+ static __trace_vector_size* _S_vector_size;
+ static __trace_vector_to_list* _S_vector_to_list;
+};
+
+template <int _Unused>
+__trace_hash_func* __tables<_Unused>::_S_hash_func = NULL;
+template <int _Unused>
+__trace_hashtable_size* __tables<_Unused>::_S_hashtable_size = NULL;
+template <int _Unused>
+__trace_map2umap* __tables<_Unused>::_S_map2umap = NULL;
+template <int _Unused>
+__trace_vector_size* __tables<_Unused>::_S_vector_size = NULL;
+template <int _Unused>
+__trace_vector_to_list* __tables<_Unused>::_S_vector_to_list = NULL;
+
+/** @brief Storage for user defined parameters. Has only static fields. */
+template <int _Unused=0>
+class __settings {
+ public:
+ static const char* _S_trace_file_name;
+ static size_t _S_max_warn_count;
+ static size_t _S_max_stack_depth;
+ static size_t _S_max_mem;
+};
+
+template <int _Unused>
+const char* __settings<_Unused>::_S_trace_file_name =
+ _GLIBCXX_PROFILE_TRACE_PATH_ROOT;
+template <int _Unused>
+size_t __settings<_Unused>::_S_max_warn_count =
+ _GLIBCXX_PROFILE_MAX_WARN_COUNT;
+template <int _Unused>
+size_t __settings<_Unused>::_S_max_stack_depth =
+ _GLIBCXX_PROFILE_MAX_STACK_DEPTH;
+template <int _Unused>
+size_t __settings<_Unused>::_S_max_mem =
+ _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC;
+
+inline size_t __stack_max_depth()
+{
+ return __settings<0>::_S_max_stack_depth;
+}
+
+inline size_t __max_mem()
+{
+ return __settings<0>::_S_max_mem;
+}
+
+/** @brief Base class for all trace producers. */
+template <typename __object_info, typename __stack_info>
+class __trace_base
+{
+ public:
+ __trace_base();
+ virtual ~__trace_base() {}
+
+ void __add_object(__object_t object, __object_info __info);
+ __object_info* __get_object_info(__object_t __object);
+ void __retire_object(__object_t __object);
+ void __write(FILE* f);
+ void __collect_warnings(__warning_vector_t& warnings);
+
+ void __lock_object_table();
+ void __lock_stack_table();
+ void __unlock_object_table();
+ void __unlock_stack_table();
+
+ private:
+ __mutex_t __object_table_lock;
+ __mutex_t __stack_table_lock;
+ typedef _GLIBCXX_IMPL_UNORDERED_MAP<__object_t,
+ __object_info> __object_table_t;
+ typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info, __stack_hash,
+ __stack_hash> __stack_table_t;
+ __object_table_t __object_table;
+ __stack_table_t __stack_table;
+ size_t __stack_table_byte_size;
+
+ protected:
+ const char* __id;
+};
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__collect_warnings(
+ __warning_vector_t& warnings)
+{
+ typename __stack_table_t::iterator __i = __stack_table.begin();
+ for ( ; __i != __stack_table.end(); ++__i )
+ {
+ warnings.push_back(__warning_data((*__i).second.__magnitude(),
+ (*__i).first,
+ __id,
+ (*__i).second.__advice()));
+ }
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_object_table()
+{
+ __mutex<0>::__lock(this->__object_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_stack_table()
+{
+ __mutex<0>::__lock(this->__stack_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_object_table()
+{
+ __mutex<0>::__unlock(this->__object_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_stack_table()
+{
+ __mutex<0>::__unlock(this->__stack_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+__trace_base<__object_info, __stack_info>::__trace_base()
+{
+ // Do not pick the initial size too large, as we don't know which diagnostics
+ // are more active.
+ __object_table.rehash(10000);
+ __stack_table.rehash(10000);
+ __stack_table_byte_size = 0;
+ __id = NULL;
+ __object_table_lock = __stack_table_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__add_object(
+ __object_t __object, __object_info __info)
+{
+ if (__max_mem() == 0
+ || __object_table.size() * sizeof(__object_info) <= __max_mem()) {
+ __lock_object_table();
+ __object_table.insert(
+ typename __object_table_t::value_type(__object, __info));
+ __unlock_object_table();
+ }
+}
+
+template <typename __object_info, typename __stack_info>
+__object_info* __trace_base<__object_info, __stack_info>::__get_object_info(
+ __object_t __object)
+{
+ // XXX: Revisit this to see if we can decrease mutex spans.
+ // Without this mutex, the object table could be rehashed during an
+ // insertion on another thread, which could result in a segfault.
+ __lock_object_table();
+ typename __object_table_t::iterator __object_it =
+ __object_table.find(__object);
+ if (__object_it == __object_table.end()){
+ __unlock_object_table();
+ return NULL;
+ } else {
+ __unlock_object_table();
+ return &__object_it->second;
+ }
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__retire_object(
+ __object_t __object)
+{
+ __lock_object_table();
+ __lock_stack_table();
+ typename __object_table_t::iterator __object_it =
+ __object_table.find(__object);
+ if (__object_it != __object_table.end()){
+ const __object_info& __info = __object_it->second;
+ const __stack_t& __stack = __info.__stack();
+ typename __stack_table_t::iterator __stack_it =
+ __stack_table.find(__stack);
+ if (__stack_it == __stack_table.end()) {
+ // First occurence of this call context.
+ if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) {
+ __stack_table_byte_size +=
+ (sizeof(__instruction_address_t) * __size(__stack)
+ + sizeof(__stack) + sizeof(__stack_info));
+ __stack_table.insert(make_pair(__stack, __stack_info(__info)));
+ }
+ } else {
+ // Merge object info into info summary for this call context.
+ __stack_it->second.__merge(__info);
+ delete __stack;
+ }
+ __object_table.erase(__object);
+ }
+ __unlock_stack_table();
+ __unlock_object_table();
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__write(FILE* __f)
+{
+ typename __stack_table_t::iterator __it;
+
+ for (__it = __stack_table.begin(); __it != __stack_table.end(); __it++) {
+ if (__it->second.__is_valid()) {
+ fprintf(__f, __id);
+ fprintf(__f, "|");
+ __cxxprof_impl::__write(__f, __it->first);
+ fprintf(__f, "|");
+ __it->second.__write(__f);
+ }
+ }
+}
+
+inline size_t __env_to_size_t(const char* __env_var, size_t __default_value)
+{
+ char* __env_value = getenv(__env_var);
+ if (__env_value) {
+ long int __converted_value = strtol(__env_value, NULL, 10);
+ if (errno || __converted_value < 0) {
+ fprintf(stderr, "Bad value for environment variable '%s'.", __env_var);
+ abort();
+ } else {
+ return static_cast<size_t>(__converted_value);
+ }
+ } else {
+ return __default_value;
+ }
+}
+
+inline void __set_max_stack_trace_depth()
+{
+ __settings<0>::_S_max_stack_depth = __env_to_size_t(
+ _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
+ __settings<0>::_S_max_stack_depth);
+}
+
+inline void __set_max_mem()
+{
+ __settings<0>::_S_max_mem = __env_to_size_t(
+ _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, __settings<0>::_S_max_mem);
+}
+
+inline int __log_magnitude(float f)
+{
+ const float log_base = 10.0;
+ int result = 0;
+ int sign = 1;
+ if (f < 0) {
+ f = -f;
+ sign = -1;
+ }
+ while (f > log_base) {
+ ++result;
+ f /= 10.0;
+ }
+ return sign * result;
+}
+
+struct __warn
+{
+ FILE* __file;
+ __warn(FILE* __f) { __file = __f; }
+ void operator() (const __warning_data& __info)
+ {
+ fprintf(__file, __info.__warning_id);
+ fprintf(__file, ": improvement = %d", __log_magnitude(__info.__magnitude));
+ fprintf(__file, ": call stack = ");
+ __cxxprof_impl::__write(__file, __info.__context);
+ fprintf(__file, ": advice = %s\n", __info.__warning_message);
+ }
+};
+
+inline FILE* __open_output_file(const char* extension)
+{
+ // The path is made of _S_trace_file_name + "." + extension.
+ size_t root_len = strlen(__settings<0>::_S_trace_file_name);
+ size_t ext_len = strlen(extension);
+ char* file_name = new char[root_len + 1 + ext_len + 1];
+ char* p = file_name;
+ memcpy(file_name, __settings<0>::_S_trace_file_name, root_len);
+ *(file_name + root_len) = '.';
+ memcpy(file_name + root_len + 1, extension, ext_len + 1);
+ FILE* out_file = fopen(file_name, "w");
+ if (out_file) {
+ return out_file;
+ } else {
+ fprintf(stderr, "Could not open trace file '%s'.", file_name);
+ abort();
+ }
+}
+
+/** @brief Final report method, registered with "atexit".
+ *
+ * This can also be called directly by user code, including signal handlers.
+ * It is protected against deadlocks by the reentrance guard in profiler.h.
+ * However, when called from a signal handler that triggers while within
+ * __cxxprof_impl (under the guarded zone), no output will be produced.
+ */
+inline void __report(void)
+{
+ __mutex<0>::__lock(__mutex<0>::__global_lock);
+
+ __warning_vector_t __warnings;
+
+ FILE* __raw_file = __open_output_file("raw");
+ __trace_vector_size_report(__raw_file, __warnings);
+ __trace_hashtable_size_report(__raw_file, __warnings);
+ __trace_hash_func_report(__raw_file, __warnings);
+ __trace_vector_to_list_report(__raw_file, __warnings);
+ __trace_map_to_unordered_map_report(__raw_file, __warnings);
+ fclose(__raw_file);
+
+ // Sort data by magnitude.
+ // XXX: instead of sorting, should collect only top N for better performance.
+ size_t __cutoff = __min(__settings<0>::_S_max_warn_count,
+ __warnings.size());
+
+ std::sort(__warnings.begin(), __warnings.end(),
+ std::greater<__warning_vector_t::value_type>());
+ __warnings.resize(__cutoff);
+
+ FILE* __warn_file = __open_output_file("txt");
+ std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
+ fclose(__warn_file);
+
+ __mutex<0>::__unlock(__mutex<0>::__global_lock);
+}
+
+inline void __set_trace_path()
+{
+ char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
+
+ if (__env_trace_file_name) {
+ __settings<0>::_S_trace_file_name = __env_trace_file_name;
+ }
+
+ // Make sure early that we can create the trace file.
+ fclose(__open_output_file("txt"));
+}
+
+inline void __set_max_warn_count()
+{
+ char* __env_max_warn_count_str = getenv(
+ _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
+
+ if (__env_max_warn_count_str) {
+ __settings<0>::_S_max_warn_count = static_cast<size_t>(
+ atoi(__env_max_warn_count_str));
+ }
+}
+
+inline void __profcxx_init_unconditional()
+{
+ __mutex<0>::__lock(__mutex<0>::__global_lock);
+
+ __set_max_warn_count();
+
+ if (__is_invalid()) {
+
+ if (__settings<0>::_S_max_warn_count == 0) {
+
+ __turn_off();
+
+ } else {
+
+ __set_max_stack_trace_depth();
+ __set_max_mem();
+ __set_trace_path();
+
+ __trace_vector_size_init();
+ __trace_hashtable_size_init();
+ __trace_hash_func_init();
+ __trace_vector_to_list_init();
+ __trace_map_to_unordered_map_init();
+
+ atexit(__report);
+
+ __turn_on();
+
+ }
+ }
+
+ __mutex<0>::__unlock(__mutex<0>::__global_lock);
+}
+
+/** @brief This function must be called by each instrumentation point.
+ *
+ * The common path is inlined fully.
+ */
+inline bool __profcxx_init(void)
+{
+ if (__is_invalid()) {
+ __profcxx_init_unconditional();
+ }
+
+ return __is_on();
+}
+
+} // namespace __cxxprof_impl
+
+#endif /* PROFCXX_PROFILER_TRACE_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_vector_size.h b/libstdc++-v3/include/profile/impl/profiler_vector_size.h
new file mode 100644
index 00000000000..dd42959825f
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_size.h
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_vector_size.h
+ * @brief Collection of vector size traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_VECTOR_SIZE_H__
+#define PROFCXX_PROFILER_VECTOR_SIZE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+#include "profile/impl/profiler_state.h"
+#include "profile/impl/profiler_container_size.h"
+
+namespace __cxxprof_impl
+{
+
+/** @brief Hashtable size instrumentation trace producer. */
+class __trace_vector_size : public __trace_container_size
+{
+ public:
+ __trace_vector_size() : __trace_container_size() { __id = "vector-size"; }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_size_init()
+{
+ __tables<0>::_S_vector_size = new __trace_vector_size();
+}
+
+inline void __trace_vector_size_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_vector_size) {
+ __tables<0>::_S_vector_size->__collect_warnings(__warnings);
+ __tables<0>::_S_vector_size->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_size_construct(const void* __obj, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_size->__insert(__obj, __get_stack(), __num);
+}
+
+inline void __trace_vector_size_destruct(const void* __obj, size_t __num,
+ size_t __inum)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_size->__destruct(__obj, __num, __inum);
+}
+
+inline void __trace_vector_size_resize(const void* __obj, size_t __from,
+ size_t __to)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_size->__resize(__obj, __from, __to);
+}
+
+} // namespace __cxxprof_impl
+
+#endif /* PROFCXX_PROFILER_VECTOR_SIZE_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
new file mode 100644
index 00000000000..ec3dfbcfb86
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
@@ -0,0 +1,318 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 profile/impl/profiler_trace.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_VECTOR_TO_LIST_H__
+#define PROFCXX_PROFILER_VECTOR_TO_LIST_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#else
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+/** @brief A vector-to-list instrumentation line in the object table. */
+class __vector2list_info: public __object_info_base
+{
+ public:
+ __vector2list_info()
+ :_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
+ _M_vector_cost(0), _M_valid(true) {}
+ __vector2list_info(__stack_t __stack)
+ : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
+ _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) {}
+ virtual ~__vector2list_info() {}
+ __vector2list_info(const __vector2list_info& __o);
+ void __merge(const __vector2list_info& __o);
+ void __write(FILE* __f) const;
+ float __magnitude() const { return _M_vector_cost - _M_list_cost; }
+ const char* __advice() const { return "change std::vector to std::list"; }
+
+ size_t __shift_count() { return _M_shift_count; }
+ size_t __iterate() { return _M_iterate; }
+ float __list_cost() { return _M_list_cost; }
+ size_t __resize() { return _M_resize; }
+ void __set_list_cost(float __lc) { _M_list_cost = __lc; }
+ void __set_vector_cost(float __vc) { _M_vector_cost = __vc; }
+ bool __is_valid() { return _M_valid; }
+ void __set_invalid() { _M_valid = false; }
+
+ void __opr_insert(size_t __pos, size_t __num);
+ void __opr_iterate(size_t __num) { _M_iterate += __num; }
+ void __resize(size_t __from, size_t __to);
+
+private:
+ size_t _M_shift_count;
+ size_t _M_iterate;
+ size_t _M_resize;
+ float _M_list_cost;
+ float _M_vector_cost;
+ bool _M_valid;
+};
+
+inline __vector2list_info::__vector2list_info(const __vector2list_info& __o)
+ : __object_info_base(__o)
+{
+ _M_shift_count = __o._M_shift_count;
+ _M_iterate = __o._M_iterate;
+ _M_vector_cost = __o._M_vector_cost;
+ _M_list_cost = __o._M_list_cost;
+ _M_valid = __o._M_valid;
+ _M_resize = __o._M_resize;
+}
+
+inline void __vector2list_info::__merge(const __vector2list_info& __o)
+{
+ _M_shift_count += __o._M_shift_count;
+ _M_iterate += __o._M_iterate;
+ _M_vector_cost += __o._M_vector_cost;
+ _M_list_cost += __o._M_list_cost;
+ _M_valid &= __o._M_valid;
+ _M_resize += __o._M_resize;
+}
+
+inline void __vector2list_info::__opr_insert(size_t __pos, size_t __num)
+{
+ _M_shift_count += __num - __pos;
+}
+
+inline void __vector2list_info::__resize(size_t __from, size_t __to)
+{
+ _M_resize += __from;
+}
+
+/** @brief A vector-to-list instrumentation line in the stack table. */
+class __vector2list_stack_info: public __vector2list_info {
+ public:
+ __vector2list_stack_info(const __vector2list_info& __o)
+ : __vector2list_info(__o) {}
+};
+
+/** @brief Vector-to-list instrumentation producer. */
+class __trace_vector_to_list
+ : public __trace_base<__vector2list_info, __vector2list_stack_info>
+{
+ public:
+ __trace_vector_to_list();
+ ~__trace_vector_to_list() {}
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void __insert(__object_t __obj, __stack_t __stack);
+ // Call at destruction/clean to set container final size.
+ void __destruct(const void* __obj);
+
+ // Find the node in the live map.
+ __vector2list_info* __find(const void* __obj);
+
+ // Collect cost of operations.
+ void __opr_insert(const void* __obj, size_t __pos, size_t __num);
+ void __opr_iterate(const void* __obj, size_t __num);
+ void __invalid_operator(const void* __obj);
+ void __resize(const void* __obj, size_t __from, size_t __to);
+ float __vector_cost(size_t __shift, size_t __iterate, size_t __resize);
+ float __list_cost(size_t __shift, size_t __iterate, size_t __resize);
+};
+
+inline __trace_vector_to_list::__trace_vector_to_list()
+ : __trace_base<__vector2list_info, __vector2list_stack_info>()
+{
+ __id = "vector-to-list";
+}
+
+inline void __trace_vector_to_list::__insert(__object_t __obj,
+ __stack_t __stack)
+{
+ __add_object(__obj, __vector2list_info(__stack));
+}
+
+inline void __vector2list_info::__write(FILE* __f) const
+{
+ fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n",
+ _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
+}
+
+// Cost model. XXX: get this from the cost model database instead.
+// Vector operation cost:
+// - Cost per shift: 1
+// - Cost per access: 1
+// - Cost per resize: 1
+// List operation cost:
+// - Cost per shift: 0
+// - Cost per access: 10
+// - Cost per resize: 0
+
+inline float __trace_vector_to_list::__vector_cost(size_t __shift,
+ size_t __iterate,
+ size_t __resize)
+{
+ return __shift * 1 + __iterate * 1 + __resize * 1;
+}
+
+inline float __trace_vector_to_list::__list_cost(size_t __shift,
+ size_t __iterate,
+ size_t __resize)
+{
+ return __shift * 0 + __iterate * 10 + __resize * 0;
+}
+
+inline void __trace_vector_to_list::__destruct(const void* __obj)
+{
+ if (!__is_on())
+ return;
+
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (!__res)
+ return;
+
+ float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
+ __res->__resize());
+ float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
+ __res->__resize());
+ __res->__set_vector_cost(__vc);
+ __res->__set_list_cost(__lc);
+
+ __retire_object(__obj);
+}
+
+inline void __trace_vector_to_list::__opr_insert(const void* __obj,
+ size_t __pos, size_t __num)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_insert(__pos, __num);
+}
+
+inline void __trace_vector_to_list::__opr_iterate(const void* __obj,
+ size_t __num)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_iterate(__num);
+}
+
+inline void __trace_vector_to_list::__invalid_operator(const void* __obj)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__set_invalid();
+}
+
+inline void __trace_vector_to_list::__resize(const void* __obj, size_t __from,
+ size_t __to)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__resize(__from, __to);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_to_list_init()
+{
+ __tables<0>::_S_vector_to_list = new __trace_vector_to_list();
+}
+
+inline void __trace_vector_to_list_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_vector_to_list) {
+ __tables<0>::_S_vector_to_list->__collect_warnings(__warnings);
+ __tables<0>::_S_vector_to_list->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_to_list_construct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__insert(__obj, __get_stack());
+}
+
+inline void __trace_vector_to_list_destruct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__destruct(__obj);
+}
+
+inline void __trace_vector_to_list_insert(const void* __obj,
+ size_t __pos, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__opr_insert(__obj, __pos, __num);
+}
+
+
+inline void __trace_vector_to_list_iterate(const void* __obj, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__opr_iterate(__obj, __num);
+}
+
+inline void __trace_vector_to_list_invalid_operator(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__invalid_operator(__obj);
+}
+
+inline void __trace_vector_to_list_resize(const void* __obj,
+ size_t __from, size_t __to)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__resize(__obj, __from, __to);
+}
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_PROFILER_VECTOR_TO_LIST_H__ */
diff --git a/libstdc++-v3/include/profile/list b/libstdc++-v3/include/profile/list
new file mode 100644
index 00000000000..061c5065826
--- /dev/null
+++ b/libstdc++-v3/include/profile/list
@@ -0,0 +1,520 @@
+// Profiling list implementation -*- C++ -*-
+
+// Copyright (C) 2009 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 3, 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/list
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_LIST
+#define _GLIBCXX_PROFILE_LIST 1
+
+#include <list>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief List wrapper with performance instrumentation. */
+ template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
+ class list
+ : public _GLIBCXX_STD_D::list<_Tp, _Allocator>
+ {
+ typedef _GLIBCXX_STD_D::list<_Tp, _Allocator> _Base;
+
+ public:
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::difference_type difference_type;
+
+ typedef _Tp value_type;
+ typedef _Allocator allocator_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Base::const_pointer const_pointer;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ // 23.2.2.1 construct/copy/destroy:
+ explicit list(const _Allocator& __a = _Allocator())
+ : _Base(__a) { }
+
+ explicit list(size_type __n, const _Tp& __value = _Tp(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__n, __value, __a) { }
+
+ template<class _InputIterator>
+ list(_InputIterator __first, _InputIterator __last,
+ const _Allocator& __a = _Allocator())
+ : _Base(__first, __last, __a)
+ { }
+
+
+ list(const list& __x)
+ : _Base(__x) { }
+
+ list(const _Base& __x)
+ : _Base(__x) { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ list(list&& __x)
+ : _Base(std::forward<list>(__x))
+ { }
+
+ list(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __a) { }
+#endif
+
+ ~list() { }
+
+ list&
+ operator=(const list& __x)
+ {
+ static_cast<_Base&>(*this) = __x;
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ list&
+ operator=(list&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ list&
+ operator=(initializer_list<value_type> __l)
+ {
+ static_cast<_Base&>(*this) = __l;
+ return *this;
+ }
+
+ void
+ assign(initializer_list<value_type> __l)
+ {
+ _Base::assign(__l);
+ }
+#endif
+
+ template<class _InputIterator>
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
+ _Base::assign(__first, __last);
+ }
+
+ void
+ assign(size_type __n, const _Tp& __t)
+ {
+ _Base::assign(__n, __t);
+ }
+
+ using _Base::get_allocator;
+
+ // iterators:
+ iterator
+ begin()
+ { return iterator(_Base::begin()); }
+
+ const_iterator
+ begin() const
+ { return const_iterator(_Base::begin()); }
+
+ iterator
+ end()
+ { return iterator(_Base::end()); }
+
+ const_iterator
+ end() const
+ { return const_iterator(_Base::end()); }
+
+ 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()); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const_iterator
+ cbegin() const
+ { return const_iterator(_Base::begin()); }
+
+ const_iterator
+ cend() const
+ { return const_iterator(_Base::end()); }
+
+ const_reverse_iterator
+ crbegin() const
+ { return const_reverse_iterator(end()); }
+
+ const_reverse_iterator
+ crend() const
+ { return const_reverse_iterator(begin()); }
+#endif
+
+ // 23.2.2.2 capacity:
+ using _Base::empty;
+ using _Base::size;
+ using _Base::max_size;
+
+ void
+ resize(size_type __sz, _Tp __c = _Tp())
+ {
+ _Base::resize(__sz, __c);
+ }
+
+ // element access:
+ reference
+ front()
+ {
+ return _Base::front();
+ }
+
+ const_reference
+ front() const
+ {
+ return _Base::front();
+ }
+
+ reference
+ back()
+ {
+ return _Base::back();
+ }
+
+ const_reference
+ back() const
+ {
+ return _Base::back();
+ }
+
+ // 23.2.2.3 modifiers:
+ using _Base::push_front;
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ using _Base::emplace_front;
+#endif
+
+ void
+ pop_front()
+ {
+ iterator __victim = begin();
+ _Base::pop_front();
+ }
+
+ using _Base::push_back;
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ using _Base::emplace_back;
+#endif
+
+ void
+ pop_back()
+ {
+ iterator __victim = end();
+ --__victim;
+ _Base::pop_back();
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename... _Args>
+ iterator
+ emplace(iterator __position, _Args&&... __args)
+ {
+ return iterator(_Base::emplace(__position,
+ std::forward<_Args>(__args)...));
+ }
+#endif
+
+ iterator
+ insert(iterator __position, const _Tp& __x)
+ {
+ return iterator(_Base::insert(__position, __x));
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ iterator
+ insert(iterator __position, _Tp&& __x)
+ { return emplace(__position, std::move(__x)); }
+
+ void
+ insert(iterator __p, initializer_list<value_type> __l)
+ {
+ _Base::insert(__p, __l);
+ }
+#endif
+
+ void
+ insert(iterator __position, size_type __n, const _Tp& __x)
+ {
+ _Base::insert(__position, __n, __x);
+ }
+
+ template<class _InputIterator>
+ void
+ insert(iterator __position, _InputIterator __first,
+ _InputIterator __last)
+ {
+ _Base::insert(__position, __first, __last);
+ }
+
+ iterator
+ erase(iterator __position)
+ {
+ return iterator(_Base::erase(__position));
+ }
+
+ iterator
+ erase(iterator __position, iterator __last)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 151. can't currently clear() empty container
+ return iterator(_Base::erase(__position, __last));
+ }
+
+ void
+ swap(list& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ {
+ _Base::clear();
+ }
+
+ // 23.2.2.4 list operations:
+ void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ splice(iterator __position, list&& __x)
+#else
+ splice(iterator __position, list& __x)
+#endif
+ {
+ this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end());
+ }
+
+ void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ splice(iterator __position, list&& __x, iterator __i)
+#else
+ splice(iterator __position, list& __x, iterator __i)
+#endif
+ {
+ // We used to perform the splice_alloc check: not anymore, redundant
+ // after implementing the relevant bits of N1599.
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ _Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
+ __i);
+ }
+
+ void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ splice(iterator __position, list&& __x, iterator __first,
+ iterator __last)
+#else
+ splice(iterator __position, list& __x, iterator __first,
+ iterator __last)
+#endif
+ {
+ // We used to perform the splice_alloc check: not anymore, redundant
+ // after implementing the relevant bits of N1599.
+
+ _Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
+ __first, __last);
+ }
+
+ void
+ remove(const _Tp& __value)
+ {
+ for (iterator __x = begin(); __x != _Base::end(); )
+ {
+ if (*__x == __value)
+ __x = erase(__x);
+ else
+ ++__x;
+ }
+ }
+
+ template<class _Predicate>
+ void
+ remove_if(_Predicate __pred)
+ {
+ for (iterator __x = begin(); __x != _Base::end(); )
+ {
+ if (__pred(*__x))
+ __x = erase(__x);
+ else
+ ++__x;
+ }
+ }
+
+ void
+ unique()
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ if (__first == __last)
+ return;
+ iterator __next = __first;
+ while (++__next != __last)
+ {
+ if (*__first == *__next)
+ erase(__next);
+ else
+ __first = __next;
+ __next = __first;
+ }
+ }
+
+ template<class _BinaryPredicate>
+ void
+ unique(_BinaryPredicate __binary_pred)
+ {
+ iterator __first = begin();
+ iterator __last = end();
+ if (__first == __last)
+ return;
+ iterator __next = __first;
+ while (++__next != __last)
+ {
+ if (__binary_pred(*__first, *__next))
+ erase(__next);
+ else
+ __first = __next;
+ __next = __first;
+ }
+ }
+
+ void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ merge(list&& __x)
+#else
+ merge(list& __x)
+#endif
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 300. list::merge() specification incomplete
+ if (this != &__x)
+ {
+ _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
+ }
+ }
+
+ template<class _Compare>
+ void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ merge(list&& __x, _Compare __comp)
+#else
+ merge(list& __x, _Compare __comp)
+#endif
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 300. list::merge() specification incomplete
+ if (this != &__x)
+ {
+ _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
+ }
+ }
+
+ void
+ sort() { _Base::sort(); }
+
+ template<typename _StrictWeakOrdering>
+ void
+ sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
+
+ using _Base::reverse;
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+ };
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator==(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() == __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator!=(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() != __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() < __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<=(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() <= __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>=(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() >= __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() > __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+} // namespace __profile
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/profile/map b/libstdc++-v3/include/profile/map
new file mode 100644
index 00000000000..e396b852398
--- /dev/null
+++ b/libstdc++-v3/include/profile/map
@@ -0,0 +1,41 @@
+// Profiling map/multimap implementation -*- C++ -*-
+
+// Copyright (C) 2009 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// 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 profile/map
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_MAP
+#define _GLIBCXX_PROFILE_MAP 1
+
+#include <map>
+#include <profile/map.h>
+#include <profile/multimap.h>
+
+#endif
diff --git a/libstdc++-v3/include/profile/map.h b/libstdc++-v3/include/profile/map.h
new file mode 100644
index 00000000000..aa9e535a1e4
--- /dev/null
+++ b/libstdc++-v3/include/profile/map.h
@@ -0,0 +1,489 @@
+// Profiling map implementation -*- C++ -*-
+
+// Copyright (C) 2009 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// 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 profile/map.h
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_MAP_H
+#define _GLIBCXX_PROFILE_MAP_H 1
+
+#include <utility>
+#include <profile/base.h>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Map wrapper with performance instrumentation. */
+ template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
+ typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
+ class map
+ : public _GLIBCXX_STD_D::map<_Key, _Tp, _Compare, _Allocator>
+ {
+ typedef _GLIBCXX_STD_D::map<_Key, _Tp, _Compare, _Allocator> _Base;
+
+ public:
+ // types:
+ typedef _Key key_type;
+ typedef _Tp mapped_type;
+ typedef std::pair<const _Key, _Tp> value_type;
+ typedef _Compare key_compare;
+ typedef _Allocator allocator_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Base::const_pointer const_pointer;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ using _Base::value_compare;
+
+ // 23.3.1.1 construct/copy/destroy:
+ explicit map(const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__comp, __a) {
+ __profcxx_map_to_unordered_map_construct(this);
+ }
+
+ template<typename _InputIterator>
+ map(_InputIterator __first, _InputIterator __last,
+ const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__first, __last, __comp, __a) {
+ __profcxx_map_to_unordered_map_construct(this);
+ }
+
+ map(const map& __x)
+ : _Base(__x) {
+ __profcxx_map_to_unordered_map_construct(this);
+ }
+
+ map(const _Base& __x)
+ : _Base(__x) {
+ __profcxx_map_to_unordered_map_construct(this);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ map(map&& __x)
+ : _Base(std::forward<map>(__x))
+ { }
+
+ map(initializer_list<value_type> __l,
+ const _Compare& __c = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __c, __a) { }
+#endif
+
+ ~map() {
+ __profcxx_map_to_unordered_map_destruct(this);
+ }
+
+ map&
+ operator=(const map& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ map&
+ operator=(map&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ map&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+#endif
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 133. map missing get_allocator()
+ using _Base::get_allocator;
+
+ // iterators:
+ iterator
+ begin()
+ { return _Base::begin(); }
+
+ const_iterator
+ begin() const
+ { return _Base::begin(); }
+
+ iterator
+ end()
+ { return _Base::end(); }
+
+ const_iterator
+ end() const
+ { return _Base::end(); }
+
+ reverse_iterator
+ rbegin()
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return reverse_iterator(end());
+ }
+
+ const_reverse_iterator
+ rbegin() const
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return const_reverse_iterator(end());
+ }
+
+ reverse_iterator
+ rend()
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return reverse_iterator(begin());
+ }
+
+ const_reverse_iterator
+ rend() const
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return const_reverse_iterator(begin());
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const_iterator
+ cbegin() const
+ { return const_iterator(_Base::begin()); }
+
+ const_iterator
+ cend() const
+ { return const_iterator(_Base::end()); }
+
+ const_reverse_iterator
+ crbegin() const
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return const_reverse_iterator(end());
+ }
+
+ const_reverse_iterator
+ crend() const
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return const_reverse_iterator(begin());
+ }
+#endif
+
+ // capacity:
+ using _Base::empty;
+ using _Base::size;
+ using _Base::max_size;
+
+ // 23.3.1.2 element access:
+ mapped_type&
+ operator[](const key_type& __k)
+ {
+ __profcxx_map_to_unordered_map_find(this, size());
+ return _Base::operator[](__k);
+ }
+
+ mapped_type&
+ at(const key_type& __k)
+ {
+ __profcxx_map_to_unordered_map_find(this, size());
+ return _Base::at(__k);
+ }
+
+ const mapped_type&
+ at(const key_type& __k) const
+ {
+ __profcxx_map_to_unordered_map_find(this, size());
+ return _Base::at(__k);
+ }
+
+ // modifiers:
+ std::pair<iterator, bool>
+ insert(const value_type& __x)
+ {
+ __profcxx_map_to_unordered_map_insert(this, size(), 1);
+ typedef typename _Base::iterator _Base_iterator;
+ std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
+ return std::pair<iterator, bool>(iterator(__res.first),
+ __res.second);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(std::initializer_list<value_type> __list)
+ {
+ size_type size_before = size();
+ _Base::insert(__list);
+ __profcxx_map_to_unordered_map_insert(this, size_before,
+ size() - size_before);
+ }
+#endif
+
+ iterator
+ insert(iterator __position, const value_type& __x)
+ {
+ size_type size_before = size();
+ return iterator(_Base::insert(__position, __x));
+ __profcxx_map_to_unordered_map_insert(this, size_before,
+ size() - size_before);
+ }
+
+ template<typename _InputIterator>
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ {
+ size_type size_before = size();
+ _Base::insert(__first, __last);
+ __profcxx_map_to_unordered_map_insert(this, size_before,
+ size() - size_before);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ iterator
+ erase(iterator __position)
+ {
+ iterator __i = _Base::erase(__position);
+ __profcxx_map_to_unordered_map_erase(this, size(), 1);
+ return __i;
+ }
+#else
+ void
+ erase(iterator __position)
+ {
+ _Base::erase(__position);
+ __profcxx_map_to_unordered_map_erase(this, size(), 1);
+ }
+#endif
+
+ size_type
+ erase(const key_type& __x)
+ {
+ iterator __victim = find(__x);
+ if (__victim == end())
+ return 0;
+ else
+ {
+ _Base::erase(__victim);
+ return 1;
+ }
+ }
+
+ void
+ erase(iterator __first, iterator __last)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 151. can't currently clear() empty container
+ while (__first != __last)
+ this->erase(__first++);
+ }
+
+ void
+
+ swap(map& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ { this->erase(begin(), end()); }
+
+ // observers:
+ using _Base::key_comp;
+ using _Base::value_comp;
+
+ // 23.3.1.3 map operations:
+ iterator
+ find(const key_type& __x)
+ {
+ __profcxx_map_to_unordered_map_find(this, size());
+ return iterator(_Base::find(__x));
+ }
+
+ const_iterator
+ find(const key_type& __x) const
+ {
+ __profcxx_map_to_unordered_map_find(this, size());
+ return const_iterator(_Base::find(__x));
+ }
+
+ size_type
+ count(const key_type& __x) const
+ {
+ __profcxx_map_to_unordered_map_find(this, size());
+ return _Base::count(__x);
+ }
+
+ iterator
+ lower_bound(const key_type& __x)
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return iterator(_Base::lower_bound(__x));
+ }
+
+ const_iterator
+ lower_bound(const key_type& __x) const
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return const_iterator(_Base::lower_bound(__x));
+ }
+
+ iterator
+ upper_bound(const key_type& __x)
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return iterator(_Base::upper_bound(__x));
+ }
+
+ const_iterator
+ upper_bound(const key_type& __x) const
+ {
+ __profcxx_map_to_unordered_map_invalidate(this);
+ return const_iterator(_Base::upper_bound(__x));
+ }
+
+ std::pair<iterator,iterator>
+ equal_range(const key_type& __x)
+ {
+ typedef typename _Base::iterator _Base_iterator;
+ std::pair<_Base_iterator, _Base_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(iterator(__res.first),
+ iterator(__res.second));
+ }
+
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& __x) const
+ {
+ __profcxx_map_to_unordered_map_find(this, size());
+ typedef typename _Base::const_iterator _Base_const_iterator;
+ std::pair<_Base_const_iterator, _Base_const_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(const_iterator(__res.first),
+ const_iterator(__res.second));
+ }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+ };
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ {
+ __profcxx_map_to_unordered_map_invalidate(&__lhs);
+ __profcxx_map_to_unordered_map_invalidate(&__rhs);
+ return __lhs._M_base() == __rhs._M_base();
+ }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ {
+ __profcxx_map_to_unordered_map_invalidate(&__lhs);
+ __profcxx_map_to_unordered_map_invalidate(&__rhs);
+ return __lhs._M_base() != __rhs._M_base();
+ }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ {
+ __profcxx_map_to_unordered_map_invalidate(&__lhs);
+ __profcxx_map_to_unordered_map_invalidate(&__rhs);
+ return __lhs._M_base() < __rhs._M_base();
+ }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ {
+ __profcxx_map_to_unordered_map_invalidate(&__lhs);
+ __profcxx_map_to_unordered_map_invalidate(&__rhs);
+ return __lhs._M_base() <= __rhs._M_base();
+ }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ {
+ __profcxx_map_to_unordered_map_invalidate(&__lhs);
+ __profcxx_map_to_unordered_map_invalidate(&__rhs);
+ return __lhs._M_base() >= __rhs._M_base();
+ }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ {
+ __profcxx_map_to_unordered_map_invalidate(&__lhs);
+ __profcxx_map_to_unordered_map_invalidate(&__rhs);
+ return __lhs._M_base() > __rhs._M_base();
+ }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline void
+ swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { __lhs.swap(__rhs); }
+
+} // namespace __profile
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/profile/multimap.h b/libstdc++-v3/include/profile/multimap.h
new file mode 100644
index 00000000000..b1fc70b63b2
--- /dev/null
+++ b/libstdc++-v3/include/profile/multimap.h
@@ -0,0 +1,363 @@
+// Profiling multimap implementation -*- C++ -*-
+
+// Copyright (C) 2009 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 3, 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/multimap.h
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_MULTIMAP_H
+#define _GLIBCXX_PROFILE_MULTIMAP_H 1
+
+#include <utility>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Multimap wrapper with performance instrumentation. */
+ template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
+ typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
+ class multimap
+ : public _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator>
+ {
+ typedef _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
+
+ public:
+ // types:
+ typedef _Key key_type;
+ typedef _Tp mapped_type;
+ typedef std::pair<const _Key, _Tp> value_type;
+ typedef _Compare key_compare;
+ typedef _Allocator allocator_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef typename _Base::reverse_iterator reverse_iterator;
+ typedef typename _Base::const_reverse_iterator const_reverse_iterator;
+
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Base::const_pointer const_pointer;
+
+ using _Base::value_compare;
+
+ // 23.3.1.1 construct/copy/destroy:
+ explicit multimap(const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__comp, __a) { }
+
+ template<typename _InputIterator>
+ multimap(_InputIterator __first, _InputIterator __last,
+ const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__first, __last, __comp, __a) { }
+
+ multimap(const multimap& __x)
+ : _Base(__x) { }
+
+ multimap(const _Base& __x)
+ : _Base(__x) { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multimap(multimap&& __x)
+ : _Base(std::forward<multimap>(__x))
+ { }
+
+ multimap(initializer_list<value_type> __l,
+ const _Compare& __c = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __c, __a) { }
+#endif
+
+ ~multimap() { }
+
+ multimap&
+ operator=(const multimap& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multimap&
+ operator=(multimap&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ multimap&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+#endif
+
+ using _Base::get_allocator;
+
+ // iterators:
+ iterator
+ begin()
+ { return iterator(_Base::begin()); }
+
+ const_iterator
+ begin() const
+ { return const_iterator(_Base::begin()); }
+
+ iterator
+ end()
+ { return iterator(_Base::end()); }
+
+ const_iterator
+ end() const
+ { return const_iterator(_Base::end()); }
+
+ 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()); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const_iterator
+ cbegin() const
+ { return const_iterator(_Base::begin()); }
+
+ const_iterator
+ cend() const
+ { return const_iterator(_Base::end()); }
+
+ const_reverse_iterator
+ crbegin() const
+ { return const_reverse_iterator(end()); }
+
+ const_reverse_iterator
+ crend() const
+ { return const_reverse_iterator(begin()); }
+#endif
+
+ // capacity:
+ using _Base::empty;
+ using _Base::size;
+ using _Base::max_size;
+
+ // modifiers:
+ iterator
+ insert(const value_type& __x)
+ { return iterator(_Base::insert(__x)); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(std::initializer_list<value_type> __list)
+ { _Base::insert(__list); }
+#endif
+
+ iterator
+ insert(iterator __position, const value_type& __x)
+ {
+ return iterator(_Base::insert(__position, __x));
+ }
+
+ template<typename _InputIterator>
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ {
+ _Base::insert(__first, __last);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ iterator
+ erase(iterator __position)
+ {
+ return _Base::erase(__position);
+ }
+#else
+ void
+ erase(iterator __position)
+ {
+ _Base::erase(__position);
+ }
+#endif
+
+ size_type
+ erase(const key_type& __x)
+ {
+ std::pair<iterator, iterator> __victims = this->equal_range(__x);
+ size_type __count = 0;
+ while (__victims.first != __victims.second)
+ {
+ iterator __victim = __victims.first++;
+ _Base::erase(__victim);
+ ++__count;
+ }
+ return __count;
+ }
+
+ void
+ erase(iterator __first, iterator __last)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 151. can't currently clear() empty container
+ while (__first != __last)
+ this->erase(__first++);
+ }
+
+ void
+ swap(multimap& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ { this->erase(begin(), end()); }
+
+ // observers:
+ using _Base::key_comp;
+ using _Base::value_comp;
+
+ // 23.3.1.3 multimap operations:
+ iterator
+ find(const key_type& __x)
+ { return iterator(_Base::find(__x)); }
+
+ const_iterator
+ find(const key_type& __x) const
+ { return const_iterator(_Base::find(__x)); }
+
+ using _Base::count;
+
+ iterator
+ lower_bound(const key_type& __x)
+ { return iterator(_Base::lower_bound(__x)); }
+
+ const_iterator
+ lower_bound(const key_type& __x) const
+ { return const_iterator(_Base::lower_bound(__x)); }
+
+ iterator
+ upper_bound(const key_type& __x)
+ { return iterator(_Base::upper_bound(__x)); }
+
+ const_iterator
+ upper_bound(const key_type& __x) const
+ { return const_iterator(_Base::upper_bound(__x)); }
+
+ std::pair<iterator,iterator>
+ equal_range(const key_type& __x)
+ {
+ typedef typename _Base::iterator _Base_iterator;
+ std::pair<_Base_iterator, _Base_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(iterator(__res.first),
+ iterator(__res.second));
+ }
+
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& __x) const
+ {
+ typedef typename _Base::const_iterator _Base_const_iterator;
+ std::pair<_Base_const_iterator, _Base_const_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(const_iterator(__res.first),
+ const_iterator(__res.second));
+ }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+ };
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() == __rhs._M_base(); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() != __rhs._M_base(); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() < __rhs._M_base(); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() <= __rhs._M_base(); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() >= __rhs._M_base(); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline bool
+ operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() > __rhs._M_base(); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline void
+ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { __lhs.swap(__rhs); }
+
+} // namespace __profile
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/profile/multiset.h b/libstdc++-v3/include/profile/multiset.h
new file mode 100644
index 00000000000..759761bd52c
--- /dev/null
+++ b/libstdc++-v3/include/profile/multiset.h
@@ -0,0 +1,363 @@
+// Profiling multiset implementation -*- C++ -*-
+
+// Copyright (C) 2009 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 3, 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/multiset.h
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_MULTISET_H
+#define _GLIBCXX_PROFILE_MULTISET_H 1
+
+#include <utility>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Multiset wrapper with performance instrumentation. */
+ template<typename _Key, typename _Compare = std::less<_Key>,
+ typename _Allocator = std::allocator<_Key> >
+ class multiset
+ : public _GLIBCXX_STD_D::multiset<_Key, _Compare, _Allocator>
+ {
+ typedef _GLIBCXX_STD_D::multiset<_Key, _Compare, _Allocator> _Base;
+
+ public:
+ // types:
+ typedef _Key key_type;
+ typedef _Key value_type;
+ typedef _Compare key_compare;
+ typedef _Compare value_compare;
+ typedef _Allocator allocator_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef typename _Base::reverse_iterator reverse_iterator;
+ typedef typename _Base::const_reverse_iterator const_reverse_iterator;
+
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Base::const_pointer const_pointer;
+
+ // 23.3.3.1 construct/copy/destroy:
+ explicit multiset(const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__comp, __a) { }
+
+ template<typename _InputIterator>
+ multiset(_InputIterator __first, _InputIterator __last,
+ const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__first, __last, __comp, __a) { }
+
+ multiset(const multiset& __x)
+ : _Base(__x) { }
+
+ multiset(const _Base& __x)
+ : _Base(__x) { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multiset(multiset&& __x)
+ : _Base(std::forward<multiset>(__x))
+ { }
+
+ multiset(initializer_list<value_type> __l,
+ const _Compare& __comp = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __comp, __a) { }
+#endif
+
+ ~multiset() { }
+
+ multiset&
+ operator=(const multiset& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multiset&
+ operator=(multiset&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ multiset&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+#endif
+
+ using _Base::get_allocator;
+
+ // iterators:
+ iterator
+ begin()
+ { return iterator(_Base::begin()); }
+
+ const_iterator
+ begin() const
+ { return const_iterator(_Base::begin()); }
+
+ iterator
+ end()
+ { return iterator(_Base::end()); }
+
+ const_iterator
+ end() const
+ { return const_iterator(_Base::end()); }
+
+ 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()); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const_iterator
+ cbegin() const
+ { return const_iterator(_Base::begin()); }
+
+ const_iterator
+ cend() const
+ { return const_iterator(_Base::end()); }
+
+ const_reverse_iterator
+ crbegin() const
+ { return const_reverse_iterator(end()); }
+
+ const_reverse_iterator
+ crend() const
+ { return const_reverse_iterator(begin()); }
+#endif
+
+ // capacity:
+ using _Base::empty;
+ using _Base::size;
+ using _Base::max_size;
+
+ // modifiers:
+ iterator
+ insert(const value_type& __x)
+ { return iterator(_Base::insert(__x)); }
+
+ iterator
+ insert(iterator __position, const value_type& __x)
+ {
+ return iterator(_Base::insert(__position, __x));
+ }
+
+ template<typename _InputIterator>
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ {
+ _Base::insert(__first, __last);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(initializer_list<value_type> __l)
+ { _Base::insert(__l); }
+#endif
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ iterator
+ erase(iterator __position)
+ {
+ return _Base::erase(__position);
+ }
+#else
+ void
+ erase(iterator __position)
+ {
+ _Base::erase(__position);
+ }
+#endif
+
+ size_type
+ erase(const key_type& __x)
+ {
+ std::pair<iterator, iterator> __victims = this->equal_range(__x);
+ size_type __count = 0;
+ while (__victims.first != __victims.second)
+ {
+ iterator __victim = __victims.first++;
+ _Base::erase(__victim);
+ ++__count;
+ }
+ return __count;
+ }
+
+ void
+ erase(iterator __first, iterator __last)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 151. can't currently clear() empty container
+ while (__first != __last)
+ this->erase(__first++);
+ }
+
+ void
+ swap(multiset& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ { this->erase(begin(), end()); }
+
+ // observers:
+ using _Base::key_comp;
+ using _Base::value_comp;
+
+ // multiset operations:
+ iterator
+ find(const key_type& __x)
+ { return iterator(_Base::find(__x)); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ const_iterator
+ find(const key_type& __x) const
+ { return const_iterator(_Base::find(__x)); }
+
+ using _Base::count;
+
+ iterator
+ lower_bound(const key_type& __x)
+ { return iterator(_Base::lower_bound(__x)); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ const_iterator
+ lower_bound(const key_type& __x) const
+ { return const_iterator(_Base::lower_bound(__x)); }
+
+ iterator
+ upper_bound(const key_type& __x)
+ { return iterator(_Base::upper_bound(__x)); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ const_iterator
+ upper_bound(const key_type& __x) const
+ { return const_iterator(_Base::upper_bound(__x)); }
+
+ std::pair<iterator,iterator>
+ equal_range(const key_type& __x)
+ {
+ typedef typename _Base::iterator _Base_iterator;
+ std::pair<_Base_iterator, _Base_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(iterator(__res.first),
+ iterator(__res.second));
+ }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& __x) const
+ {
+ typedef typename _Base::const_iterator _Base_iterator;
+ std::pair<_Base_iterator, _Base_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(const_iterator(__res.first),
+ const_iterator(__res.second));
+ }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+ };
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator==(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() == __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator!=(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() != __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator<(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() < __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator<=(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() <= __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator>=(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() >= __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator>(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() > __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ void
+ swap(multiset<_Key, _Compare, _Allocator>& __x,
+ multiset<_Key, _Compare, _Allocator>& __y)
+ { return __x.swap(__y); }
+
+} // namespace __profile
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/profile/set b/libstdc++-v3/include/profile/set
new file mode 100644
index 00000000000..11603a84858
--- /dev/null
+++ b/libstdc++-v3/include/profile/set
@@ -0,0 +1,41 @@
+// Profiling set/multiset implementation -*- C++ -*-
+
+// Copyright (C) 2009 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// 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 profile/set
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_SET
+#define _GLIBCXX_PROFILE_SET 1
+
+#include <set>
+#include <profile/set.h>
+#include <profile/multiset.h>
+
+#endif
diff --git a/libstdc++-v3/include/profile/set.h b/libstdc++-v3/include/profile/set.h
new file mode 100644
index 00000000000..50fb16faf37
--- /dev/null
+++ b/libstdc++-v3/include/profile/set.h
@@ -0,0 +1,367 @@
+// Profiling set implementation -*- C++ -*-
+
+// Copyright (C) 2009 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 3, 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/set.h
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_SET_H
+#define _GLIBCXX_PROFILE_SET_H 1
+
+#include <utility>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Set wrapper with performance instrumentation. */
+ template<typename _Key, typename _Compare = std::less<_Key>,
+ typename _Allocator = std::allocator<_Key> >
+ class set
+ : public _GLIBCXX_STD_D::set<_Key,_Compare,_Allocator>
+ {
+ typedef _GLIBCXX_STD_D::set<_Key, _Compare, _Allocator> _Base;
+
+ public:
+ // types:
+ typedef _Key key_type;
+ typedef _Key value_type;
+ typedef _Compare key_compare;
+ typedef _Compare value_compare;
+ typedef _Allocator allocator_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef typename _Base::reverse_iterator reverse_iterator;
+ typedef typename _Base::const_reverse_iterator const_reverse_iterator;
+
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Base::const_pointer const_pointer;
+
+ // 23.3.3.1 construct/copy/destroy:
+ explicit set(const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__comp, __a) { }
+
+ template<typename _InputIterator>
+ set(_InputIterator __first, _InputIterator __last,
+ const _Compare& __comp = _Compare(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__first, __last, __comp, __a) { }
+
+ set(const set& __x)
+ : _Base(__x) { }
+
+ set(const _Base& __x)
+ : _Base(__x) { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ set(set&& __x)
+ : _Base(std::forward<set>(__x))
+ { }
+
+ set(initializer_list<value_type> __l,
+ const _Compare& __comp = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __comp, __a) { }
+#endif
+
+ ~set() { }
+
+ set&
+ operator=(const set& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ set&
+ operator=(set&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ set&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+#endif
+
+ using _Base::get_allocator;
+
+ // iterators:
+ iterator
+ begin()
+ { return iterator(_Base::begin()); }
+
+ const_iterator
+ begin() const
+ { return const_iterator(_Base::begin()); }
+
+ iterator
+ end()
+ { return iterator(_Base::end()); }
+
+ const_iterator
+ end() const
+ { return const_iterator(_Base::end()); }
+
+ 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()); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const_iterator
+ cbegin() const
+ { return const_iterator(_Base::begin()); }
+
+ const_iterator
+ cend() const
+ { return const_iterator(_Base::end()); }
+
+ const_reverse_iterator
+ crbegin() const
+ { return const_reverse_iterator(end()); }
+
+ const_reverse_iterator
+ crend() const
+ { return const_reverse_iterator(begin()); }
+#endif
+
+ // capacity:
+ using _Base::empty;
+ using _Base::size;
+ using _Base::max_size;
+
+ // modifiers:
+ std::pair<iterator, bool>
+ insert(const value_type& __x)
+ {
+ typedef typename _Base::iterator _Base_iterator;
+ std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
+ return std::pair<iterator, bool>(iterator(__res.first),
+ __res.second);
+ }
+
+ iterator
+ insert(iterator __position, const value_type& __x)
+ {
+ return iterator(_Base::insert(__position, __x));
+ }
+
+ template <typename _InputIterator>
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ {
+ _Base::insert(__first, __last);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(initializer_list<value_type> __l)
+ { _Base::insert(__l); }
+#endif
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ iterator
+ erase(iterator __position)
+ {
+ return _Base::erase(__position);
+ }
+#else
+ void
+ erase(iterator __position)
+ {
+ _Base::erase(__position);
+ }
+#endif
+
+ size_type
+ erase(const key_type& __x)
+ {
+ iterator __victim = find(__x);
+ if (__victim == end())
+ return 0;
+ else
+ {
+ _Base::erase(__victim);
+ return 1;
+ }
+ }
+
+ void
+ erase(iterator __first, iterator __last)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 151. can't currently clear() empty container
+ while (__first != __last)
+ this->erase(__first++);
+ }
+
+ void
+ swap(set& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ { this->erase(begin(), end()); }
+
+ // observers:
+ using _Base::key_comp;
+ using _Base::value_comp;
+
+ // set operations:
+ iterator
+ find(const key_type& __x)
+ { return iterator(_Base::find(__x)); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ const_iterator
+ find(const key_type& __x) const
+ { return const_iterator(_Base::find(__x)); }
+
+ using _Base::count;
+
+ iterator
+ lower_bound(const key_type& __x)
+ { return iterator(_Base::lower_bound(__x)); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ const_iterator
+ lower_bound(const key_type& __x) const
+ { return const_iterator(_Base::lower_bound(__x)); }
+
+ iterator
+ upper_bound(const key_type& __x)
+ { return iterator(_Base::upper_bound(__x)); }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ const_iterator
+ upper_bound(const key_type& __x) const
+ { return const_iterator(_Base::upper_bound(__x)); }
+
+ std::pair<iterator,iterator>
+ equal_range(const key_type& __x)
+ {
+ typedef typename _Base::iterator _Base_iterator;
+ std::pair<_Base_iterator, _Base_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(iterator(__res.first),
+ iterator(__res.second));
+ }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 214. set::find() missing const overload
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& __x) const
+ {
+ typedef typename _Base::const_iterator _Base_iterator;
+ std::pair<_Base_iterator, _Base_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(const_iterator(__res.first),
+ const_iterator(__res.second));
+ }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+ };
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator==(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() == __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator!=(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() != __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator<(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() < __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator<=(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() <= __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator>=(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() >= __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ inline bool
+ operator>(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
+ { return __lhs._M_base() > __rhs._M_base(); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ void
+ swap(set<_Key, _Compare, _Allocator>& __x,
+ set<_Key, _Compare, _Allocator>& __y)
+ { return __x.swap(__y); }
+
+} // namespace __profile
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/profile/unordered_map b/libstdc++-v3/include/profile/unordered_map
new file mode 100644
index 00000000000..d1cb9217d23
--- /dev/null
+++ b/libstdc++-v3/include/profile/unordered_map
@@ -0,0 +1,498 @@
+// Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
+
+// Copyright (C) 2009 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// 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 profile/unordered_map
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
+#define _GLIBCXX_PROFILE_UNORDERED_MAP 1
+
+#include <profile/base.h>
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+# include <unordered_map>
+#else
+# include <c++0x_warning.h>
+#endif
+
+#include <initializer_list>
+
+#define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
+#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Unordered_map wrapper with performance instrumentation. */
+ template<typename _Key, typename _Tp,
+ typename _Hash = std::hash<_Key>,
+ typename _Pred = std::equal_to<_Key>,
+ typename _Alloc = std::allocator<_Key> >
+ class unordered_map
+ : public _GLIBCXX_STD_BASE
+ {
+ typedef typename _GLIBCXX_STD_BASE _Base;
+
+ public:
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::hasher hasher;
+ typedef typename _Base::key_equal key_equal;
+ typedef typename _Base::allocator_type allocator_type;
+ typedef typename _Base::key_type key_type;
+ typedef typename _Base::value_type value_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+ typedef typename _Base::mapped_type mapped_type;
+ typedef std::pair<typename _Base::iterator, bool> pair_type;
+ typedef typename _Base::insert_return_type insert_return_type;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+
+ explicit
+ unordered_map(size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ template<typename _InputIterator>
+ unordered_map(_InputIterator __f, _InputIterator __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__f, __l, __n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ unordered_map(const _Base& __x)
+ : _Base(__x)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ unordered_map(unordered_map&& __x)
+ : _Base(std::forward<_Base>(__x))
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ unordered_map(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __n, __hf, __eql, __a) { }
+
+ unordered_map&
+ operator=(const unordered_map& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+ unordered_map&
+ operator=(unordered_map&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ unordered_map&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
+ ~unordered_map()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
+ _M_profile_destruct();
+ }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+
+ void
+ clear()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
+ _M_profile_destruct();
+ _Base::clear();
+ }
+
+ void
+ insert(std::initializer_list<value_type> __l)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__l);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ insert_return_type
+ insert(const value_type& __obj)
+ {
+ size_type __old_size = _Base::bucket_count();
+ insert_return_type __res = _Base::insert(__obj);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return __res;
+ }
+ iterator
+ insert(iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ iterator res = _Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ const_iterator
+ insert(const_iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ const_iterator res =_Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ template<typename _InputIter>
+ void
+ insert(_InputIter __first, _InputIter __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first.base(), __last.base());
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ void
+ insert(const value_type* __first, const value_type* __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first, __last);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ // operator []
+ mapped_type&
+ operator[](const _Key& _k)
+ {
+ size_type __old_size = _Base::bucket_count();
+ mapped_type& __res = _M_base()[_k];
+ size_type __new_size = _Base::bucket_count();
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return __res;
+ }
+
+ void
+ swap(unordered_map& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void rehash(size_type __n)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::rehash(__n);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+ private:
+ void _M_profile_resize(size_type __old_size, size_type __new_size)
+ {
+ if (__old_size != __new_size)
+ {
+ __profcxx_hashtable_resize(this, __old_size, __new_size);
+ }
+ }
+ void _M_profile_destruct()
+ {
+ size_type __hops = 0, __lc = 0, __chain = 0;
+ for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
+ {
+ while (it._M_cur_node->_M_next) {
+ __chain++;
+ it++;
+ }
+ if (__chain) {
+ __chain++;
+ __lc = __lc > __chain ? __lc : __chain;
+ __hops += __chain * (__chain - 1) / 2;
+ __chain = 0;
+ }
+ }
+ __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
+ }
+ };
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline void
+ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { __x.swap(__y); }
+
+#undef _GLIBCXX_BASE
+#undef _GLIBCXX_STD_BASE
+#define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
+#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
+
+ /** @brief Unordered_multimap wrapper with performance instrumentation. */
+ template<typename _Key, typename _Tp,
+ typename _Hash = std::hash<_Key>,
+ typename _Pred = std::equal_to<_Key>,
+ typename _Alloc = std::allocator<_Key> >
+ class unordered_multimap
+ : public _GLIBCXX_STD_BASE
+ {
+ typedef typename _GLIBCXX_STD_BASE _Base;
+
+ public:
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::hasher hasher;
+ typedef typename _Base::key_equal key_equal;
+ typedef typename _Base::allocator_type allocator_type;
+ typedef typename _Base::key_type key_type;
+ typedef typename _Base::value_type value_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+ typedef std::pair<typename _Base::iterator, bool> pair_type;
+ typedef typename _Base::insert_return_type insert_return_type;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+
+ explicit
+ unordered_multimap(size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+ template<typename _InputIterator>
+ unordered_multimap(_InputIterator __f, _InputIterator __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__f, __l, __n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+
+ unordered_multimap(const _Base& __x)
+ : _Base(__x)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+
+ unordered_multimap(unordered_multimap&& __x)
+ : _Base(std::forward<_Base>(__x))
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+
+ unordered_multimap(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __n, __hf, __eql, __a) { }
+
+ unordered_multimap&
+ operator=(const unordered_multimap& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+ unordered_multimap&
+ operator=(unordered_multimap&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ unordered_multimap&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
+ ~unordered_multimap()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
+ _M_profile_destruct();
+ }
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+
+ void
+ clear()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(), _Base::size());
+ _M_profile_destruct();
+ _Base::clear();
+ }
+
+ void
+ insert(std::initializer_list<value_type> __l)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__l);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ insert_return_type
+ insert(const value_type& __obj)
+ {
+ size_type __old_size = _Base::bucket_count();
+ insert_return_type __res = _Base::insert(__obj);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return __res;
+ }
+ iterator
+ insert(iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ iterator res = _Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ const_iterator
+ insert(const_iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ const_iterator res =_Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ template<typename _InputIter>
+ void
+ insert(_InputIter __first, _InputIter __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first.base(), __last.base());
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ void
+ insert(const value_type* __first, const value_type* __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first, __last);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ void
+ swap(unordered_multimap& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void rehash(size_type __n)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::rehash(__n);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+ private:
+ void _M_profile_resize(size_type __old_size, size_type __new_size)
+ {
+ if (__old_size != __new_size)
+ {
+ __profcxx_hashtable_resize(this, __old_size, __new_size);
+ }
+ }
+
+ void _M_profile_destruct()
+ {
+ size_type __hops = 0, __lc = 0, __chain = 0;
+ for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
+ {
+ while (it._M_cur_node->_M_next) {
+ __chain++;
+ it++;
+ }
+ if (__chain) {
+ __chain++;
+ __lc = __lc > __chain ? __lc : __chain;
+ __hops += __chain * (__chain - 1) / 2;
+ __chain = 0;
+ }
+ }
+ __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
+ }
+
+ };
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline void
+ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { __x.swap(__y); }
+
+} // namespace __profile
+} // namespace std
+
+#undef _GLIBCXX_BASE
+#undef _GLIBCXX_STD_BASE
+
+#endif
diff --git a/libstdc++-v3/include/profile/unordered_set b/libstdc++-v3/include/profile/unordered_set
new file mode 100644
index 00000000000..6c2dd77cb5f
--- /dev/null
+++ b/libstdc++-v3/include/profile/unordered_set
@@ -0,0 +1,480 @@
+// Profiling unordered_set/unordered_multiset implementation -*- C++ -*-
+
+// Copyright (C) 2009 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// 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 profile/unordered_set
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_UNORDERED_SET
+#define _GLIBCXX_PROFILE_UNORDERED_SET 1
+
+#include <profile/base.h>
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+# include <unordered_set>
+#else
+# include <c++0x_warning.h>
+#endif
+
+#include <initializer_list>
+
+#define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
+#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Unordered_set wrapper with performance instrumentation. */
+ template<typename _Key,
+ typename _Hash = std::hash<_Key>,
+ typename _Pred = std::equal_to<_Key>,
+ typename _Alloc = std::allocator<_Key> >
+ class unordered_set
+ : public _GLIBCXX_STD_BASE
+ {
+ typedef typename _GLIBCXX_STD_BASE _Base;
+
+ public:
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::hasher hasher;
+ typedef typename _Base::key_equal key_equal;
+ typedef typename _Base::allocator_type allocator_type;
+ typedef typename _Base::key_type key_type;
+ typedef typename _Base::value_type value_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+ typedef typename _Base::insert_return_type insert_return_type;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+
+ explicit
+ unordered_set(size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ template<typename _InputIterator>
+ unordered_set(_InputIterator __f, _InputIterator __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__f, __l, __n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ unordered_set(const _Base& __x)
+ : _Base(__x)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ unordered_set(unordered_set&& __x)
+ : _Base(std::forward<_Base>(__x))
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ __profcxx_hashtable_construct2(this);
+ }
+
+ unordered_set(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __n, __hf, __eql, __a) { }
+
+ unordered_set&
+ operator=(const unordered_set& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+ unordered_set&
+ operator=(unordered_set&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ unordered_set&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
+ ~unordered_set()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(),
+ _Base::size());
+ _M_profile_destruct();
+ }
+
+ void
+ swap(unordered_set& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(),
+ _Base::size());
+ _M_profile_destruct();
+ _Base::clear();
+ }
+ void
+ insert(std::initializer_list<value_type> __l)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__l);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+ insert_return_type insert(const value_type& __obj)
+ {
+ size_type __old_size = _Base::bucket_count();
+ insert_return_type __res = _Base::insert(__obj);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return __res;
+ }
+ iterator
+ insert(iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ iterator res = _Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ const_iterator
+ insert(const_iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ const_iterator res =_Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ template<typename _InputIter>
+ void
+ insert(_InputIter __first, _InputIter __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first, __last);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ void
+ insert(const value_type* __first, const value_type* __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first, __last);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ void rehash(size_type __n)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::rehash(__n);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+ private:
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+ void _M_profile_resize(size_type __old_size, size_type __new_size)
+ {
+ if (__old_size != __new_size)
+ {
+ __profcxx_hashtable_resize(this, __old_size, __new_size);
+ }
+ }
+ void _M_profile_destruct()
+ {
+ size_type __hops = 0, __lc = 0, __chain = 0;
+ for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
+ {
+ while (it._M_cur_node->_M_next) {
+ __chain++;
+ it++;
+ }
+ if (__chain) {
+ __chain++;
+ __lc = __lc > __chain ? __lc : __chain;
+ __hops += __chain * (__chain - 1) / 2;
+ __chain = 0;
+ }
+ }
+ __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
+ }
+
+ };
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline void
+ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+ unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+ { __x.swap(__y); }
+
+#undef _GLIBCXX_BASE
+#undef _GLIBCXX_STD_BASE
+#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
+#define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
+
+ /** @brief Unordered_multiset wrapper with performance instrumentation. */
+ template<typename _Value,
+ typename _Hash = std::hash<_Value>,
+ typename _Pred = std::equal_to<_Value>,
+ typename _Alloc = std::allocator<_Value> >
+ class unordered_multiset
+ : public _GLIBCXX_STD_BASE
+ {
+ typedef typename _GLIBCXX_STD_BASE _Base;
+
+ public:
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::hasher hasher;
+ typedef typename _Base::key_equal key_equal;
+ typedef typename _Base::allocator_type allocator_type;
+ typedef typename _Base::key_type key_type;
+ typedef typename _Base::value_type value_type;
+ typedef typename _Base::difference_type difference_type;
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+ typedef typename _Base::insert_return_type insert_return_type;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+
+ explicit
+ unordered_multiset(size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+
+ template<typename _InputIterator>
+ unordered_multiset(_InputIterator __f, _InputIterator __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__f, __l, __n, __hf, __eql, __a)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+
+ unordered_multiset(const _Base& __x)
+ : _Base(__x)
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+
+ unordered_multiset(unordered_multiset&& __x)
+ : _Base(std::forward<_Base>(__x))
+ {
+ __profcxx_hashtable_construct(this, _Base::bucket_count());
+ }
+
+ unordered_multiset(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __n, __hf, __eql, __a) { }
+
+ unordered_multiset&
+ operator=(const unordered_multiset& __x)
+ {
+ *static_cast<_Base*>(this) = __x;
+ return *this;
+ }
+
+ unordered_multiset&
+ operator=(unordered_multiset&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ unordered_multiset&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
+ ~unordered_multiset()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(),
+ _Base::size());
+ _M_profile_destruct();
+ }
+
+ void
+ swap(unordered_multiset& __x)
+ {
+ _Base::swap(__x);
+ }
+
+ void
+ clear()
+ {
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(),
+ _Base::size());
+ _M_profile_destruct();
+ _Base::clear();
+ }
+ void
+ insert(std::initializer_list<value_type> __l)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__l);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+ insert_return_type insert(const value_type& __obj)
+ {
+ size_type __old_size = _Base::bucket_count();
+ insert_return_type __res = _Base::insert(__obj);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return __res;
+ }
+ iterator
+ insert(iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ iterator res = _Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ const_iterator
+ insert(const_iterator __iter, const value_type& __v)
+ {
+ size_type __old_size = _Base::bucket_count();
+ const_iterator res =_Base::insert(__iter, __v);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ return res;
+ }
+
+ template<typename _InputIter>
+ void
+ insert(_InputIter __first, _InputIter __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first, __last);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ void
+ insert(const value_type* __first, const value_type* __last)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::insert(__first, __last);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+
+ void rehash(size_type __n)
+ {
+ size_type __old_size = _Base::bucket_count();
+ _Base::rehash(__n);
+ _M_profile_resize(__old_size, _Base::bucket_count());
+ }
+ private:
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+ void _M_profile_resize(size_type __old_size, size_type __new_size)
+ {
+ if (__old_size != __new_size)
+ {
+ __profcxx_hashtable_resize(this, __old_size, __new_size);
+ }
+ }
+
+ void _M_profile_destruct()
+ {
+ size_type __hops = 0, __lc = 0, __chain = 0;
+ for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
+ {
+ while (it._M_cur_node->_M_next) {
+ __chain++;
+ it++;
+ }
+ if (__chain) {
+ __chain++;
+ __lc = __lc > __chain ? __lc : __chain;
+ __hops += __chain * (__chain - 1) / 2;
+ __chain = 0;
+ }
+ }
+ __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
+ }
+
+ };
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline void
+ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+ unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+ { __x.swap(__y); }
+
+} // namespace __profile
+} // namespace std
+
+#undef _GLIBCXX_BASE
+#undef _GLIBCXX_STD_BASE
+
+#endif
diff --git a/libstdc++-v3/include/profile/vector b/libstdc++-v3/include/profile/vector
new file mode 100644
index 00000000000..e6aeb686a7a
--- /dev/null
+++ b/libstdc++-v3/include/profile/vector
@@ -0,0 +1,369 @@
+// Profiling vector implementation -*- C++ -*-
+
+// Copyright (C) 2009 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// 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 profile/vector
+ * This file is a GNU profile extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_PROFILE_VECTOR
+#define _GLIBCXX_PROFILE_VECTOR 1
+
+#include <vector>
+#include <utility>
+#include <profile/base.h>
+
+namespace std
+{
+namespace __profile
+{
+ /** @brief Vector wrapper with performance instrumentation. */
+ template<typename _Tp,
+ typename _Allocator = std::allocator<_Tp> >
+ class vector
+ : public _GLIBCXX_STD_PR::vector<_Tp, _Allocator>
+ {
+ typedef _GLIBCXX_STD_PR::vector<_Tp, _Allocator> _Base;
+
+ public:
+ typedef typename _Base::reference reference;
+ typedef typename _Base::const_reference const_reference;
+
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+
+ typedef typename _Base::size_type size_type;
+ typedef typename _Base::difference_type difference_type;
+
+ typedef _Tp value_type;
+ typedef _Allocator allocator_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Base::const_pointer const_pointer;
+
+ _Base&
+ _M_base() { return *this; }
+
+ const _Base&
+ _M_base() const { return *this; }
+
+ // 23.2.4.1 construct/copy/destroy:
+ explicit vector(const _Allocator& __a = _Allocator())
+ : _Base(__a)
+ {
+ __profcxx_vector_construct(this, this->capacity());
+ __profcxx_vector_construct2(this);
+ }
+
+ explicit vector(size_type __n, const _Tp& __value = _Tp(),
+ const _Allocator& __a = _Allocator())
+ : _Base(__n, __value, __a)
+ {
+ __profcxx_vector_construct(this, this->capacity());
+ __profcxx_vector_construct2(this);
+ }
+
+ template<class _InputIterator>
+ vector(_InputIterator __first, _InputIterator __last,
+ const _Allocator& __a = _Allocator())
+ : _Base(__first, __last, __a)
+ {
+ __profcxx_vector_construct(this, this->capacity());
+ __profcxx_vector_construct2(this);
+ }
+
+ vector(const vector& __x)
+ : _Base(__x)
+ {
+ __profcxx_vector_construct(this, this->capacity());
+ __profcxx_vector_construct2(this);
+ }
+
+ /// Construction from a release-mode vector
+ vector(const _Base& __x)
+ : _Base(__x)
+ {
+ __profcxx_vector_construct(this, this->capacity());
+ __profcxx_vector_construct2(this);
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ vector(vector&& __x)
+ : _Base(std::forward<vector>(__x))
+ {
+ __profcxx_vector_construct(this, this->capacity());
+ __profcxx_vector_construct2(this);
+ }
+
+ vector(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __a) { }
+#endif
+
+ ~vector() {
+ __profcxx_vector_destruct(this, this->capacity(), this->size());
+ __profcxx_vector_destruct2(this);
+ }
+
+ vector&
+ operator=(const vector& __x)
+ {
+ static_cast<_Base&>(*this) = __x;
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ vector&
+ operator=(vector&& __x)
+ {
+ // NB: DR 675.
+ this->clear();
+ this->swap(__x);
+ return *this;
+ }
+
+ vector&
+ operator=(initializer_list<value_type> __l)
+ {
+ static_cast<_Base&>(*this) = __l;
+ return *this;
+ }
+#endif
+
+ using _Base::assign;
+ using _Base::get_allocator;
+
+ // 23.2.4.2 capacity:
+ using _Base::size;
+ using _Base::max_size;
+
+ void
+ resize(size_type __sz, _Tp __c = _Tp())
+ {
+ __profcxx_vector_invalid_operator(this);
+ _M_profile_resize(this, this->capacity(), __sz);
+ _Base::resize(__sz, __c);
+ }
+
+ using _Base::empty;
+
+ // element access:
+ reference
+ operator[](size_type __n)
+ {
+ __profcxx_vector_invalid_operator(this);
+ return _M_base()[__n];
+ }
+ const_reference
+ operator[](size_type __n) const
+ {
+ __profcxx_vector_invalid_operator(this);
+ return _M_base()[__n];
+ }
+
+ using _Base::at;
+
+ reference
+ front()
+ {
+ return _Base::front();
+ }
+
+ const_reference
+ front() const
+ {
+ return _Base::front();
+ }
+
+ reference
+ back()
+ {
+ return _Base::back();
+ }
+
+ const_reference
+ back() const
+ {
+ return _Base::back();
+ }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 464. Suggestion for new member functions in standard containers.
+ using _Base::data;
+
+ // 23.2.4.3 modifiers:
+ void
+ push_back(const _Tp& __x)
+ {
+ size_type __old_size = this->capacity();
+ _Base::push_back(__x);
+ _M_profile_resize(this, __old_size, this->capacity());
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ push_back(_Tp&& __x)
+ {
+ size_type __old_size = this->capacity();
+ _Base::push_back(__x);
+ _M_profile_resize(this, __old_size, this->capacity());
+ }
+
+#endif
+
+ iterator
+ insert(iterator __position, const _Tp& __x)
+ {
+ __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ size_type __old_size = this->capacity();
+ typename _Base::iterator __res = _Base::insert(__position,__x);
+ _M_profile_resize(this, __old_size, this->capacity());
+ return __res;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ iterator
+ insert(iterator __position, _Tp&& __x)
+ {
+ __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ size_type __old_size = this->capacity();
+ typename _Base::iterator __res = _Base::insert(__position,__x);
+ _M_profile_resize(this, __old_size, this->capacity());
+ return __res;
+ }
+
+ void
+ insert(iterator __position, initializer_list<value_type> __l)
+ { this->insert(__position, __l.begin(), __l.end()); }
+#endif
+
+ void
+
+ swap(vector& __x)
+ {
+ _Base::swap(__x);
+ }
+
+
+ void
+ insert(iterator __position, size_type __n, const _Tp& __x)
+ {
+ __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ size_type __old_size = this->capacity();
+ _Base::insert(__position, __n, __x);
+ _M_profile_resize(this, __old_size, this->capacity());
+ }
+
+ template<class _InputIterator>
+ void
+ insert(iterator __position,
+ _InputIterator __first, _InputIterator __last)
+ {
+ __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ size_type __old_size = this->capacity();
+ _Base::insert(__position, __first, __last);
+ _M_profile_resize(this, __old_size, this->capacity());
+ }
+
+ void
+ clear()
+ {
+ __profcxx_vector_destruct(this, this->capacity(), this->size());
+ __profcxx_vector_destruct2(this);
+ _Base::clear();
+ }
+
+ // iterators:
+ iterator
+ begin()
+ {
+ return _Base::begin();
+ }
+
+ const_iterator
+ begin() const
+ {
+ return _Base::begin();
+ }
+
+ private:
+ void _M_profile_resize(void* obj, size_type __old_size,
+ size_type __new_size)
+ {
+ if (__old_size < __new_size) {
+ __profcxx_vector_resize(this, this->size(), __new_size);
+ __profcxx_vector_resize2(this, this->size(), __new_size);
+ }
+ }
+ };
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator==(const vector<_Tp, _Alloc>& __lhs,
+ const vector<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() == __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator!=(const vector<_Tp, _Alloc>& __lhs,
+ const vector<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() != __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<(const vector<_Tp, _Alloc>& __lhs,
+ const vector<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() < __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator<=(const vector<_Tp, _Alloc>& __lhs,
+ const vector<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() <= __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>=(const vector<_Tp, _Alloc>& __lhs,
+ const vector<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() >= __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator>(const vector<_Tp, _Alloc>& __lhs,
+ const vector<_Tp, _Alloc>& __rhs)
+ { return __lhs._M_base() > __rhs._M_base(); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+} // namespace __profile
+ using _GLIBCXX_STD_D::_S_word_bit;
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index 5ca442989aa..131fe56de2d 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -1393,4 +1393,8 @@ _GLIBCXX_END_NESTED_NAMESPACE
# include <debug/bitset>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/bitset>
+#endif
+
#endif /* _GLIBCXX_BITSET */
diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque
index 8f64b005ccf..f8a55f72165 100644
--- a/libstdc++-v3/include/std/deque
+++ b/libstdc++-v3/include/std/deque
@@ -72,4 +72,8 @@
# include <debug/deque>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/deque>
+#endif
+
#endif /* _GLIBCXX_DEQUE */
diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list
index d199802d736..fcf164b4bd5 100644
--- a/libstdc++-v3/include/std/list
+++ b/libstdc++-v3/include/std/list
@@ -70,5 +70,9 @@
# include <debug/list>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/list>
+#endif
+
#endif /* _GLIBCXX_LIST */
diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map
index 159bfb3d040..25f86df6976 100644
--- a/libstdc++-v3/include/std/map
+++ b/libstdc++-v3/include/std/map
@@ -65,4 +65,8 @@
# include <debug/map>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/map>
+#endif
+
#endif /* _GLIBCXX_MAP */
diff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set
index 21e3f5a8a1e..0b7805cabec 100644
--- a/libstdc++-v3/include/std/set
+++ b/libstdc++-v3/include/std/set
@@ -65,4 +65,8 @@
# include <debug/set>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/set>
+#endif
+
#endif /* _GLIBCXX_SET */
diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map
index 56906d28b5f..f8cd5459787 100644
--- a/libstdc++-v3/include/std/unordered_map
+++ b/libstdc++-v3/include/std/unordered_map
@@ -53,7 +53,7 @@
# include <tr1_impl/unordered_map>
#else
# define _GLIBCXX_INCLUDE_AS_CXX0X
-#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL)
+#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PROFILE)
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace _GLIBCXX_STD_D {
# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 _GLIBCXX_STD_D
@@ -73,6 +73,10 @@
# include <debug/unordered_map>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/unordered_map>
+#endif
+
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // _GLIBCXX_UNORDERED_MAP
diff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set
index 880f3bef4ec..b5b4f108980 100644
--- a/libstdc++-v3/include/std/unordered_set
+++ b/libstdc++-v3/include/std/unordered_set
@@ -53,7 +53,7 @@
# include <tr1_impl/unordered_set>
#else
# define _GLIBCXX_INCLUDE_AS_CXX0X
-#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL)
+#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PROFILE)
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace _GLIBCXX_STD_D {
# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 _GLIBCXX_STD_D
@@ -73,6 +73,9 @@
# include <debug/unordered_set>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/unordered_set>
+#endif
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // _GLIBCXX_UNORDERED_SET
diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector
index 114665b6c96..41ecdde6c7b 100644
--- a/libstdc++-v3/include/std/vector
+++ b/libstdc++-v3/include/std/vector
@@ -34,7 +34,7 @@
* 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.
+ ded "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
@@ -73,5 +73,9 @@
# include <debug/vector>
#endif
+#ifdef _GLIBCXX_PROFILE
+# include <profile/vector>
+#endif
+
#endif /* _GLIBCXX_VECTOR */
diff --git a/libstdc++-v3/include/tr1_impl/hashtable b/libstdc++-v3/include/tr1_impl/hashtable
index bce550ff1f1..c4776982334 100644
--- a/libstdc++-v3/include/tr1_impl/hashtable
+++ b/libstdc++-v3/include/tr1_impl/hashtable
@@ -409,6 +409,9 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
_M_erase_node(_Node*, _Node**);
public:
+ // Expose insert_return_type for profiling mode.
+ typedef _Insert_Return_Type insert_return_type;
+
// Insert and erase
_Insert_Return_Type
insert(const value_type& __v)