]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorBenjamin Kosnik <bkoz@gcc.gnu.org>
Wed, 11 Jun 2003 15:52:11 +0000 (15:52 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Wed, 11 Jun 2003 15:52:11 +0000 (15:52 +0000)
2003-06-11  Benjamin Kosnik  <bkoz@redhat.com>

* include/bits/stl_alloc.h (__debug_alloc): Move out.
(__malloc_alloc): Same.
(__pool_alloc): Same.
(__new_alloc): Same.
Rename to..
* include/bits/allocator.h: ...this.
* include/bits/stl_deque.h: Modify comment.
* include/bits/stl_tree.h: Modify include.
* include/std/std_memory.h: Same.
* include/ext/rope: Same.
* include/ext/slist: Same.
* include/std/std_vector.h: Same.
* include/std/std_stack.h: Same.
* include/std/std_queue.h: Same.
* include/std/std_list.h: Same.
* include/std/std_deque.h: Same.
* include/backward/alloc.h: Same.
* include/ext/debug_allocator.h: New.
* include/ext/malloc_allocator.h: New.
* include/ext/pool_allocator.h: New.
* include/ext/new_allocator.h: New.
* include/bits/pthread_allocimpl.h: Remove.
* include/bits/stl_pthread_alloc.h: Remove.
* include/Makefile.am (ext_headers): Add.
* include/Makefile.in: Regenerate.
* src/stl-inst.cc: Use __gnu_cxx namespace.
* src/stl-inst.cc: Move to...
* src/allocator-inst.cc: Here.
* src/Makefile.am (sources): Update.
* src/Makefile.in: Regenerate.
* config/linker-map.gnu: Remove __pool_alloc bits.
* testsuite/ext/headers.cc: Add.
* testsuite/ext/allocators.cc: Fixup.

2003-06-11  Stefan Olsson  <stefan@snon.net>
            Ola R�nnerup  <fnolis@home.se>

* include/Makefile.am (ext_headers): Add.
* include/Makefile.in: Regenerate.
* include/ext/mt_allocator.h: New file.

From-SVN: r67777

30 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/linker-map.gnu
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/backward/alloc.h
libstdc++-v3/include/bits/allocator.h [new file with mode: 0644]
libstdc++-v3/include/bits/allocator_traits.h [new file with mode: 0644]
libstdc++-v3/include/bits/pthread_allocimpl.h [deleted file]
libstdc++-v3/include/bits/stl_alloc.h [deleted file]
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/include/bits/stl_threads.h
libstdc++-v3/include/bits/stl_tree.h
libstdc++-v3/include/ext/debug_allocator.h [new file with mode: 0644]
libstdc++-v3/include/ext/malloc_allocator.h [new file with mode: 0644]
libstdc++-v3/include/ext/mt_allocator.h [new file with mode: 0644]
libstdc++-v3/include/ext/new_allocator.h [moved from libstdc++-v3/include/bits/stl_pthread_alloc.h with 55% similarity]
libstdc++-v3/include/ext/pool_allocator.h [new file with mode: 0644]
libstdc++-v3/include/ext/rope
libstdc++-v3/include/ext/slist
libstdc++-v3/include/std/std_deque.h
libstdc++-v3/include/std/std_list.h
libstdc++-v3/include/std/std_memory.h
libstdc++-v3/include/std/std_queue.h
libstdc++-v3/include/std/std_stack.h
libstdc++-v3/include/std/std_vector.h
libstdc++-v3/src/Makefile.am
libstdc++-v3/src/Makefile.in
libstdc++-v3/src/allocator-inst.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/allocators.cc
libstdc++-v3/testsuite/ext/headers.cc

index 0c01a43308e49a7ae837a6e3cf8f64d35a6f8ab9..ad3c2d65ab93910297930849675ba7afdb38a27f 100644 (file)
@@ -1,3 +1,46 @@
+2003-06-11  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * include/bits/stl_alloc.h (__debug_alloc): Move out.
+       (__malloc_alloc): Same.
+       (__pool_alloc): Same.
+       (__new_alloc): Same.
+       Rename to..
+       * include/bits/allocator.h: ...this.
+       * include/bits/stl_deque.h: Modify comment.
+       * include/bits/stl_tree.h: Modify include.
+       * include/std/std_memory.h: Same.
+       * include/ext/rope: Same.
+       * include/ext/slist: Same.      
+       * include/std/std_vector.h: Same.
+       * include/std/std_stack.h: Same.
+       * include/std/std_queue.h: Same.
+       * include/std/std_list.h: Same.
+       * include/std/std_deque.h: Same.
+       * include/backward/alloc.h: Same.
+       * include/ext/debug_allocator.h: New.
+       * include/ext/malloc_allocator.h: New.  
+       * include/ext/pool_allocator.h: New.            
+       * include/ext/new_allocator.h: New.
+       * include/bits/pthread_allocimpl.h: Remove.
+       * include/bits/stl_pthread_alloc.h: Remove.     
+       * include/Makefile.am (ext_headers): Add.
+       * include/Makefile.in: Regenerate.
+       * src/stl-inst.cc: Use __gnu_cxx namespace.
+       * src/stl-inst.cc: Move to...
+       * src/allocator-inst.cc: Here.
+       * src/Makefile.am (sources): Update.
+       * src/Makefile.in: Regenerate.
+       * config/linker-map.gnu: Remove __pool_alloc bits.
+       * testsuite/ext/headers.cc: Add.
+       * testsuite/ext/allocators.cc: Fixup.
+       
+2003-06-11  Stefan Olsson  <stefan@snon.net>
+            Ola Rönnerup  <fnolis@home.se>
+       
+       * include/Makefile.am (ext_headers): Add.
+       * include/Makefile.in: Regenerate.
+       * include/ext/mt_allocator.h: New file.
+
 2003-06-10  Paolo Carlini  <pcarlini@unitus.it>
 
        * include/bits/fstream.tcc (close): Clean up a bit.
index 6f87a0b9967b970cccee860665cd2c1d19208569..6723a057e079e596b6097b165f05c7b4e5c9e724 100644 (file)
@@ -78,15 +78,6 @@ GLIBCPP_3.4 {
     # bool has_facet 
     _ZSt9has_facet*;
 
-    # std::__pool_alloc
-    _ZNSt12__pool_allocILb1ELi0EE10deallocateEPv[jm]*;
-    _ZNSt12__pool_allocILb1ELi0EE8allocateE[jm]*;
-    _ZNSt12__pool_allocILb1ELi0EE5_Lock*;
-    _ZNSt12__pool_allocILb1ELi0EE12_S_force_newE;
-    _ZNSt12__pool_allocILb1ELi0EE12_S_free_listE;
-    _ZNSt12__pool_allocILb1ELi0EE7_S_lockE;
-    _ZNSt12__pool_allocILb1ELi0EE9_S_refillE[jm];
-
     # operator new(size_t)
     _Znw[jm];
     # operator new(size_t, std::nothrow_t const&)
index 5c200dcd8a7d2ac4076bb91143748ad87b232da4..760e85ba4e88418e20acda4e8c6dd092bdfedc48 100644 (file)
@@ -103,6 +103,8 @@ std_headers_rename = \
 bits_srcdir = ${glibcpp_srcdir}/include/bits
 bits_builddir = ./bits
 bits_headers = \
+       ${bits_srcdir}/allocator.h \
+       ${bits_srcdir}/allocator_traits.h \
        ${bits_srcdir}/basic_ios.h \
        ${bits_srcdir}/basic_ios.tcc \
        ${bits_srcdir}/basic_string.h \
@@ -129,14 +131,12 @@ bits_headers = \
        ${bits_srcdir}/localefwd.h \
        ${bits_srcdir}/mask_array.h \
        ${bits_srcdir}/ostream.tcc \
-       ${bits_srcdir}/pthread_allocimpl.h \
        ${bits_srcdir}/stream_iterator.h \
        ${bits_srcdir}/streambuf_iterator.h \
        ${bits_srcdir}/slice_array.h \
        ${bits_srcdir}/sstream.tcc \
        ${bits_srcdir}/stl_algo.h \
        ${bits_srcdir}/stl_algobase.h \
-       ${bits_srcdir}/stl_alloc.h \
        ${bits_srcdir}/stl_bvector.h \
        ${bits_srcdir}/stl_construct.h \
        ${bits_srcdir}/stl_deque.h \
@@ -151,7 +151,6 @@ bits_headers = \
        ${bits_srcdir}/stl_multiset.h \
        ${bits_srcdir}/stl_numeric.h \
        ${bits_srcdir}/stl_pair.h \
-       ${bits_srcdir}/stl_pthread_alloc.h \
        ${bits_srcdir}/stl_queue.h \
        ${bits_srcdir}/stl_raw_storage_iter.h \
        ${bits_srcdir}/stl_relops.h \
@@ -215,6 +214,7 @@ ext_srcdir = ${glibcpp_srcdir}/include/ext
 ext_builddir = ./ext
 ext_headers = \
        ${ext_srcdir}/algorithm \
+       ${ext_srcdir}/debug_allocator.h \
        ${ext_srcdir}/enc_filebuf.h \
        ${ext_srcdir}/stdio_filebuf.h \
        ${ext_srcdir}/stdio_sync_filebuf.h \
@@ -222,8 +222,12 @@ ext_headers = \
        ${ext_srcdir}/hash_map \
        ${ext_srcdir}/hash_set \
        ${ext_srcdir}/iterator \
+       ${ext_srcdir}/malloc_allocator.h \
        ${ext_srcdir}/memory \
+       ${ext_srcdir}/mt_allocator.h \
+       ${ext_srcdir}/new_allocator.h \
        ${ext_srcdir}/numeric \
+       ${ext_srcdir}/pool_allocator.h \
        ${ext_srcdir}/rb_tree \
        ${ext_srcdir}/rope \
        ${ext_srcdir}/ropeimpl.h \
index 7dfd79311e11012c5ba9decffd51430742027de4..33d5a81846ce9418c4fe1551f2bc61ce20dbf126 100644 (file)
@@ -222,6 +222,8 @@ std_headers_rename = \
 bits_srcdir = ${glibcpp_srcdir}/include/bits
 bits_builddir = ./bits
 bits_headers = \
+       ${bits_srcdir}/allocator.h \
+       ${bits_srcdir}/allocator_traits.h \
        ${bits_srcdir}/basic_ios.h \
        ${bits_srcdir}/basic_ios.tcc \
        ${bits_srcdir}/basic_string.h \
@@ -248,14 +250,12 @@ bits_headers = \
        ${bits_srcdir}/localefwd.h \
        ${bits_srcdir}/mask_array.h \
        ${bits_srcdir}/ostream.tcc \
-       ${bits_srcdir}/pthread_allocimpl.h \
        ${bits_srcdir}/stream_iterator.h \
        ${bits_srcdir}/streambuf_iterator.h \
        ${bits_srcdir}/slice_array.h \
        ${bits_srcdir}/sstream.tcc \
        ${bits_srcdir}/stl_algo.h \
        ${bits_srcdir}/stl_algobase.h \
-       ${bits_srcdir}/stl_alloc.h \
        ${bits_srcdir}/stl_bvector.h \
        ${bits_srcdir}/stl_construct.h \
        ${bits_srcdir}/stl_deque.h \
@@ -270,7 +270,6 @@ bits_headers = \
        ${bits_srcdir}/stl_multiset.h \
        ${bits_srcdir}/stl_numeric.h \
        ${bits_srcdir}/stl_pair.h \
-       ${bits_srcdir}/stl_pthread_alloc.h \
        ${bits_srcdir}/stl_queue.h \
        ${bits_srcdir}/stl_raw_storage_iter.h \
        ${bits_srcdir}/stl_relops.h \
@@ -336,6 +335,7 @@ ext_srcdir = ${glibcpp_srcdir}/include/ext
 ext_builddir = ./ext
 ext_headers = \
        ${ext_srcdir}/algorithm \
+       ${ext_srcdir}/debug_allocator.h \
        ${ext_srcdir}/enc_filebuf.h \
        ${ext_srcdir}/stdio_filebuf.h \
        ${ext_srcdir}/stdio_sync_filebuf.h \
@@ -343,8 +343,12 @@ ext_headers = \
        ${ext_srcdir}/hash_map \
        ${ext_srcdir}/hash_set \
        ${ext_srcdir}/iterator \
+       ${ext_srcdir}/malloc_allocator.h \
        ${ext_srcdir}/memory \
+       ${ext_srcdir}/mt_allocator.h \
+       ${ext_srcdir}/new_allocator.h \
        ${ext_srcdir}/numeric \
+       ${ext_srcdir}/pool_allocator.h \
        ${ext_srcdir}/rb_tree \
        ${ext_srcdir}/rope \
        ${ext_srcdir}/ropeimpl.h \
index 6bcc421b7af2e0f39b397057703947b8c7309dc0..b748ef26c01d4e1d0ad538345a326029c354de2b 100644 (file)
 
 #include "backward_warning.h"
 #include <bits/c++config.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
+#include <ext/debug_allocator.h>
+#include <ext/malloc_allocator.h>
 
-using std::__malloc_alloc; 
-using std::__simple_alloc; 
-using std::__debug_alloc; 
+using __gnu_cxx::__malloc_alloc; 
+using __gnu_cxx::__debug_alloc; 
+using __gnu_cxx::__pool_alloc; 
 using std::__alloc; 
-using std::__single_client_alloc; 
-using std::__pool_alloc; 
+using std::__simple_alloc; 
 using std::allocator;
 
-
 #endif 
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
new file mode 100644 (file)
index 0000000..b6dec02
--- /dev/null
@@ -0,0 +1,215 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/** @file allocator.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+/**
+ *  @defgroup Allocators Memory Allocators
+ *  @if maint
+ *  allocator.h implements some node allocators.  These are NOT the same as
+ *  allocators in the C++ standard, nor in the original H-P STL.  They do not
+ *  encapsulate different pointer types; we assume that there is only one
+ *  pointer type.  The C++ standard allocators are intended to allocate
+ *  individual objects, not pools or arenas.
+ *
+ *  In this file allocators are of two different styles:  "standard" and
+ *  "SGI" (quotes included).  "Standard" allocators conform to 20.4.  "SGI"
+ *  allocators differ in AT LEAST the following ways (add to this list as you
+ *  discover them):
+ *
+ *   - "Standard" allocate() takes two parameters (n_count,hint=0) but "SGI"
+ *     allocate() takes one paramter (n_size).
+ *   - Likewise, "standard" deallocate()'s argument is a count, but in "SGI"
+ *     is a byte size.
+ *   - max_size(), construct(), and destroy() are missing in "SGI" allocators.
+ *   - reallocate(p,oldsz,newsz) is added in "SGI", and behaves as
+ *     if p=realloc(p,newsz).
+ *
+ *  "SGI" allocators may be wrapped in __allocator to convert the interface
+ *  into a "standard" one.
+ *  @endif
+ *
+ *  The canonical description of these classes is in docs/html/ext/howto.html
+ *  or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3
+*/
+
+#ifndef _ALLOCATOR_H
+#define _ALLOCATOR_H 1
+
+#include <bits/functexcept.h>   // For __throw_bad_alloc
+#include <bits/allocator_traits.h>
+
+// Pick a default underlying allocator.
+#include <ext/pool_allocator.h>
+
+namespace std
+{
+  typedef __gnu_cxx::__pool_alloc<true, 0>    __alloc;
+
+  /// The version for the default allocator.
+  template<typename _Tp, typename _Tp1>
+    struct _Alloc_traits<_Tp, allocator<_Tp1> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
+      typedef allocator<_Tp> allocator_type;
+    };
+  //@}
+}
+
+namespace std
+{
+  /**
+   *  @brief  The "standard" allocator, as per [20.4].
+   *
+   *  The private _Alloc is "SGI" style.  (See comments at the top
+   *  of allocator.h.)
+   *
+   *  The underlying allocator behaves as follows.
+   *    - __pool_alloc is used via two typedefs
+   *    - "__alloc" typedef is threadsafe via the locks
+   *    - __new_alloc is used for memory requests
+   *
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<typename _Tp>
+    class allocator
+    {
+      // The underlying allocator.
+      typedef __alloc _Alloc;     
+     
+    public:
+      typedef size_t     size_type;
+      typedef ptrdiff_t  difference_type;
+      typedef _Tp*       pointer;
+      typedef const _Tp* const_pointer;
+      typedef _Tp&       reference;
+      typedef const _Tp& const_reference;
+      typedef _Tp        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef allocator<_Tp1> other; };
+
+      allocator() throw() { }
+
+      allocator(const allocator&) throw() { }
+
+      template<typename _Tp1>
+        allocator(const allocator<_Tp1>&) throw() { }
+
+      ~allocator() throw() { }
+
+      pointer
+      address(reference __x) const { return &__x; }
+
+      const_pointer
+      address(const_reference __x) const { return &__x; }
+
+      // NB: __n is permitted to be 0.  The C++ standard says nothing
+      // about what the return value is when __n == 0.
+      _Tp*
+      allocate(size_type __n, const void* = 0)
+      {
+       _Tp* __ret = 0;
+       if (__n)
+         {
+           if (__n <= this->max_size())
+             __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+           else
+             __throw_bad_alloc();
+         }
+       return __ret;
+      }
+
+      // __p is not permitted to be a null pointer.
+      void
+      deallocate(pointer __p, size_type __n)
+      { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
+
+      size_type
+      max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
+
+      void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+
+      void destroy(pointer __p) { __p->~_Tp(); }
+    };
+
+  template<>
+    class allocator<void>
+    {
+    public:
+      typedef size_t      size_type;
+      typedef ptrdiff_t   difference_type;
+      typedef void*       pointer;
+      typedef const void* const_pointer;
+      typedef void        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef allocator<_Tp1> other; };
+    };
+
+
+  template<typename _T1, typename _T2>
+    inline bool
+    operator==(const allocator<_T1>&, const allocator<_T2>&)
+    { return true; }
+
+  template<typename _T1, typename _T2>
+    inline bool
+    operator!=(const allocator<_T1>&, const allocator<_T2>&)
+    { return false; }
+
+  // Inhibit implicit instantiations for required instantiations,
+  // which are defined via explicit instantiations elsewhere.
+  // NB: This syntax is a GNU extension.
+#if _GLIBCPP_EXTERN_TEMPLATE
+  extern template class allocator<char>;
+  extern template class allocator<wchar_t>;
+#endif
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/bits/allocator_traits.h b/libstdc++-v3/include/bits/allocator_traits.h
new file mode 100644 (file)
index 0000000..be9a352
--- /dev/null
@@ -0,0 +1,236 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * 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.
+ */
+
+#ifndef _ALLOCATOR_TRAITS_H
+#define _ALLOCATOR_TRAITS_H 1
+
+#include <cstddef>
+
+namespace std
+{
+  /**
+   *  @if maint
+   *  This is used primarily (only?) in _Alloc_traits and other places to
+   *  help provide the _Alloc_type typedef.  All it does is forward the
+   *  requests after some minimal checking.
+   *
+   *  This is neither "standard"-conforming nor "SGI".  The _Alloc parameter
+   *  must be "SGI" style.
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<typename _Tp, typename _Alloc>
+    class __simple_alloc
+    {
+    public:
+      static _Tp*
+      allocate(size_t __n)
+      {
+       _Tp* __ret = 0;
+       if (__n)
+         __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+       return __ret;
+      }
+  
+      static _Tp*
+      allocate()
+      { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
+  
+      static void
+      deallocate(_Tp* __p, size_t __n)
+      { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
+  
+      static void
+      deallocate(_Tp* __p)
+      { _Alloc::deallocate(__p, sizeof (_Tp)); }
+    };
+
+
+  /**
+   *  @if maint
+   *  Allocator adaptor to turn an "SGI" style allocator (e.g.,
+   *  __alloc, __malloc_alloc) into a "standard" conforming
+   *  allocator.  Note that this adaptor does *not* assume that all
+   *  objects of the underlying alloc class are identical, nor does it
+   *  assume that all of the underlying alloc's member functions are
+   *  static member functions.  Note, also, that __allocator<_Tp,
+   *  __alloc> is essentially the same thing as allocator<_Tp>.
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<typename _Tp, typename _Alloc>
+    struct __allocator
+    {
+      _Alloc __underlying_alloc;
+      
+      typedef size_t    size_type;
+      typedef ptrdiff_t difference_type;
+      typedef _Tp*       pointer;
+      typedef const _Tp* const_pointer;
+      typedef _Tp&       reference;
+      typedef const _Tp& const_reference;
+      typedef _Tp        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef __allocator<_Tp1, _Alloc> other; };
+
+      __allocator() throw() { }
+
+      __allocator(const __allocator& __a) throw()
+      : __underlying_alloc(__a.__underlying_alloc) { }
+
+      template<typename _Tp1>
+        __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
+        : __underlying_alloc(__a.__underlying_alloc) { }
+
+      ~__allocator() throw() { }
+
+      pointer
+      address(reference __x) const { return &__x; }
+
+      const_pointer
+      address(const_reference __x) const { return &__x; }
+
+      // NB: __n is permitted to be 0.  The C++ standard says nothing
+      // about what the return value is when __n == 0.
+      _Tp*
+      allocate(size_type __n, const void* = 0)
+      {
+       _Tp* __ret = 0;
+       if (__n)
+         __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+       return __ret;
+      }
+
+      // __p is not permitted to be a null pointer.
+      void
+      deallocate(pointer __p, size_type __n)
+      { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
+      
+      size_type
+      max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
+      
+      void
+      construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+      
+      void
+      destroy(pointer __p) { __p->~_Tp(); }
+    };
+
+  template<typename _Alloc>
+    struct __allocator<void, _Alloc>
+    {
+      typedef size_t      size_type;
+      typedef ptrdiff_t   difference_type;
+      typedef void*       pointer;
+      typedef const void* const_pointer;
+      typedef void        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef __allocator<_Tp1, _Alloc> other; };
+    };
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator==(const __allocator<_Tp,_Alloc>& __a1, 
+              const __allocator<_Tp,_Alloc>& __a2)
+    { return __a1.__underlying_alloc == __a2.__underlying_alloc; }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator!=(const __allocator<_Tp, _Alloc>& __a1,
+               const __allocator<_Tp, _Alloc>& __a2)
+    { return __a1.__underlying_alloc != __a2.__underlying_alloc; }
+
+
+  /**
+   *  @if maint
+   *  Another allocator adaptor:  _Alloc_traits.  This serves two purposes.
+   *  First, make it possible to write containers that can use either "SGI"
+   *  style allocators or "standard" allocators.  Second, provide a mechanism
+   *  so that containers can query whether or not the allocator has distinct
+   *  instances.  If not, the container can avoid wasting a word of memory to
+   *  store an empty object.  For examples of use, see stl_vector.h, etc, or
+   *  any of the other classes derived from this one.
+   *
+   *  This adaptor uses partial specialization.  The general case of
+   *  _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
+   *  standard-conforming allocator, possibly with non-equal instances and
+   *  non-static members.  (It still behaves correctly even if _Alloc has
+   *  static member and if all instances are equal.  Refinements affect
+   *  performance, not correctness.)
+   *
+   *  There are always two members:  allocator_type, which is a standard-
+   *  conforming allocator type for allocating objects of type _Tp, and
+   *  _S_instanceless, a static const member of type bool.  If
+   *  _S_instanceless is true, this means that there is no difference
+   *  between any two instances of type allocator_type.  Furthermore, if
+   *  _S_instanceless is true, then _Alloc_traits has one additional
+   *  member:  _Alloc_type.  This type encapsulates allocation and
+   *  deallocation of objects of type _Tp through a static interface; it
+   *  has two member functions, whose signatures are
+   *
+   *  -  static _Tp* allocate(size_t)
+   *  -  static void deallocate(_Tp*, size_t)
+   *
+   *  The size_t parameters are "standard" style (see top of
+   *  allocator.h) in that they take counts, not sizes.
+   *
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  //@{
+  // The fully general version.
+  template<typename _Tp, typename _Allocator>
+    struct _Alloc_traits
+    {
+      static const bool _S_instanceless = false;
+      typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
+    };
+
+  template<typename _Tp, typename _Allocator>
+    const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/bits/pthread_allocimpl.h b/libstdc++-v3/include/bits/pthread_allocimpl.h
deleted file mode 100644 (file)
index 050b206..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-// POSIX thread-related memory allocation -*- C++ -*-
-
-// Copyright (C) 2001 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- */
-
-/** @file pthread_allocimpl.h
- *  This is an internal header file, included by other library headers.
- *  You should not attempt to use it directly.
- */
-
-#ifndef _CPP_BITS_PTHREAD_ALLOCIMPL_H
-#define _CPP_BITS_PTHREAD_ALLOCIMPL_H 1
-
-// Pthread-specific node allocator.
-// This is similar to the default allocator, except that free-list
-// information is kept separately for each thread, avoiding locking.
-// This should be reasonably fast even in the presence of threads.
-// The down side is that storage may not be well-utilized.
-// It is not an error to allocate memory in thread A and deallocate
-// it in thread B.  But this effectively transfers ownership of the memory,
-// so that it can only be reallocated by thread B.  Thus this can effectively
-// result in a storage leak if it's done on a regular basis.
-// It can also result in frequent sharing of
-// cache lines among processors, with potentially serious performance
-// consequences.
-
-#include <bits/c++config.h>
-#include <cerrno>
-#include <bits/stl_alloc.h>
-#ifndef __RESTRICT
-#  define __RESTRICT
-#endif
-
-#include <new>
-
-namespace std
-{
-
-#define __STL_DATA_ALIGNMENT 8
-
-union _Pthread_alloc_obj {
-    union _Pthread_alloc_obj * __free_list_link;
-    char __client_data[__STL_DATA_ALIGNMENT];    /* The client sees this.    */
-};
-
-// Pthread allocators don't appear to the client to have meaningful
-// instances.  We do in fact need to associate some state with each
-// thread.  That state is represented by
-// _Pthread_alloc_per_thread_state<_Max_size>.
-
-template<size_t _Max_size>
-struct _Pthread_alloc_per_thread_state {
-  typedef _Pthread_alloc_obj __obj;
-  enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT };
-  _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; 
-  _Pthread_alloc_per_thread_state<_Max_size> * __next; 
-       // Free list link for list of available per thread structures.
-       // When one of these becomes available for reuse due to thread
-       // termination, any objects in its free list remain associated
-       // with it.  The whole structure may then be used by a newly
-       // created thread.
-  _Pthread_alloc_per_thread_state() : __next(0)
-  {
-    memset((void *)__free_list, 0, (size_t) _S_NFREELISTS * sizeof(__obj *));
-  }
-  // Returns an object of size __n, and possibly adds to size n free list.
-  void *_M_refill(size_t __n);
-};
-
-// Pthread-specific allocator.
-// The argument specifies the largest object size allocated from per-thread
-// free lists.  Larger objects are allocated using malloc_alloc.
-// Max_size must be a power of 2.
-template <size_t _Max_size = 128>
-class _Pthread_alloc_template {
-
-public: // but only for internal use:
-
-  typedef _Pthread_alloc_obj __obj;
-
-  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
-  // if it is inconvenient to allocate the requested number.
-  static char *_S_chunk_alloc(size_t __size, int &__nobjs);
-
-  enum {_S_ALIGN = __STL_DATA_ALIGNMENT};
-
-  static size_t _S_round_up(size_t __bytes) {
-    return (((__bytes) + (int) _S_ALIGN-1) & ~((int) _S_ALIGN - 1));
-  }
-  static size_t _S_freelist_index(size_t __bytes) {
-    return (((__bytes) + (int) _S_ALIGN-1)/(int)_S_ALIGN - 1);
-  }
-
-private:
-  // Chunk allocation state. And other shared state.
-  // Protected by _S_chunk_allocator_lock.
-  static pthread_mutex_t _S_chunk_allocator_lock;
-  static char *_S_start_free;
-  static char *_S_end_free;
-  static size_t _S_heap_size;
-  static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states;
-  static pthread_key_t _S_key;
-  static bool _S_key_initialized;
-        // Pthread key under which per thread state is stored. 
-        // Allocator instances that are currently unclaimed by any thread.
-  static void _S_destructor(void *instance);
-        // Function to be called on thread exit to reclaim per thread
-        // state.
-  static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state();
-        // Return a recycled or new per thread state.
-  static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state();
-        // ensure that the current thread has an associated
-        // per thread state.
-  class _M_lock;
-  friend class _M_lock;
-  class _M_lock {
-      public:
-        _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); }
-        ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); }
-  };
-
-public:
-
-  /* n must be > 0      */
-  static void * allocate(size_t __n)
-  {
-    __obj * volatile * __my_free_list;
-    __obj * __RESTRICT __result;
-    _Pthread_alloc_per_thread_state<_Max_size>* __a;
-
-    if (__n > _Max_size) {
-        return(malloc_alloc::allocate(__n));
-    }
-    if (!_S_key_initialized ||
-        !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*)
-                                 pthread_getspecific(_S_key))) {
-        __a = _S_get_per_thread_state();
-    }
-    __my_free_list = __a -> __free_list + _S_freelist_index(__n);
-    __result = *__my_free_list;
-    if (__result == 0) {
-        void *__r = __a -> _M_refill(_S_round_up(__n));
-        return __r;
-    }
-    *__my_free_list = __result -> __free_list_link;
-    return (__result);
-  };
-
-  /* p may not be 0 */
-  static void deallocate(void *__p, size_t __n)
-  {
-    __obj *__q = (__obj *)__p;
-    __obj * volatile * __my_free_list;
-    _Pthread_alloc_per_thread_state<_Max_size>* __a;
-
-    if (__n > _Max_size) {
-        malloc_alloc::deallocate(__p, __n);
-        return;
-    }
-    if (!_S_key_initialized ||
-        !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *)
-                pthread_getspecific(_S_key))) {
-        __a = _S_get_per_thread_state();
-    }
-    __my_free_list = __a->__free_list + _S_freelist_index(__n);
-    __q -> __free_list_link = *__my_free_list;
-    *__my_free_list = __q;
-  }
-
-  static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz);
-
-} ;
-
-typedef _Pthread_alloc_template<> pthread_alloc;
-
-
-template <size_t _Max_size>
-void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance)
-{
-    _M_lock __lock_instance;   // Need to acquire lock here.
-    _Pthread_alloc_per_thread_state<_Max_size>* __s =
-        (_Pthread_alloc_per_thread_state<_Max_size> *)__instance;
-    __s -> __next = _S_free_per_thread_states;
-    _S_free_per_thread_states = __s;
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state()
-{    
-    /* lock already held here. */
-    if (0 != _S_free_per_thread_states) {
-        _Pthread_alloc_per_thread_state<_Max_size> *__result =
-                                       _S_free_per_thread_states;
-        _S_free_per_thread_states = _S_free_per_thread_states -> __next;
-        return __result;
-    } else {
-        return new _Pthread_alloc_per_thread_state<_Max_size>;
-    }
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state()
-{
-    /*REFERENCED*/
-    _M_lock __lock_instance;   // Need to acquire lock here.
-    int __ret_code;
-    _Pthread_alloc_per_thread_state<_Max_size> * __result;
-    if (!_S_key_initialized) {
-        if (pthread_key_create(&_S_key, _S_destructor)) {
-           std::__throw_bad_alloc();  // defined in funcexcept.h
-        }
-        _S_key_initialized = true;
-    }
-    __result = _S_new_per_thread_state();
-    __ret_code = pthread_setspecific(_S_key, __result);
-    if (__ret_code) {
-      if (__ret_code == ENOMEM) {
-       std::__throw_bad_alloc();
-      } else {
-       // EINVAL
-       abort();
-      }
-    }
-    return __result;
-}
-
-/* We allocate memory in large chunks in order to avoid fragmenting     */
-/* the malloc heap too much.                                            */
-/* We assume that size is properly aligned.                             */
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_chunk_alloc(size_t __size, int &__nobjs)
-{
-  {
-    char * __result;
-    size_t __total_bytes;
-    size_t __bytes_left;
-    /*REFERENCED*/
-    _M_lock __lock_instance;         // Acquire lock for this routine
-
-    __total_bytes = __size * __nobjs;
-    __bytes_left = _S_end_free - _S_start_free;
-    if (__bytes_left >= __total_bytes) {
-        __result = _S_start_free;
-        _S_start_free += __total_bytes;
-        return(__result);
-    } else if (__bytes_left >= __size) {
-        __nobjs = __bytes_left/__size;
-        __total_bytes = __size * __nobjs;
-        __result = _S_start_free;
-        _S_start_free += __total_bytes;
-        return(__result);
-    } else {
-        size_t __bytes_to_get =
-               2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
-        // Try to make use of the left-over piece.
-        if (__bytes_left > 0) {
-            _Pthread_alloc_per_thread_state<_Max_size>* __a = 
-                (_Pthread_alloc_per_thread_state<_Max_size>*)
-                       pthread_getspecific(_S_key);
-            __obj * volatile * __my_free_list =
-                        __a->__free_list + _S_freelist_index(__bytes_left);
-
-            ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list;
-            *__my_free_list = (__obj *)_S_start_free;
-        }
-#       ifdef _SGI_SOURCE
-          // Try to get memory that's aligned on something like a
-          // cache line boundary, so as to avoid parceling out
-          // parts of the same line to different threads and thus
-          // possibly different processors.
-          {
-            const int __cache_line_size = 128;  // probable upper bound
-            __bytes_to_get &= ~(__cache_line_size-1);
-            _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); 
-            if (0 == _S_start_free) {
-              _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
-            }
-          }
-#       else  /* !SGI_SOURCE */
-          _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
-#       endif
-        _S_heap_size += __bytes_to_get;
-        _S_end_free = _S_start_free + __bytes_to_get;
-    }
-  }
-  // lock is released here
-  return(_S_chunk_alloc(__size, __nobjs));
-}
-
-
-/* Returns an object of size n, and optionally adds to size n free list.*/
-/* We assume that n is properly aligned.                                */
-/* We hold the allocation lock.                                         */
-template <size_t _Max_size>
-void *_Pthread_alloc_per_thread_state<_Max_size>
-::_M_refill(size_t __n)
-{
-    int __nobjs = 128;
-    char * __chunk =
-       _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs);
-    __obj * volatile * __my_free_list;
-    __obj * __result;
-    __obj * __current_obj, * __next_obj;
-    int __i;
-
-    if (1 == __nobjs)  {
-        return(__chunk);
-    }
-    __my_free_list = __free_list
-                + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n);
-
-    /* Build free list in chunk */
-      __result = (__obj *)__chunk;
-      *__my_free_list = __next_obj = (__obj *)(__chunk + __n);
-      for (__i = 1; ; __i++) {
-        __current_obj = __next_obj;
-        __next_obj = (__obj *)((char *)__next_obj + __n);
-        if (__nobjs - 1 == __i) {
-            __current_obj -> __free_list_link = 0;
-            break;
-        } else {
-            __current_obj -> __free_list_link = __next_obj;
-        }
-      }
-    return(__result);
-}
-
-template <size_t _Max_size>
-void *_Pthread_alloc_template<_Max_size>
-::reallocate(void *__p, size_t __old_sz, size_t __new_sz)
-{
-    void * __result;
-    size_t __copy_sz;
-
-    if (__old_sz > _Max_size
-       && __new_sz > _Max_size) {
-        return(realloc(__p, __new_sz));
-    }
-    if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
-    __result = allocate(__new_sz);
-    __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
-    memcpy(__result, __p, __copy_sz);
-    deallocate(__p, __old_sz);
-    return(__result);
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0;
-
-template <size_t _Max_size>
-pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key;
-
-template <size_t _Max_size>
-bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false;
-
-template <size_t _Max_size>
-pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock
-= PTHREAD_MUTEX_INITIALIZER;
-
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_start_free = 0;
-
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_end_free = 0;
-
-template <size_t _Max_size>
-size_t _Pthread_alloc_template<_Max_size>
-::_S_heap_size = 0;
-
-
-template <class _Tp>
-class pthread_allocator {
-  typedef pthread_alloc _S_Alloc;          // The underlying allocator.
-public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef _Tp*       pointer;
-  typedef const _Tp* const_pointer;
-  typedef _Tp&       reference;
-  typedef const _Tp& const_reference;
-  typedef _Tp        value_type;
-
-  template <class _NewType> struct rebind {
-    typedef pthread_allocator<_NewType> other;
-  };
-
-  pthread_allocator() throw() {}
-  pthread_allocator(const pthread_allocator& a) throw() {}
-  template <class _OtherType>
-       pthread_allocator(const pthread_allocator<_OtherType>&)
-               throw() {}
-  ~pthread_allocator() throw() {}
-
-  pointer address(reference __x) const { return &__x; }
-  const_pointer address(const_reference __x) const { return &__x; }
-
-  // __n is permitted to be 0.  The C++ standard says nothing about what
-  // the return value is when __n == 0.
-  _Tp* allocate(size_type __n, const void* = 0) {
-    return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp)))
-                    : 0;
-  }
-
-  // p is not permitted to be a null pointer.
-  void deallocate(pointer __p, size_type __n)
-    { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); }
-
-  size_type max_size() const throw() 
-    { return size_t(-1) / sizeof(_Tp); }
-
-  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
-  void destroy(pointer _p) { _p->~_Tp(); }
-};
-
-template<>
-class pthread_allocator<void> {
-public:
-  typedef size_t      size_type;
-  typedef ptrdiff_t   difference_type;
-  typedef void*       pointer;
-  typedef const void* const_pointer;
-  typedef void        value_type;
-
-  template <class _NewType> struct rebind {
-    typedef pthread_allocator<_NewType> other;
-  };
-};
-
-template <size_t _Max_size>
-inline bool operator==(const _Pthread_alloc_template<_Max_size>&,
-                       const _Pthread_alloc_template<_Max_size>&)
-{
-  return true;
-}
-
-template <class _T1, class _T2>
-inline bool operator==(const pthread_allocator<_T1>&,
-                       const pthread_allocator<_T2>& a2) 
-{
-  return true;
-}
-
-template <class _T1, class _T2>
-inline bool operator!=(const pthread_allocator<_T1>&,
-                       const pthread_allocator<_T2>&)
-{
-  return false;
-}
-
-template <class _Tp, size_t _Max_size>
-struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> >
-{
-  static const bool _S_instanceless = true;
-  typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type;
-  typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > 
-          allocator_type;
-};
-
-template <class _Tp, class _Atype, size_t _Max>
-struct _Alloc_traits<_Tp, __allocator<_Atype, _Pthread_alloc_template<_Max> > >
-{
-  static const bool _S_instanceless = true;
-  typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type;
-  typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type;
-};
-
-template <class _Tp, class _Atype>
-struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
-{
-  static const bool _S_instanceless = true;
-  typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type;
-  typedef pthread_allocator<_Tp> allocator_type;
-};
-
-
-} // namespace std
-
-#endif /* _CPP_BITS_PTHREAD_ALLOCIMPL_H */
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/libstdc++-v3/include/bits/stl_alloc.h b/libstdc++-v3/include/bits/stl_alloc.h
deleted file mode 100644 (file)
index 3d26d6d..0000000
+++ /dev/null
@@ -1,900 +0,0 @@
-// Allocators -*- C++ -*-
-
-// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/*
- * Copyright (c) 1996-1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- */
-
-/** @file stl_alloc.h
- *  This is an internal header file, included by other library headers.
- *  You should not attempt to use it directly.
- */
-
-#ifndef __GLIBCPP_INTERNAL_ALLOC_H
-#define __GLIBCPP_INTERNAL_ALLOC_H
-
-/**
- *  @defgroup Allocators Memory Allocators
- *  @if maint
- *  stl_alloc.h implements some node allocators.  These are NOT the same as
- *  allocators in the C++ standard, nor in the original H-P STL.  They do not
- *  encapsulate different pointer types; we assume that there is only one
- *  pointer type.  The C++ standard allocators are intended to allocate
- *  individual objects, not pools or arenas.
- *
- *  In this file allocators are of two different styles:  "standard" and
- *  "SGI" (quotes included).  "Standard" allocators conform to 20.4.  "SGI"
- *  allocators differ in AT LEAST the following ways (add to this list as you
- *  discover them):
- *
- *   - "Standard" allocate() takes two parameters (n_count,hint=0) but "SGI"
- *     allocate() takes one paramter (n_size).
- *   - Likewise, "standard" deallocate()'s argument is a count, but in "SGI"
- *     is a byte size.
- *   - max_size(), construct(), and destroy() are missing in "SGI" allocators.
- *   - reallocate(p,oldsz,newsz) is added in "SGI", and behaves as
- *     if p=realloc(p,newsz).
- *
- *  "SGI" allocators may be wrapped in __allocator to convert the interface
- *  into a "standard" one.
- *  @endif
- *
- *  The canonical description of these classes is in docs/html/ext/howto.html
- *  or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3
-*/
-
-#include <cstddef>
-#include <cstdlib>
-#include <cstring>
-#include <bits/functexcept.h>   // For __throw_bad_alloc
-#include <bits/stl_threads.h>
-#include <bits/atomicity.h>
-
-namespace std
-{
-  /**
-   *  @if maint
-   *  A new-based allocator, as required by the standard.  Allocation and
-   *  deallocation forward to global new and delete.  "SGI" style, minus
-   *  reallocate().
-   *  @endif
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  class __new_alloc
-  {
-  public:
-    static void*
-    allocate(size_t __n)
-    { return ::operator new(__n); }
-
-    static void
-    deallocate(void* __p, size_t)
-    { ::operator delete(__p); }
-  };
-
-
-  /**
-   *  @if maint
-   *  A malloc-based allocator.  Typically slower than the
-   *  __pool_alloc (below).  Typically thread-safe and more
-   *  storage efficient.  The template argument is unused and is only present
-   *  to permit multiple instantiations (but see __pool_alloc
-   *  for caveats).  "SGI" style, plus __set_malloc_handler for OOM conditions.
-   *  @endif
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  template<int __inst>
-    class __malloc_alloc
-    {
-    private:
-      static void* _S_oom_malloc(size_t);
-      static void (* __malloc_alloc_oom_handler)();
-
-    public:
-      static void*
-      allocate(size_t __n)
-      {
-        void* __result = malloc(__n);
-        if (__builtin_expect(__result == 0, 0))
-         __result = _S_oom_malloc(__n);
-        return __result;
-      }
-
-      static void
-      deallocate(void* __p, size_t /* __n */)
-      { free(__p); }
-
-      static void (* __set_malloc_handler(void (*__f)()))()
-      {
-        void (* __old)() = __malloc_alloc_oom_handler;
-        __malloc_alloc_oom_handler = __f;
-        return __old;
-      }
-    };
-
-  // malloc_alloc out-of-memory handling
-  template<int __inst>
-    void (* __malloc_alloc<__inst>::__malloc_alloc_oom_handler)() = 0;
-
-  template<int __inst>
-    void*
-    __malloc_alloc<__inst>::
-    _S_oom_malloc(size_t __n)
-    {
-      void (* __my_malloc_handler)();
-      void* __result;
-
-      for (;;)
-        {
-          __my_malloc_handler = __malloc_alloc_oom_handler;
-          if (__builtin_expect(__my_malloc_handler == 0, 0))
-            __throw_bad_alloc();
-          (*__my_malloc_handler)();
-          __result = malloc(__n);
-          if (__result)
-            return __result;
-        }
-    }
-
-
-  /**
-   *  @if maint
-   *  This is used primarily (only?) in _Alloc_traits and other places to
-   *  help provide the _Alloc_type typedef.  All it does is forward the
-   *  requests after some minimal checking.
-   *
-   *  This is neither "standard"-conforming nor "SGI".  The _Alloc parameter
-   *  must be "SGI" style.
-   *  @endif
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  template<typename _Tp, typename _Alloc>
-    class __simple_alloc
-    {
-    public:
-      static _Tp*
-      allocate(size_t __n)
-      {
-       _Tp* __ret = 0;
-       if (__n)
-         __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
-       return __ret;
-      }
-  
-      static _Tp*
-      allocate()
-      { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
-  
-      static void
-      deallocate(_Tp* __p, size_t __n)
-      { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
-  
-      static void
-      deallocate(_Tp* __p)
-      { _Alloc::deallocate(__p, sizeof (_Tp)); }
-    };
-
-
-  /**
-   *  @if maint
-   *  An adaptor for an underlying allocator (_Alloc) to check the size
-   *  arguments for debugging.
-   *
-   *  "There is some evidence that this can confuse Purify." - SGI comment
-   *
-   *  This adaptor is "SGI" style.  The _Alloc parameter must also be "SGI".
-   *  @endif
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  template<typename _Alloc>
-    class __debug_alloc
-    {
-    private:
-      // Size of space used to store size.  Note that this must be
-      // large enough to preserve alignment.
-      enum {_S_extra = 8};
-
-    public:
-      static void*
-      allocate(size_t __n)
-      {
-        char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
-        *(size_t*)__result = __n;
-        return __result + (int) _S_extra;
-      }
-
-      static void
-      deallocate(void* __p, size_t __n)
-      {
-        char* __real_p = (char*)__p - (int) _S_extra;
-        if (*(size_t*)__real_p != __n)
-          abort();
-        _Alloc::deallocate(__real_p, __n + (int) _S_extra);
-      }
-    };
-
-
-  /**
-   *  @if maint
-   *  Default node allocator.  "SGI" style.  Uses various allocators to
-   *  fulfill underlying requests (and makes as few requests as possible
-   *  when in default high-speed pool mode).
-   *
-   *  Important implementation properties:
-   *  0. If globally mandated, then allocate objects from __new_alloc
-   *  1. If the clients request an object of size > _S_max_bytes, the resulting
-   *     object will be obtained directly from __new_alloc
-   *  2. In all other cases, we allocate an object of size exactly
-   *     _S_round_up(requested_size).  Thus the client has enough size
-   *     information that we can return the object to the proper free list
-   *     without permanently losing part of the object.
-   *
-   *  The first template parameter specifies whether more than one thread may
-   *  use this allocator.  It is safe to allocate an object from one instance
-   *  of a default_alloc and deallocate it with another one.  This effectively
-   *  transfers its ownership to the second one.  This may have undesirable
-   *  effects on reference locality.
-   *
-   *  The second parameter is unused and serves only to allow the creation of
-   *  multiple default_alloc instances.  Note that containers built on different
-   *  allocator instances have different types, limiting the utility of this
-   *  approach.  If you do not wish to share the free lists with the main
-   *  default_alloc instance, instantiate this with a non-zero __inst.
-   *
-   *  @endif
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  template<bool __threads, int __inst>
-    class __pool_alloc
-    {
-    private:
-      enum {_S_align = 8};
-      enum {_S_max_bytes = 128};
-      enum {_S_freelists = _S_max_bytes / _S_align};
-
-      union _Obj
-      {
-        union _Obj* _M_free_list_link;
-        char        _M_client_data[1];    // The client sees this.
-      };
-
-      static _Obj* volatile         _S_free_list[_S_freelists];
-
-      // Chunk allocation state.
-      static char*                  _S_start_free;
-      static char*                  _S_end_free;
-      static size_t                 _S_heap_size;
-
-      static _STL_mutex_lock        _S_lock;
-      static _Atomic_word          _S_force_new;
-
-      static size_t
-      _S_round_up(size_t __bytes)
-      { return (((__bytes) + (size_t) _S_align-1) & ~((size_t) _S_align - 1)); }
-
-      static size_t
-      _S_freelist_index(size_t __bytes)
-      { return (((__bytes) + (size_t)_S_align - 1)/(size_t)_S_align - 1); }
-
-      // Returns an object of size __n, and optionally adds to size __n
-      // free list.
-      static void*
-      _S_refill(size_t __n);
-
-      // Allocates a chunk for nobjs of size size.  nobjs may be reduced
-      // if it is inconvenient to allocate the requested number.
-      static char*
-      _S_chunk_alloc(size_t __size, int& __nobjs);
-
-      // It would be nice to use _STL_auto_lock here.  But we need a
-      // test whether threads are in use.
-      struct _Lock
-      {
-        _Lock() { if (__threads) _S_lock._M_acquire_lock(); }
-        ~_Lock() { if (__threads) _S_lock._M_release_lock(); }
-      } __attribute__ ((__unused__));
-      friend struct _Lock;
-
-    public:
-      // __n must be > 0
-      static void*
-      allocate(size_t __n)
-      {
-       void* __ret = 0;
-
-       // If there is a race through here, assume answer from getenv
-       // will resolve in same direction.  Inspired by techniques
-       // to efficiently support threading found in basic_string.h.
-       if (_S_force_new == 0)
-         {
-           if (getenv("GLIBCPP_FORCE_NEW"))
-             __atomic_add(&_S_force_new, 1);
-           else
-             __atomic_add(&_S_force_new, -1);
-         }
-
-       if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
-         __ret = __new_alloc::allocate(__n);
-       else
-         {
-           _Obj* volatile* __my_free_list = _S_free_list
-             + _S_freelist_index(__n);
-           // Acquire the lock here with a constructor call.  This
-           // ensures that it is released in exit or during stack
-           // unwinding.
-           _Lock __lock_instance;
-           _Obj* __restrict__ __result = *__my_free_list;
-           if (__builtin_expect(__result == 0, 0))
-             __ret = _S_refill(_S_round_up(__n));
-           else
-             {
-               *__my_free_list = __result -> _M_free_list_link;
-               __ret = __result;
-             }     
-           if (__builtin_expect(__ret == 0, 0))
-             __throw_bad_alloc();
-         }
-       return __ret;
-      }
-
-      // __p may not be 0
-      static void
-      deallocate(void* __p, size_t __n)
-      {
-       if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
-         __new_alloc::deallocate(__p, __n);
-       else
-         {
-           _Obj* volatile*  __my_free_list = _S_free_list
-             + _S_freelist_index(__n);
-           _Obj* __q = (_Obj*)__p;
-
-           // Acquire the lock here with a constructor call.  This
-           // ensures that it is released in exit or during stack
-           // unwinding.
-           _Lock __lock_instance;
-           __q -> _M_free_list_link = *__my_free_list;
-           *__my_free_list = __q;
-         }
-      }
-    };
-
-  template<bool __threads, int __inst> _Atomic_word
-  __pool_alloc<__threads, __inst>::_S_force_new = 0;
-
-  template<bool __threads, int __inst>
-    inline bool
-    operator==(const __pool_alloc<__threads,__inst>&, 
-              const __pool_alloc<__threads,__inst>&)
-    { return true; }
-
-  template<bool __threads, int __inst>
-    inline bool
-    operator!=(const __pool_alloc<__threads,__inst>&,
-               const __pool_alloc<__threads,__inst>&)
-    { return false; }
-
-
-  // We allocate memory in large chunks in order to avoid fragmenting the
-  // heap too much.  We assume that __size is properly aligned.  We hold
-  // the allocation lock.
-  template<bool __threads, int __inst>
-    char*
-    __pool_alloc<__threads, __inst>::
-    _S_chunk_alloc(size_t __size, int& __nobjs)
-    {
-      char* __result;
-      size_t __total_bytes = __size * __nobjs;
-      size_t __bytes_left = _S_end_free - _S_start_free;
-
-      if (__bytes_left >= __total_bytes)
-        {
-          __result = _S_start_free;
-          _S_start_free += __total_bytes;
-          return __result ;
-        }
-      else if (__bytes_left >= __size)
-        {
-          __nobjs = (int)(__bytes_left/__size);
-          __total_bytes = __size * __nobjs;
-          __result = _S_start_free;
-          _S_start_free += __total_bytes;
-          return __result;
-        }
-      else
-        {
-          size_t __bytes_to_get =
-            2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
-          // Try to make use of the left-over piece.
-          if (__bytes_left > 0)
-            {
-              _Obj* volatile* __my_free_list =
-                _S_free_list + _S_freelist_index(__bytes_left);
-
-              ((_Obj*)(void*)_S_start_free) -> _M_free_list_link = *__my_free_list;
-              *__my_free_list = (_Obj*)(void*)_S_start_free;
-            }
-          _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
-          if (_S_start_free == 0)
-            {
-              size_t __i;
-              _Obj* volatile* __my_free_list;
-              _Obj* __p;
-              // Try to make do with what we have.  That can't hurt.  We
-              // do not try smaller requests, since that tends to result
-              // in disaster on multi-process machines.
-              __i = __size;
-              for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
-                {
-                  __my_free_list = _S_free_list + _S_freelist_index(__i);
-                  __p = *__my_free_list;
-                  if (__p != 0)
-                    {
-                      *__my_free_list = __p -> _M_free_list_link;
-                      _S_start_free = (char*)__p;
-                      _S_end_free = _S_start_free + __i;
-                      return _S_chunk_alloc(__size, __nobjs);
-                      // Any leftover piece will eventually make it to the
-                      // right free list.
-                    }
-                }
-              _S_end_free = 0;        // In case of exception.
-              _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
-              // This should either throw an exception or remedy the situation.
-              // Thus we assume it succeeded.
-            }
-          _S_heap_size += __bytes_to_get;
-          _S_end_free = _S_start_free + __bytes_to_get;
-          return _S_chunk_alloc(__size, __nobjs);
-        }
-    }
-
-
-  // Returns an object of size __n, and optionally adds to "size
-  // __n"'s free list.  We assume that __n is properly aligned.  We
-  // hold the allocation lock.
-  template<bool __threads, int __inst>
-    void*
-    __pool_alloc<__threads, __inst>::_S_refill(size_t __n)
-    {
-      int __nobjs = 20;
-      char* __chunk = _S_chunk_alloc(__n, __nobjs);
-      _Obj* volatile* __my_free_list;
-      _Obj* __result;
-      _Obj* __current_obj;
-      _Obj* __next_obj;
-      int __i;
-
-      if (1 == __nobjs)
-        return __chunk;
-      __my_free_list = _S_free_list + _S_freelist_index(__n);
-
-      // Build free list in chunk.
-      __result = (_Obj*)(void*)__chunk;
-      *__my_free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
-      for (__i = 1; ; __i++)
-        {
-         __current_obj = __next_obj;
-          __next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
-         if (__nobjs - 1 == __i)
-           {
-             __current_obj -> _M_free_list_link = 0;
-             break;
-           }
-         else
-           __current_obj -> _M_free_list_link = __next_obj;
-       }
-      return __result;
-    }
-
-
-  template<bool __threads, int __inst>
-    _STL_mutex_lock
-    __pool_alloc<__threads,__inst>::_S_lock __STL_MUTEX_INITIALIZER;
-
-  template<bool __threads, int __inst>
-    char* __pool_alloc<__threads,__inst>::_S_start_free = 0;
-
-  template<bool __threads, int __inst>
-    char* __pool_alloc<__threads,__inst>::_S_end_free = 0;
-
-  template<bool __threads, int __inst>
-    size_t __pool_alloc<__threads,__inst>::_S_heap_size = 0;
-
-  template<bool __threads, int __inst>
-    typename __pool_alloc<__threads,__inst>::_Obj* volatile
-    __pool_alloc<__threads,__inst>::_S_free_list[_S_freelists];
-
-  typedef __pool_alloc<true,0>    __alloc;
-  typedef __pool_alloc<false,0>   __single_client_alloc;
-
-
-  /**
-   *  @brief  The "standard" allocator, as per [20.4].
-   *
-   *  The private _Alloc is "SGI" style.  (See comments at the top
-   *  of stl_alloc.h.)
-   *
-   *  The underlying allocator behaves as follows.
-   *    - __pool_alloc is used via two typedefs
-   *    - "__single_client_alloc" typedef does no locking for threads
-   *    - "__alloc" typedef is threadsafe via the locks
-   *    - __new_alloc is used for memory requests
-   *
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  template<typename _Tp>
-    class allocator
-    {
-      typedef __alloc _Alloc;          // The underlying allocator.
-    public:
-      typedef size_t     size_type;
-      typedef ptrdiff_t  difference_type;
-      typedef _Tp*       pointer;
-      typedef const _Tp* const_pointer;
-      typedef _Tp&       reference;
-      typedef const _Tp& const_reference;
-      typedef _Tp        value_type;
-
-      template<typename _Tp1>
-        struct rebind
-        { typedef allocator<_Tp1> other; };
-
-      allocator() throw() {}
-      allocator(const allocator&) throw() {}
-      template<typename _Tp1>
-        allocator(const allocator<_Tp1>&) throw() {}
-      ~allocator() throw() {}
-
-      pointer
-      address(reference __x) const { return &__x; }
-
-      const_pointer
-      address(const_reference __x) const { return &__x; }
-
-      // NB: __n is permitted to be 0.  The C++ standard says nothing
-      // about what the return value is when __n == 0.
-      _Tp*
-      allocate(size_type __n, const void* = 0)
-      {
-       _Tp* __ret = 0;
-       if (__n)
-         {
-           if (__n <= this->max_size())
-             __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
-           else
-             __throw_bad_alloc();
-         }
-       return __ret;
-      }
-
-      // __p is not permitted to be a null pointer.
-      void
-      deallocate(pointer __p, size_type __n)
-      { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
-
-      size_type
-      max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
-
-      void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
-      void destroy(pointer __p) { __p->~_Tp(); }
-    };
-
-  template<>
-    class allocator<void>
-    {
-    public:
-      typedef size_t      size_type;
-      typedef ptrdiff_t   difference_type;
-      typedef void*       pointer;
-      typedef const void* const_pointer;
-      typedef void        value_type;
-
-      template<typename _Tp1>
-        struct rebind
-        { typedef allocator<_Tp1> other; };
-    };
-
-
-  template<typename _T1, typename _T2>
-    inline bool
-    operator==(const allocator<_T1>&, const allocator<_T2>&)
-    { return true; }
-
-  template<typename _T1, typename _T2>
-    inline bool
-    operator!=(const allocator<_T1>&, const allocator<_T2>&)
-    { return false; }
-
-
-  /**
-   *  @if maint
-   *  Allocator adaptor to turn an "SGI" style allocator (e.g.,
-   *  __alloc, __malloc_alloc) into a "standard" conforming
-   *  allocator.  Note that this adaptor does *not* assume that all
-   *  objects of the underlying alloc class are identical, nor does it
-   *  assume that all of the underlying alloc's member functions are
-   *  static member functions.  Note, also, that __allocator<_Tp,
-   *  __alloc> is essentially the same thing as allocator<_Tp>.
-   *  @endif
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  template<typename _Tp, typename _Alloc>
-    struct __allocator
-    {
-      _Alloc __underlying_alloc;
-      
-      typedef size_t    size_type;
-      typedef ptrdiff_t difference_type;
-      typedef _Tp*       pointer;
-      typedef const _Tp* const_pointer;
-      typedef _Tp&       reference;
-      typedef const _Tp& const_reference;
-      typedef _Tp        value_type;
-
-      template<typename _Tp1>
-        struct rebind
-        { typedef __allocator<_Tp1, _Alloc> other; };
-
-      __allocator() throw() {}
-      __allocator(const __allocator& __a) throw()
-      : __underlying_alloc(__a.__underlying_alloc) {}
-
-      template<typename _Tp1>
-        __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
-        : __underlying_alloc(__a.__underlying_alloc) {}
-
-      ~__allocator() throw() {}
-
-      pointer
-      address(reference __x) const { return &__x; }
-
-      const_pointer
-      address(const_reference __x) const { return &__x; }
-
-      // NB: __n is permitted to be 0.  The C++ standard says nothing
-      // about what the return value is when __n == 0.
-      _Tp*
-      allocate(size_type __n, const void* = 0)
-      {
-       _Tp* __ret = 0;
-       if (__n)
-         __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
-       return __ret;
-      }
-
-      // __p is not permitted to be a null pointer.
-      void
-      deallocate(pointer __p, size_type __n)
-      { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
-      
-      size_type
-      max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
-      
-      void
-      construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
-      
-      void
-      destroy(pointer __p) { __p->~_Tp(); }
-    };
-
-  template<typename _Alloc>
-    struct __allocator<void, _Alloc>
-    {
-      typedef size_t      size_type;
-      typedef ptrdiff_t   difference_type;
-      typedef void*       pointer;
-      typedef const void* const_pointer;
-      typedef void        value_type;
-
-      template<typename _Tp1>
-        struct rebind
-        { typedef __allocator<_Tp1, _Alloc> other; };
-    };
-
-  template<typename _Tp, typename _Alloc>
-    inline bool
-    operator==(const __allocator<_Tp,_Alloc>& __a1,
-               const __allocator<_Tp,_Alloc>& __a2)
-    { return __a1.__underlying_alloc == __a2.__underlying_alloc; }
-
-  template<typename _Tp, typename _Alloc>
-    inline bool
-    operator!=(const __allocator<_Tp, _Alloc>& __a1,
-               const __allocator<_Tp, _Alloc>& __a2)
-    { return __a1.__underlying_alloc != __a2.__underlying_alloc; }
-
-
-  //@{
-  /** Comparison operators for all of the predifined SGI-style allocators.
-   *  This ensures that __allocator<malloc_alloc> (for example) will work
-   *  correctly.  As required, all allocators compare equal.
-   */
-  template<int inst>
-    inline bool
-    operator==(const __malloc_alloc<inst>&,
-               const __malloc_alloc<inst>&)
-    { return true; }
-
-  template<int __inst>
-    inline bool
-    operator!=(const __malloc_alloc<__inst>&,
-               const __malloc_alloc<__inst>&)
-    { return false; }
-
-  template<typename _Alloc>
-    inline bool
-    operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
-    { return true; }
-
-  template<typename _Alloc>
-    inline bool
-    operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
-    { return false; }
-  //@}
-
-
-  /**
-   *  @if maint
-   *  Another allocator adaptor:  _Alloc_traits.  This serves two purposes.
-   *  First, make it possible to write containers that can use either "SGI"
-   *  style allocators or "standard" allocators.  Second, provide a mechanism
-   *  so that containers can query whether or not the allocator has distinct
-   *  instances.  If not, the container can avoid wasting a word of memory to
-   *  store an empty object.  For examples of use, see stl_vector.h, etc, or
-   *  any of the other classes derived from this one.
-   *
-   *  This adaptor uses partial specialization.  The general case of
-   *  _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
-   *  standard-conforming allocator, possibly with non-equal instances and
-   *  non-static members.  (It still behaves correctly even if _Alloc has
-   *  static member and if all instances are equal.  Refinements affect
-   *  performance, not correctness.)
-   *
-   *  There are always two members:  allocator_type, which is a standard-
-   *  conforming allocator type for allocating objects of type _Tp, and
-   *  _S_instanceless, a static const member of type bool.  If
-   *  _S_instanceless is true, this means that there is no difference
-   *  between any two instances of type allocator_type.  Furthermore, if
-   *  _S_instanceless is true, then _Alloc_traits has one additional
-   *  member:  _Alloc_type.  This type encapsulates allocation and
-   *  deallocation of objects of type _Tp through a static interface; it
-   *  has two member functions, whose signatures are
-   *
-   *  -  static _Tp* allocate(size_t)
-   *  -  static void deallocate(_Tp*, size_t)
-   *
-   *  The size_t parameters are "standard" style (see top of stl_alloc.h) in
-   *  that they take counts, not sizes.
-   *
-   *  @endif
-   *  (See @link Allocators allocators info @endlink for more.)
-   */
-  //@{
-  // The fully general version.
-  template<typename _Tp, typename _Allocator>
-    struct _Alloc_traits
-    {
-      static const bool _S_instanceless = false;
-      typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
-    };
-
-  template<typename _Tp, typename _Allocator>
-    const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
-
-  /// The version for the default allocator.
-  template<typename _Tp, typename _Tp1>
-    struct _Alloc_traits<_Tp, allocator<_Tp1> >
-    {
-      static const bool _S_instanceless = true;
-      typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
-      typedef allocator<_Tp> allocator_type;
-    };
-  //@}
-
-  //@{
-  /// Versions for the predefined "SGI" style allocators.
-  template<typename _Tp, int __inst>
-    struct _Alloc_traits<_Tp, __malloc_alloc<__inst> >
-    {
-      static const bool _S_instanceless = true;
-      typedef __simple_alloc<_Tp, __malloc_alloc<__inst> > _Alloc_type;
-      typedef __allocator<_Tp, __malloc_alloc<__inst> > allocator_type;
-    };
-
-  template<typename _Tp, bool __threads, int __inst>
-    struct _Alloc_traits<_Tp, __pool_alloc<__threads, __inst> >
-    {
-      static const bool _S_instanceless = true;
-      typedef __simple_alloc<_Tp, __pool_alloc<__threads, __inst> >
-      _Alloc_type;
-      typedef __allocator<_Tp, __pool_alloc<__threads, __inst> >
-      allocator_type;
-    };
-
-  template<typename _Tp, typename _Alloc>
-    struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
-    {
-      static const bool _S_instanceless = true;
-      typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
-      typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
-    };
-  //@}
-
-  //@{
-  /// Versions for the __allocator adaptor used with the predefined
-  /// "SGI" style allocators.
-  template<typename _Tp, typename _Tp1, int __inst>
-    struct _Alloc_traits<_Tp,
-                         __allocator<_Tp1, __malloc_alloc<__inst> > >
-    {
-      static const bool _S_instanceless = true;
-      typedef __simple_alloc<_Tp, __malloc_alloc<__inst> > _Alloc_type;
-      typedef __allocator<_Tp, __malloc_alloc<__inst> > allocator_type;
-    };
-
-  template<typename _Tp, typename _Tp1, bool __thr, int __inst>
-    struct _Alloc_traits<_Tp, __allocator<_Tp1, __pool_alloc<__thr, __inst> > >
-    {
-      static const bool _S_instanceless = true;
-      typedef __simple_alloc<_Tp, __pool_alloc<__thr,__inst> >
-      _Alloc_type;
-      typedef __allocator<_Tp, __pool_alloc<__thr,__inst> >
-      allocator_type;
-    };
-
-  template<typename _Tp, typename _Tp1, typename _Alloc>
-    struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
-    {
-      static const bool _S_instanceless = true;
-      typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
-      typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
-    };
-  //@}
-
-  // Inhibit implicit instantiations for required instantiations,
-  // which are defined via explicit instantiations elsewhere.
-  // NB: This syntax is a GNU extension.
-#if _GLIBCPP_EXTERN_TEMPLATE
-  extern template class allocator<char>;
-  extern template class allocator<wchar_t>;
-  extern template class __pool_alloc<true,0>;
-#endif
-} // namespace std
-
-#endif
index 8805b7589f63518f6d155a14094ec79d71bc6dac..5863af55a35664788a795997e9e3daa6de37fd6f 100644 (file)
@@ -340,7 +340,7 @@ namespace std
    *  and destructor allocate (but don't initialize) storage.  This makes
    *  %exception safety easier.  Second, the base class encapsulates all of
    *  the differences between SGI-style allocators and standard-conforming
-   *  allocators.  (See stl_alloc.h for more on this topic.)  There are two
+   *  allocators.  (See allocator.h for more on this topic.)  There are two
    *  versions:  this ordinary one, and the space-saving specialization for
    *  instanceless allocators.
    *  @endif
index a95fc38a4236003d1cffb34d8a87eda2cd165cdc..1fb68f01e5f594ec25532b7495ed627eb012541f 100644 (file)
@@ -48,6 +48,8 @@
 #ifndef __SGI_STL_INTERNAL_THREADS_H
 #define __SGI_STL_INTERNAL_THREADS_H
 
+#include <cstddef>
+
 // The only supported threading model is GCC's own gthr.h abstraction layer.
 #include "bits/gthr.h"
 
@@ -209,7 +211,6 @@ namespace std
     void operator=(const _STL_auto_lock&);
     _STL_auto_lock(const _STL_auto_lock&);
   } __attribute__ ((__unused__));
-  
 } // namespace std
 
 #endif 
index 2965d4caab5fe79e28409fe6b79376e711cc2d60..895b98a6a527f4cf05bc471de314c058ce30cc13 100644 (file)
@@ -84,7 +84,7 @@ iterators invalidated are those referring to the deleted node.
 */
 
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_function.h>
 
diff --git a/libstdc++-v3/include/ext/debug_allocator.h b/libstdc++-v3/include/ext/debug_allocator.h
new file mode 100644 (file)
index 0000000..0f7eb0c
--- /dev/null
@@ -0,0 +1,139 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/** @file ext/debug_allocator.h
+ *  This file is a GNU extension to the Standard C++ Library. 
+ *  You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _DEBUG_ALLOCATOR_H
+#define _DEBUG_ALLOCATOR_H 1
+
+#include <bits/allocator_traits.h>
+
+namespace __gnu_cxx
+{
+  /**
+   *  @if maint
+   *  An adaptor for an underlying allocator (_Alloc) to check the size
+   *  arguments for debugging.
+   *
+   *  "There is some evidence that this can confuse Purify." - SGI comment
+   *
+   *  This adaptor is "SGI" style.  The _Alloc parameter must also be "SGI".
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<typename _Alloc>
+    class __debug_alloc
+    {
+    private:
+      // Size of space used to store size.  Note that this must be
+      // large enough to preserve alignment.
+      enum {_S_extra = 8};
+
+    public:
+      static void*
+      allocate(size_t __n)
+      {
+        char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
+        *(size_t*)__result = __n;
+        return __result + (int) _S_extra;
+      }
+
+      static void
+      deallocate(void* __p, size_t __n)
+      {
+        char* __real_p = (char*)__p - (int) _S_extra;
+        if (*(size_t*)__real_p != __n)
+          abort();
+        _Alloc::deallocate(__real_p, __n + (int) _S_extra);
+      }
+    };
+
+  //@{
+  /** Comparison operators for all of the predifined SGI-style allocators.
+   *  This ensures that __allocator<malloc_alloc> (for example) will work
+   *  correctly.  As required, all allocators compare equal.
+   */
+  template<typename _Alloc>
+    inline bool
+    operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+    { return true; }
+
+  template<typename _Alloc>
+    inline bool
+    operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+    { return false; }
+  //@}
+} // namespace __gnu_cxx
+
+namespace std
+{
+  //@{
+  /// Versions for the predefined "SGI" style allocators.
+  template<typename _Tp, typename _Alloc>
+    struct _Alloc_traits<_Tp, __gnu_cxx::__debug_alloc<_Alloc> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __gnu_cxx::__debug_alloc<_Alloc>         base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+  //@}
+
+  //@{
+  /// Versions for the __allocator adaptor used with the predefined
+  /// "SGI" style allocators.
+  template<typename _Tp, typename _Tp1, typename _Alloc>
+    struct _Alloc_traits<_Tp, __allocator<_Tp1, 
+                                         __gnu_cxx::__debug_alloc<_Alloc> > >
+    {
+      static const bool _S_instanceless = true;
+      typedef __gnu_cxx::__debug_alloc<_Alloc>         base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+  //@}
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/ext/malloc_allocator.h b/libstdc++-v3/include/ext/malloc_allocator.h
new file mode 100644 (file)
index 0000000..410b296
--- /dev/null
@@ -0,0 +1,163 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/** @file ext/debug_allocator.h
+ *  This file is a GNU extension to the Standard C++ Library. 
+ *  You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _MALLOC_ALLOCATOR_H
+#define _MALLOC_ALLOCATOR_H 1
+
+#include <bits/allocator_traits.h>
+
+namespace __gnu_cxx
+{
+  /**
+   *  @if maint
+   *  A malloc-based allocator.  Typically slower than the
+   *  __pool_alloc (below).  Typically thread-safe and more
+   *  storage efficient.  The template argument is unused and is only present
+   *  to permit multiple instantiations (but see __pool_alloc
+   *  for caveats).  "SGI" style, plus __set_malloc_handler for OOM conditions.
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<int __inst>
+    class __malloc_alloc
+    {
+    private:
+      static void* _S_oom_malloc(size_t);
+      static void (* __malloc_alloc_oom_handler)();
+
+    public:
+      static void*
+      allocate(size_t __n)
+      {
+        void* __result = malloc(__n);
+        if (__builtin_expect(__result == 0, 0))
+         __result = _S_oom_malloc(__n);
+        return __result;
+      }
+
+      static void
+      deallocate(void* __p, size_t /* __n */)
+      { free(__p); }
+
+      static void (* __set_malloc_handler(void (*__f)()))()
+      {
+        void (* __old)() = __malloc_alloc_oom_handler;
+        __malloc_alloc_oom_handler = __f;
+        return __old;
+      }
+    };
+
+  // malloc_alloc out-of-memory handling
+  template<int __inst>
+    void (* __malloc_alloc<__inst>::__malloc_alloc_oom_handler)() = 0;
+
+  template<int __inst>
+    void*
+    __malloc_alloc<__inst>::
+    _S_oom_malloc(size_t __n)
+    {
+      void (* __my_malloc_handler)();
+      void* __result;
+
+      for (;;)
+        {
+          __my_malloc_handler = __malloc_alloc_oom_handler;
+          if (__builtin_expect(__my_malloc_handler == 0, 0))
+            __throw_bad_alloc();
+          (*__my_malloc_handler)();
+          __result = malloc(__n);
+          if (__result)
+            return __result;
+        }
+    }
+  //@{
+  /** Comparison operators for all of the predifined SGI-style allocators.
+   *  This ensures that __allocator<malloc_alloc> (for example) will work
+   *  correctly.  As required, all allocators compare equal.
+   */
+  template<int inst>
+    inline bool
+    operator==(const __malloc_alloc<inst>&, const __malloc_alloc<inst>&)
+    { return true; }
+
+  template<int __inst>
+    inline bool
+    operator!=(const __malloc_alloc<__inst>&, const __malloc_alloc<__inst>&)
+    { return false; }
+  //@}
+} // namespace __gnu_cxx
+
+namespace std
+{
+  //@{
+  /// Versions for the predefined "SGI" style allocators.
+  template<typename _Tp, int __inst>
+    struct _Alloc_traits<_Tp, __gnu_cxx::__malloc_alloc<__inst> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __gnu_cxx:: __malloc_alloc<__inst>       base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+  //@}
+
+  //@{
+  /// Versions for the __allocator adaptor used with the predefined
+  /// "SGI" style allocators.
+  template<typename _Tp, typename _Tp1, int __inst>
+    struct _Alloc_traits<_Tp, __allocator<_Tp1, 
+                                         __gnu_cxx::__malloc_alloc<__inst> > >
+    {
+      static const bool _S_instanceless = true;
+      typedef __gnu_cxx:: __malloc_alloc<__inst>       base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+  //@}
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h
new file mode 100644 (file)
index 0000000..1e95b55
--- /dev/null
@@ -0,0 +1,861 @@
+// MT-optimized allocator -*- C++ -*-
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file ext/mt_allocator.h
+ *  This file is a GNU extension to the Standard C++ Library. 
+ *  You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _MT_ALLOCATOR_H
+#define _MT_ALLOCATOR_H 1
+
+#include <cstdlib>
+#include <bits/functexcept.h> 
+#include <bits/stl_threads.h>
+#include <bits/atomicity.h>
+#include <bits/allocator_traits.h>
+
+/**
+ *  This is a fixed size (power of 2) allocator which - when compiled
+ *  with thread support - will maintain one freelist per size per thread
+ *  plus a "global" one. Steps are taken to limit the per thread freelist
+ *  sizes (by returning excess back to "global").
+ *
+ *  Usage examples:
+ *    vector<int, __gnu_cxx::__mt_alloc<0> > v1;
+ *
+ *    typedef std::__allocator<char, __gnu_cxx::__mt_alloc<0> > string_alloc;
+ *    std::basic_string<char, std::char_traits<char>, string_alloc> s1;
+ */
+
+namespace __gnu_cxx
+{
+  template<int __inst>
+    class __mt_alloc
+    {
+    private:
+      /*
+       * We need to create the initial lists and set up some variables
+       * before we can answer to the first request for memory. 
+       * The initialization of these variables is done at file scope 
+       * below class declaration.
+       */
+#ifdef __GTHREADS
+      static __gthread_once_t _S_once_mt;
+#endif
+      static bool _S_initialized;
+
+      /*
+       * Using short int as type for the binmap implies we are never caching
+       * blocks larger than 65535 with this allocator
+       */
+      typedef unsigned short int binmap_type;
+      static binmap_type* _S_binmap;
+
+      static void _S_init();
+
+      /*
+       * Variables used to "tune" the behavior of the allocator, assigned
+       * and explained in detail below.
+       */
+      static size_t _S_max_bytes;
+      static size_t _S_chunk_size;
+      static size_t _S_max_threads;
+      static size_t _S_no_of_bins;
+      static size_t _S_freelist_headroom;
+
+      /*
+       * Each requesting thread is assigned an id ranging from 1 to 
+       * _S_max_threads. Thread id 0 is used as a global memory pool.
+       * In order to get constant performance on the thread assignment
+       * routine, we keep a list of free ids. When a thread first requests
+       * memory we remove the first record in this list and stores the address
+       * in a __gthread_key. When initializing the __gthread_key
+       * we specify a destructor. When this destructor (i.e. the thread dies)
+       * is called, we return the thread id to the back of this list.
+       */
+#ifdef __GTHREADS
+      struct thread_record
+      {
+        /*
+         * Points to next free thread id record. NULL if last record in list.
+         */
+        thread_record* next;
+
+        /*
+         * Thread id ranging from 1 to _S_max_threads.
+         */
+        size_t id;
+      };
+
+      static thread_record* _S_thread_freelist_first;
+      static thread_record* _S_thread_freelist_last;
+      static __gthread_mutex_t _S_thread_freelist_mutex;
+      static void _S_thread_key_destr(void* freelist_pos);
+      static __gthread_key_t _S_thread_key;
+      static size_t _S_get_thread_id();
+#endif
+
+      struct block_record
+      {
+        /*
+         * Points to the next block_record for its thread_id.
+         */
+        block_record* next;
+
+        /*
+         * The thread id of the thread which has requested this block.
+         * All blocks are initially "owned" by global pool thread id 0.
+         */
+        size_t thread_id;
+      };
+
+      struct bin_record
+      {
+        /*
+         * An "array" of pointers to the first/last free block for each 
+         * thread id. Memory to these "arrays" is allocated in _S_init() 
+         * for _S_max_threads + global pool 0.
+         */
+        block_record** first;
+        block_record** last;
+
+        /*
+         * An "array" of counters used to keep track of the amount of blocks
+         * that are on the freelist/used for each thread id.
+         * Memory to these "arrays" is allocated in _S_init() 
+         * for _S_max_threads + global pool 0.
+         */
+        size_t* free;
+        size_t* used;
+
+        /*
+         * Each bin has its own mutex which is used to ensure data integrity 
+         * while changing "ownership" on a block.
+         * The mutex is initialized in _S_init().
+         */
+#ifdef __GTHREADS
+        __gthread_mutex_t* mutex; 
+#endif
+      };
+
+      /*
+       * An "array" of bin_records each of which represents a specific 
+       * power of 2 size. Memory to this "array" is allocated in _S_init().
+       */
+      static bin_record* _S_bin;
+
+    public:
+      static void*
+      allocate(size_t __n)
+      {
+
+        /*
+         * Requests larger than _S_max_bytes are handled by
+         * malloc/free directly
+         */
+        if (__n > _S_max_bytes)
+          {
+            void* __ret = malloc(__n);
+            if (!__ret) 
+              __throw_bad_alloc();
+
+            return __ret;
+          }
+
+        /*
+         * Although the test in __gthread_once() would suffice, we
+         * wrap test of the once condition in our own unlocked
+         * check. This saves one function call to pthread_once()
+         * (which itself only tests for the once value unlocked anyway
+         * and immediately returns if set)
+         */
+        if (!_S_initialized)
+          {
+#ifdef __GTHREADS
+            if (__gthread_active_p())
+              __gthread_once(&_S_once_mt, _S_init);
+            else
+#endif
+              {
+                _S_max_threads = 0;
+                _S_init();
+              }
+          }
+
+        /*
+         * Round up to power of 2 and figure out which bin to use
+         */
+        size_t bin = _S_binmap[__n];
+
+#ifdef __GTHREADS
+        size_t thread_id = _S_get_thread_id();
+#else
+        size_t thread_id = 0;
+#endif
+
+        block_record* block;
+
+        /*
+         * Find out if we have blocks on our freelist.
+         * If so, go ahead and use them directly without
+         * having to lock anything.
+         */
+        if (_S_bin[bin].first[thread_id] == NULL)
+          {
+            /*
+             * Are we using threads?
+             * - Yes, lock and check if there are free blocks on the global 
+             *   list (and if not add new ones), get the first one 
+             *   and change owner.
+             * - No, all operations are made directly to global pool 0 
+             *   no need to lock or change ownership but check for free 
+             *   blocks on global list (and if not add new ones) and 
+             *   get the first one.
+             */
+#ifdef __GTHREADS
+            if (__gthread_active_p())
+              {
+                __gthread_mutex_lock(_S_bin[bin].mutex);
+
+                if (_S_bin[bin].first[0] == NULL)
+                  {
+                    _S_bin[bin].first[0] = 
+                      (block_record*)malloc(_S_chunk_size);
+
+                    if (!_S_bin[bin].first[0])
+                      {
+                        __gthread_mutex_unlock(_S_bin[bin].mutex);
+                        __throw_bad_alloc();
+                      }
+
+                    size_t bin_t = 1 << bin;
+                    size_t block_count = 
+                      _S_chunk_size /(bin_t + sizeof(block_record));
+
+                    _S_bin[bin].free[0] = block_count;
+
+                    block_count--;
+                    block = _S_bin[bin].first[0];
+
+                    while (block_count > 0)
+                      {
+                        block->next = (block_record*)((char*)block + 
+                                      (bin_t + sizeof(block_record)));
+                        block = block->next;
+                        block_count--;
+                      }
+
+                    block->next = NULL;
+                    _S_bin[bin].last[0] = block;
+                  }
+
+                block = _S_bin[bin].first[0];
+
+                /*
+                 * Remove from list and count down the available counter on
+                 * global pool 0.
+                 */
+                _S_bin[bin].first[0] = _S_bin[bin].first[0]->next;
+                _S_bin[bin].free[0]--;
+
+                __gthread_mutex_unlock(_S_bin[bin].mutex);
+
+                /*
+                 * Now that we have removed the block from the global
+                 * freelist we can change owner and update the used
+                 * counter for this thread without locking.
+                 */
+                block->thread_id = thread_id;
+                _S_bin[bin].used[thread_id]++;
+              }
+            else
+#endif
+              {
+                _S_bin[bin].first[0] = (block_record*)malloc(_S_chunk_size);
+
+                if (!_S_bin[bin].first[0]) 
+                  __throw_bad_alloc();
+
+                size_t bin_t = 1 << bin;
+                size_t block_count = 
+                  _S_chunk_size / (bin_t + sizeof(block_record));
+
+                _S_bin[bin].free[0] = block_count;
+
+                block_count--;
+                block = _S_bin[bin].first[0];
+
+                while (block_count > 0)
+                  {
+                    block->next = (block_record*)((char*)block + 
+                                  (bin_t + sizeof(block_record)));
+                    block = block->next;
+                    block_count--;
+                  }
+
+                block->next = NULL;
+                _S_bin[bin].last[0] = block;
+
+                block = _S_bin[bin].first[0];
+
+                /*
+                 * Remove from list and count down the available counter on
+                 * global pool 0 and increase it's used counter.
+                 */
+                _S_bin[bin].first[0] = _S_bin[bin].first[0]->next;
+                _S_bin[bin].free[0]--;
+                _S_bin[bin].used[0]++;
+              }
+          }  
+        else
+          {
+            /*
+             * "Default" operation - we have blocks on our own freelist
+             * grab the first record and update the counters.
+             */
+            block = _S_bin[bin].first[thread_id];
+
+            _S_bin[bin].first[thread_id] = _S_bin[bin].first[thread_id]->next;
+            _S_bin[bin].free[thread_id]--;
+            _S_bin[bin].used[thread_id]++;
+          }
+
+        return (void*)((char*)block + sizeof(block_record));
+      }
+
+      static void
+      deallocate(void* __p, size_t __n)
+      {
+        /*
+         * Requests larger than _S_max_bytes are handled by
+         * malloc/free directly
+         */
+        if (__n > _S_max_bytes)
+          {
+            free(__p);
+            return;
+          }
+
+        /*
+         * Round up to power of 2 and figure out which bin to use
+         */
+        size_t bin = _S_binmap[__n];
+
+#ifdef __GTHREADS
+        size_t thread_id = _S_get_thread_id();
+#else
+        size_t thread_id = 0;
+#endif
+
+        block_record* block = (block_record*)((char*)__p 
+                                             - sizeof(block_record));
+
+        /*
+         * This block will always be at the back of a list and thus
+         * we set its next pointer to NULL.
+         */
+        block->next = NULL;
+
+#ifdef __GTHREADS
+        if (__gthread_active_p())
+          {
+            /*
+             * Calculate the number of records to remove from our freelist
+             */
+            int remove = _S_bin[bin].free[thread_id] - 
+                         (_S_bin[bin].used[thread_id] / _S_freelist_headroom);
+
+            /*
+             * The calculation above will almost always tell us to
+             * remove one or two records at a time, but this creates
+             * too much contention when locking and therefore we
+             * wait until the number of records is "high enough".
+             */
+            if (remove > (int)(100 * (_S_no_of_bins - bin)) && 
+                remove > (int)(_S_bin[bin].free[thread_id] / 
+                               _S_freelist_headroom))
+              {
+                __gthread_mutex_lock(_S_bin[bin].mutex);
+
+                while (remove > 0)
+                  {
+                    if (_S_bin[bin].first[0] == NULL)
+                      _S_bin[bin].first[0] = _S_bin[bin].first[thread_id];
+                    else
+                      _S_bin[bin].last[0]->next = _S_bin[bin].first[thread_id];
+
+                    _S_bin[bin].last[0] = _S_bin[bin].first[thread_id];
+
+                    _S_bin[bin].first[thread_id] = 
+                      _S_bin[bin].first[thread_id]->next;
+
+                    _S_bin[bin].free[0]++;
+                    _S_bin[bin].free[thread_id]--;
+
+                    remove--;
+                  }
+
+                _S_bin[bin].last[0]->next = NULL;
+
+                __gthread_mutex_unlock(_S_bin[bin].mutex);
+              }
+
+            /*
+             * Did we allocate this block?
+             * - Yes, return it to our freelist
+             * - No, return it to global pool
+             */
+            if (thread_id == block->thread_id)
+              {
+                if (_S_bin[bin].first[thread_id] == NULL)
+                  _S_bin[bin].first[thread_id] = block;
+                else
+                  _S_bin[bin].last[thread_id]->next = block;
+
+                _S_bin[bin].last[thread_id] = block;
+
+                _S_bin[bin].free[thread_id]++;
+                _S_bin[bin].used[thread_id]--;
+              }
+            else
+              {
+                __gthread_mutex_lock(_S_bin[bin].mutex);
+
+                if (_S_bin[bin].first[0] == NULL)
+                  _S_bin[bin].first[0] = block;
+                else
+                  _S_bin[bin].last[0]->next = block;
+
+                _S_bin[bin].last[0] = block;
+
+                _S_bin[bin].free[0]++;
+                _S_bin[bin].used[block->thread_id]--;
+
+                __gthread_mutex_unlock(_S_bin[bin].mutex);
+              }
+          }
+        else
+#endif
+          {
+            /*
+             * Single threaded application - return to global pool
+             */
+            if (_S_bin[bin].first[0] == NULL)
+              _S_bin[bin].first[0] = block;
+            else
+              _S_bin[bin].last[0]->next = block;
+
+            _S_bin[bin].last[0] = block;
+
+            _S_bin[bin].free[0]++;
+            _S_bin[bin].used[0]--;
+          }
+      }
+    };
+
+  template<int __inst>
+    void
+    __mt_alloc<__inst>::
+    _S_init()
+    {
+      /*
+       * Calculate the number of bins required based on _S_max_bytes,
+       * _S_no_of_bins is initialized to 1 below.
+       */
+      {
+        size_t bin_t = 1;
+        while (_S_max_bytes > bin_t)
+          {
+            bin_t = bin_t << 1;
+            _S_no_of_bins++;
+          }
+      }
+
+      /*
+       * Setup the bin map for quick lookup of the relevant bin
+       */
+      _S_binmap = (binmap_type*)
+        malloc ((_S_max_bytes + 1) * sizeof(binmap_type));
+
+      if (!_S_binmap) 
+        __throw_bad_alloc();
+
+      binmap_type* bp_t = _S_binmap;
+      binmap_type bin_max_t = 1;
+      binmap_type bin_t = 0;
+      for (binmap_type ct = 0; ct <= _S_max_bytes; ct++)
+        {
+          if (ct > bin_max_t)
+            {
+              bin_max_t <<= 1;
+              bin_t++;
+            }
+          *bp_t++ = bin_t;
+        }
+
+      /*
+       * If __gthread_active_p() create and initialize the list of
+       * free thread ids. Single threaded applications use thread id 0
+       * directly and have no need for this.
+       */
+#ifdef __GTHREADS
+      if (__gthread_active_p())
+        {
+          _S_thread_freelist_first = 
+            (thread_record*)malloc(sizeof(thread_record) * _S_max_threads);
+
+          if (!_S_thread_freelist_first) 
+            __throw_bad_alloc();
+
+          /*
+           * NOTE! The first assignable thread id is 1 since the global 
+           * pool uses id 0
+           */
+          size_t i;
+          for (i = 1; i < _S_max_threads; i++)
+            {
+              _S_thread_freelist_first[i - 1].next = 
+                &_S_thread_freelist_first[i];
+
+              _S_thread_freelist_first[i - 1].id = i;
+            }
+
+          /*
+           * Set last record and pointer to this
+           */
+          _S_thread_freelist_first[i - 1].next = NULL;
+          _S_thread_freelist_first[i - 1].id = i;
+          _S_thread_freelist_last = &_S_thread_freelist_first[i - 1];
+
+          /*
+           * Initialize per thread key to hold pointer to
+           * _S_thread_freelist NOTE! Here's an ugly workaround - if
+           * _S_thread_key_destr is not explicitly called at least
+           * once it won't be linked into the application. This is the
+           * behavior of template methods and __gthread_key_create()
+           * takes only a pointer to the function and does not cause
+           * the compiler to create an instance.
+           */
+          _S_thread_key_destr(NULL);
+          __gthread_key_create(&_S_thread_key, _S_thread_key_destr);
+        }
+#endif
+
+      /*
+       * Initialize _S_bin and its members
+       */
+      _S_bin = (bin_record*)malloc(sizeof(bin_record) * _S_no_of_bins);
+
+      if (!_S_bin) 
+        __throw_bad_alloc();
+
+      for (size_t bin = 0; bin < _S_no_of_bins; bin++)
+        {
+          _S_bin[bin].first = (block_record**)
+            malloc(sizeof(block_record*) * (_S_max_threads + 1));
+
+          if (!_S_bin[bin].first) 
+            __throw_bad_alloc();
+
+          _S_bin[bin].last = (block_record**)
+            malloc(sizeof(block_record*) * (_S_max_threads + 1));
+
+          if (!_S_bin[bin].last) 
+            __throw_bad_alloc();
+
+          _S_bin[bin].free = (size_t*)
+            malloc(sizeof(size_t) * (_S_max_threads + 1));
+
+          if (!_S_bin[bin].free) 
+            __throw_bad_alloc();
+
+          _S_bin[bin].used = (size_t*)
+            malloc(sizeof(size_t) * (_S_max_threads + 1));
+
+          if (!_S_bin[bin].used) 
+            __throw_bad_alloc();
+
+          /*
+           * Ugly workaround of what at the time of writing seems to be
+           * a parser problem - see PR c++/9779 for more info.
+           */
+#ifdef __GTHREADS
+          size_t s = sizeof(__gthread_mutex_t); 
+          _S_bin[bin].mutex = (__gthread_mutex_t*)malloc(s);
+
+          if (!_S_bin[bin].mutex) 
+            __throw_bad_alloc();
+
+          /*
+           * This is not only ugly - it's extremly non-portable!
+           * However gthr.h does not currently provide a
+           * __gthread_mutex_init() call. The correct solution to
+           * this problem needs to be discussed.
+           */
+          pthread_mutex_init(_S_bin[bin].mutex, NULL);
+#endif
+
+          for (size_t thread = 0; thread <= _S_max_threads; thread++)
+            {
+              _S_bin[bin].first[thread] = NULL;
+              _S_bin[bin].last[thread] = NULL;
+              _S_bin[bin].free[thread] = 0;
+              _S_bin[bin].used[thread] = 0;
+            }
+        }
+
+        _S_initialized = true;
+    }
+
+#ifdef __GTHREADS
+  template<int __inst>
+    void
+    __mt_alloc<__inst>::
+    _S_thread_key_destr(void* freelist_pos)
+    {
+      /*
+       * This is due to the ugly workaround mentioned in _S_init()
+       */
+      if (freelist_pos == NULL)
+        return;
+
+      /*
+       * If the thread - when it dies - still have records on its
+       * freelist we return them to the global pool here.
+       */
+      for (size_t bin = 0; bin < _S_no_of_bins; bin++)
+        {
+          block_record* block = 
+            _S_bin[bin].first[((thread_record*)freelist_pos)->id];
+
+          if (block != NULL)
+            {
+              __gthread_mutex_lock(_S_bin[bin].mutex);
+
+              while (block != NULL)
+                {
+                  if (_S_bin[bin].first[0] == NULL)
+                    _S_bin[bin].first[0] = block;
+                  else
+                    _S_bin[bin].last[0]->next = block;
+
+                  _S_bin[bin].last[0] = block;
+
+                  block = block->next;
+
+                  _S_bin[bin].free[0]++;
+                }
+
+              _S_bin[bin].last[0]->next = NULL;
+
+              __gthread_mutex_unlock(_S_bin[bin].mutex);
+            }
+        }
+
+      /*
+       * Return this thread id record to thread_freelist
+       */
+      __gthread_mutex_lock(&_S_thread_freelist_mutex);
+
+      _S_thread_freelist_last->next = (thread_record*)freelist_pos;
+      _S_thread_freelist_last = (thread_record*)freelist_pos;
+      _S_thread_freelist_last->next = NULL;
+
+      __gthread_mutex_unlock(&_S_thread_freelist_mutex);
+
+    }
+
+  template<int __inst>
+    size_t
+    __mt_alloc<__inst>::
+    _S_get_thread_id()
+    {
+      /*
+       * If we have thread support and it's active we check the thread
+       * key value and return it's id or if it's not set we take the
+       * first record from _S_thread_freelist and sets the key and
+       * returns it's id.
+       */
+      if (__gthread_active_p())
+        {
+          thread_record* freelist_pos;
+
+          if ((freelist_pos = 
+              (thread_record*)__gthread_getspecific(_S_thread_key)) == NULL)
+            {
+              __gthread_mutex_lock(&_S_thread_freelist_mutex);
+
+              /*
+               * Since _S_max_threads must be larger than the
+               * theoretical max number of threads of the OS the list
+               * can never be empty.
+               */
+              freelist_pos = _S_thread_freelist_first;
+              _S_thread_freelist_first = _S_thread_freelist_first->next;
+
+              __gthread_mutex_unlock(&_S_thread_freelist_mutex);
+
+              __gthread_setspecific(_S_thread_key, (void*)freelist_pos);
+
+              /*
+               * Since thread_ids may/will be reused (espcially in
+               * producer/consumer applications) we make sure that the
+               * list pointers and free counter is reset BUT as the
+               * "old" thread may still be owner of some memory (which
+               * is referred to by other threads and thus not freed)
+               * we don't reset the used counter.
+               */
+              for (size_t bin = 0; bin < _S_no_of_bins; bin++)
+                {
+                  _S_bin[bin].first[freelist_pos->id] = NULL;
+                  _S_bin[bin].last[freelist_pos->id] = NULL;
+                  _S_bin[bin].free[freelist_pos->id] = 0;
+                }
+            } 
+
+          return freelist_pos->id;
+        }
+
+      /*
+       * Otherwise (no thread support or inactive) all requests are
+       * served from the global pool 0.
+       */
+      return 0;
+    }
+
+  template<int __inst> __gthread_once_t
+  __mt_alloc<__inst>::_S_once_mt = __GTHREAD_ONCE_INIT;
+#endif
+
+  template<int __inst> bool
+  __mt_alloc<__inst>::_S_initialized = false;
+
+  template<int __inst> typename __mt_alloc<__inst>::binmap_type*
+  __mt_alloc<__inst>::_S_binmap = NULL;
+
+  /*
+   * Allocation requests (after round-up to power of 2) below this
+   * value will be handled by the allocator. A raw malloc/free() call
+   * will be used for requests larger than this value.
+   */
+  template<int __inst> size_t
+  __mt_alloc<__inst>::_S_max_bytes = 128;
+
+  /*
+   * In order to avoid fragmenting and minimize the number of malloc()
+   * calls we always request new memory using this value. Based on
+   * previous discussions on the libstdc++ mailing list we have
+   * choosen the value below. See
+   * http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
+   */
+  template<int __inst> size_t
+  __mt_alloc<__inst>::_S_chunk_size = 4096 - 4 * sizeof(void*);
+
+  /*
+   * The maximum number of supported threads. Our Linux 2.4.18 reports
+   * 4070 in /proc/sys/kernel/threads-max
+   */
+  template<int __inst> size_t
+  __mt_alloc<__inst>::_S_max_threads = 4096;
+
+  /*
+   * Actual value calculated in _S_init()
+   */
+  template<int __inst> size_t
+  __mt_alloc<__inst>::_S_no_of_bins = 1;
+
+  /*
+   * Each time a deallocation occurs in a threaded application we make
+   * sure that there are no more than _S_freelist_headroom % of used
+   * memory on the freelist. If the number of additional records is
+   * more than _S_freelist_headroom % of the freelist, we move these
+   * records back to the global pool.
+   */
+  template<int __inst> size_t
+  __mt_alloc<__inst>::_S_freelist_headroom = 10;
+
+  /*
+   * Actual initialization in _S_init()
+   */
+#ifdef __GTHREADS
+  template<int __inst> typename __mt_alloc<__inst>::thread_record*
+  __mt_alloc<__inst>::_S_thread_freelist_first = NULL;
+
+  template<int __inst> typename __mt_alloc<__inst>::thread_record*
+  __mt_alloc<__inst>::_S_thread_freelist_last = NULL;
+
+  template<int __inst> __gthread_mutex_t
+  __mt_alloc<__inst>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT;
+
+  /*
+   * Actual initialization in _S_init()
+   */
+  template<int __inst> __gthread_key_t
+  __mt_alloc<__inst>::_S_thread_key;
+#endif
+
+  template<int __inst> typename __mt_alloc<__inst>::bin_record*
+  __mt_alloc<__inst>::_S_bin = NULL;
+
+  template<int __inst>
+    inline bool
+    operator==(const __mt_alloc<__inst>&, const __mt_alloc<__inst>&)
+    { return true; }
+
+  template<int __inst>
+    inline bool
+    operator!=(const __mt_alloc<__inst>&, const __mt_alloc<__inst>&)
+    { return false; }
+} // namespace __gnu_cxx
+
+namespace std
+{
+  template<typename _Tp, int __inst>
+    struct _Alloc_traits<_Tp, __gnu_cxx::__mt_alloc<__inst> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __gnu_cxx:: __mt_alloc<__inst>           base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+
+  template<typename _Tp, typename _Tp1, int __inst>
+    struct _Alloc_traits<_Tp, 
+                         __allocator<_Tp1, __gnu_cxx::__mt_alloc<__inst> > >
+    {
+      static const bool _S_instanceless = true;
+      typedef __gnu_cxx:: __mt_alloc<__inst>           base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+} // namespace std
+
+#endif
+
similarity index 55%
rename from libstdc++-v3/include/bits/stl_pthread_alloc.h
rename to libstdc++-v3/include/ext/new_allocator.h
index 09b7d727af65cab36c7baa430246e7d5fba3ae53..794751d3c13ef0aca9610c82909386ed911decc2 100644 (file)
@@ -1,6 +1,6 @@
-// Wrapper of pthread allocation header -*- C++ -*-
+// Allocators -*- C++ -*-
 
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
-/*
- * Copyright (c) 1996-1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- */
-
-/** @file stl_pthread_alloc.h
- *  This is an internal header file, included by other library headers.
- *  You should not attempt to use it directly.
- */
-
-#ifndef _CPP_BITS_STL_PTHREAD_ALLOC_H
-#define _CPP_BITS_STL_PTHREAD_ALLOC_H 1
-
-#include <bits/pthread_allocimpl.h>
-
-using std::_Pthread_alloc_template;
-using std::pthread_alloc;
-
-#endif /* _CPP_BITS_STL_PTHREAD_ALLOC_H */
-
-// Local Variables:
-// mode:C++
-// End:
+#ifndef _NEW_ALLOCATOR_H
+#define _NEW_ALLOCATOR_H 1
+
+#include <new>
+
+namespace __gnu_cxx
+{
+  /**
+   *  @if maint
+   *  A new-based allocator, as required by the standard.  Allocation and
+   *  deallocation forward to global new and delete.  "SGI" style, minus
+   *  reallocate().
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  class __new_alloc
+  {
+  public:
+    static void*
+    allocate(size_t __n)
+    { return ::operator new(__n); }
+
+    static void
+    deallocate(void* __p, size_t)
+    { ::operator delete(__p); }
+  };
+} // namespace __gnu_cxx
+
+#endif
diff --git a/libstdc++-v3/include/ext/pool_allocator.h b/libstdc++-v3/include/ext/pool_allocator.h
new file mode 100644 (file)
index 0000000..77d354f
--- /dev/null
@@ -0,0 +1,383 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/** @file ext/debug_allocator.h
+ *  This file is a GNU extension to the Standard C++ Library. 
+ *  You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _POOL_ALLOCATOR_H
+#define _POOL_ALLOCATOR_H 1
+
+#include <bits/functexcept.h> 
+#include <bits/stl_threads.h>
+#include <bits/atomicity.h>
+#include <bits/allocator_traits.h>
+#include <ext/new_allocator.h>
+
+namespace __gnu_cxx
+{
+  using std::_STL_mutex_lock;
+  using std::__throw_bad_alloc;
+
+  /**
+   *  @if maint
+   *  Default node allocator.  "SGI" style.  Uses various allocators to
+   *  fulfill underlying requests (and makes as few requests as possible
+   *  when in default high-speed pool mode).
+   *
+   *  Important implementation properties:
+   *  0. If globally mandated, then allocate objects from __new_alloc
+   *  1. If the clients request an object of size > _S_max_bytes, the resulting
+   *     object will be obtained directly from __new_alloc
+   *  2. In all other cases, we allocate an object of size exactly
+   *     _S_round_up(requested_size).  Thus the client has enough size
+   *     information that we can return the object to the proper free list
+   *     without permanently losing part of the object.
+   *
+   *  The first template parameter specifies whether more than one thread may
+   *  use this allocator.  It is safe to allocate an object from one instance
+   *  of a default_alloc and deallocate it with another one.  This effectively
+   *  transfers its ownership to the second one.  This may have undesirable
+   *  effects on reference locality.
+   *
+   *  The second parameter is unused and serves only to allow the creation of
+   *  multiple default_alloc instances.  Note that containers built on different
+   *  allocator instances have different types, limiting the utility of this
+   *  approach.  If you do not wish to share the free lists with the main
+   *  default_alloc instance, instantiate this with a non-zero __inst.
+   *
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<bool __threads, int __inst>
+    class __pool_alloc
+    {
+    private:
+      enum {_S_align = 8};
+      enum {_S_max_bytes = 128};
+      enum {_S_freelists = _S_max_bytes / _S_align};
+
+      union _Obj
+      {
+        union _Obj* _M_free_list_link;
+        char        _M_client_data[1];    // The client sees this.
+      };
+
+      static _Obj* volatile         _S_free_list[_S_freelists];
+
+      // Chunk allocation state.
+      static char*                  _S_start_free;
+      static char*                  _S_end_free;
+      static size_t                 _S_heap_size;
+
+      static _STL_mutex_lock        _S_lock;
+      static _Atomic_word          _S_force_new;
+
+      static size_t
+      _S_round_up(size_t __bytes)
+      { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); }
+
+      static size_t
+      _S_freelist_index(size_t __bytes)
+      { return ((__bytes + (size_t)_S_align - 1)/(size_t)_S_align - 1); }
+
+      // Returns an object of size __n, and optionally adds to size __n
+      // free list.
+      static void*
+      _S_refill(size_t __n);
+
+      // Allocates a chunk for nobjs of size size.  nobjs may be reduced
+      // if it is inconvenient to allocate the requested number.
+      static char*
+      _S_chunk_alloc(size_t __size, int& __nobjs);
+
+      // It would be nice to use _STL_auto_lock here.  But we need a
+      // test whether threads are in use.
+      struct _Lock
+      {
+        _Lock() { if (__threads) _S_lock._M_acquire_lock(); }
+        ~_Lock() { if (__threads) _S_lock._M_release_lock(); }
+      } __attribute__ ((__unused__));
+      friend struct _Lock;
+
+    public:
+      // __n must be > 0
+      static void*
+      allocate(size_t __n)
+      {
+       void* __ret = 0;
+
+       // If there is a race through here, assume answer from getenv
+       // will resolve in same direction.  Inspired by techniques
+       // to efficiently support threading found in basic_string.h.
+       if (_S_force_new == 0)
+         {
+           if (getenv("GLIBCPP_FORCE_NEW"))
+             __atomic_add(&_S_force_new, 1);
+           else
+             __atomic_add(&_S_force_new, -1);
+         }
+
+       if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
+         __ret = __new_alloc::allocate(__n);
+       else
+         {
+           _Obj* volatile* __my_free_list = _S_free_list
+             + _S_freelist_index(__n);
+           // Acquire the lock here with a constructor call.  This
+           // ensures that it is released in exit or during stack
+           // unwinding.
+           _Lock __lock_instance;
+           _Obj* __restrict__ __result = *__my_free_list;
+           if (__builtin_expect(__result == 0, 0))
+             __ret = _S_refill(_S_round_up(__n));
+           else
+             {
+               *__my_free_list = __result -> _M_free_list_link;
+               __ret = __result;
+             }     
+           if (__builtin_expect(__ret == 0, 0))
+             __throw_bad_alloc();
+         }
+       return __ret;
+      }
+
+      // __p may not be 0
+      static void
+      deallocate(void* __p, size_t __n)
+      {
+       if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
+         __new_alloc::deallocate(__p, __n);
+       else
+         {
+           _Obj* volatile*  __my_free_list = _S_free_list
+             + _S_freelist_index(__n);
+           _Obj* __q = (_Obj*)__p;
+
+           // Acquire the lock here with a constructor call.  This
+           // ensures that it is released in exit or during stack
+           // unwinding.
+           _Lock __lock_instance;
+           __q -> _M_free_list_link = *__my_free_list;
+           *__my_free_list = __q;
+         }
+      }
+    };
+
+  template<bool __threads, int __inst> _Atomic_word
+  __pool_alloc<__threads, __inst>::_S_force_new = 0;
+
+  template<bool __threads, int __inst>
+    inline bool
+    operator==(const __pool_alloc<__threads,__inst>&, 
+              const __pool_alloc<__threads,__inst>&)
+    { return true; }
+
+  template<bool __threads, int __inst>
+    inline bool
+    operator!=(const __pool_alloc<__threads,__inst>&,
+               const __pool_alloc<__threads,__inst>&)
+    { return false; }
+
+
+  // We allocate memory in large chunks in order to avoid fragmenting the
+  // heap too much.  We assume that __size is properly aligned.  We hold
+  // the allocation lock.
+  template<bool __threads, int __inst>
+    char*
+    __pool_alloc<__threads, __inst>::
+    _S_chunk_alloc(size_t __size, int& __nobjs)
+    {
+      char* __result;
+      size_t __total_bytes = __size * __nobjs;
+      size_t __bytes_left = _S_end_free - _S_start_free;
+
+      if (__bytes_left >= __total_bytes)
+        {
+          __result = _S_start_free;
+          _S_start_free += __total_bytes;
+          return __result ;
+        }
+      else if (__bytes_left >= __size)
+        {
+          __nobjs = (int)(__bytes_left/__size);
+          __total_bytes = __size * __nobjs;
+          __result = _S_start_free;
+          _S_start_free += __total_bytes;
+          return __result;
+        }
+      else
+        {
+          size_t __bytes_to_get =
+            2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
+          // Try to make use of the left-over piece.
+          if (__bytes_left > 0)
+            {
+              _Obj* volatile* __my_free_list =
+                _S_free_list + _S_freelist_index(__bytes_left);
+
+              ((_Obj*)(void*)_S_start_free) -> _M_free_list_link = *__my_free_list;
+              *__my_free_list = (_Obj*)(void*)_S_start_free;
+            }
+          _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
+          if (_S_start_free == 0)
+            {
+              size_t __i;
+              _Obj* volatile* __my_free_list;
+              _Obj* __p;
+              // Try to make do with what we have.  That can't hurt.  We
+              // do not try smaller requests, since that tends to result
+              // in disaster on multi-process machines.
+              __i = __size;
+              for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
+                {
+                  __my_free_list = _S_free_list + _S_freelist_index(__i);
+                  __p = *__my_free_list;
+                  if (__p != 0)
+                    {
+                      *__my_free_list = __p -> _M_free_list_link;
+                      _S_start_free = (char*)__p;
+                      _S_end_free = _S_start_free + __i;
+                      return _S_chunk_alloc(__size, __nobjs);
+                      // Any leftover piece will eventually make it to the
+                      // right free list.
+                    }
+                }
+              _S_end_free = 0;        // In case of exception.
+              _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
+              // This should either throw an exception or remedy the situation.
+              // Thus we assume it succeeded.
+            }
+          _S_heap_size += __bytes_to_get;
+          _S_end_free = _S_start_free + __bytes_to_get;
+          return _S_chunk_alloc(__size, __nobjs);
+        }
+    }
+
+
+  // Returns an object of size __n, and optionally adds to "size
+  // __n"'s free list.  We assume that __n is properly aligned.  We
+  // hold the allocation lock.
+  template<bool __threads, int __inst>
+    void*
+    __pool_alloc<__threads, __inst>::_S_refill(size_t __n)
+    {
+      int __nobjs = 20;
+      char* __chunk = _S_chunk_alloc(__n, __nobjs);
+      _Obj* volatile* __my_free_list;
+      _Obj* __result;
+      _Obj* __current_obj;
+      _Obj* __next_obj;
+      int __i;
+
+      if (1 == __nobjs)
+        return __chunk;
+      __my_free_list = _S_free_list + _S_freelist_index(__n);
+
+      // Build free list in chunk.
+      __result = (_Obj*)(void*)__chunk;
+      *__my_free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
+      for (__i = 1; ; __i++)
+        {
+         __current_obj = __next_obj;
+          __next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
+         if (__nobjs - 1 == __i)
+           {
+             __current_obj -> _M_free_list_link = 0;
+             break;
+           }
+         else
+           __current_obj -> _M_free_list_link = __next_obj;
+       }
+      return __result;
+    }
+
+
+  template<bool __threads, int __inst>
+    _STL_mutex_lock
+    __pool_alloc<__threads, __inst>::_S_lock __STL_MUTEX_INITIALIZER;
+
+  template<bool __threads, int __inst>
+    char* __pool_alloc<__threads, __inst>::_S_start_free = 0;
+
+  template<bool __threads, int __inst>
+    char* __pool_alloc<__threads, __inst>::_S_end_free = 0;
+
+  template<bool __threads, int __inst>
+    size_t __pool_alloc<__threads, __inst>::_S_heap_size = 0;
+
+  template<bool __threads, int __inst>
+    typename __pool_alloc<__threads, __inst>::_Obj* volatile
+    __pool_alloc<__threads, __inst>::_S_free_list[_S_freelists];
+} // namespace __gnu_cxx
+
+namespace std
+{
+  //@{
+  /// Versions for the predefined "SGI" style allocators.
+  template<typename _Tp, bool __thr, int __inst>
+    struct _Alloc_traits<_Tp, __gnu_cxx::__pool_alloc<__thr, __inst> >
+    {
+      static const bool _S_instanceless = true;      
+      typedef __gnu_cxx::__pool_alloc<__thr, __inst>   base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+  //@}
+
+  //@{
+  /// Versions for the __allocator adaptor used with the predefined
+  /// "SGI" style allocators.
+  template<typename _Tp, typename _Tp1, bool __thr, int __inst>
+    struct _Alloc_traits<_Tp, __allocator<_Tp1, 
+                                    __gnu_cxx::__pool_alloc<__thr, __inst> > >
+    {
+      static const bool _S_instanceless = true;
+      typedef __gnu_cxx::__pool_alloc<__thr, __inst>   base_alloc_type;
+      typedef __simple_alloc<_Tp, base_alloc_type>     _Alloc_type;
+      typedef __allocator<_Tp, base_alloc_type>                allocator_type;
+    };
+  //@}
+} // namespace std
+
+#endif
index d621ba84aa0fe5921a02f482135328746a1a60fe..9ba261845b35738a78e27dcba0330d2e3cbd3f74 100644 (file)
@@ -53,7 +53,7 @@
 #include <bits/stl_algo.h>
 #include <bits/stl_function.h>
 #include <bits/stl_numeric.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <ext/hash_fun.h>
index 780e2c2d69309c655d71282cac99bdd0b12e0f9a..875f7604de57a5f85e6463f3446b2b08af5658e3 100644 (file)
@@ -51,7 +51,7 @@
 #define _SLIST 1
 
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/concept_check.h>
index 921c25fa4931bd90ff76baf2f692f66d0dbc9812..774d334e8d7149e5e546a6b5318cfaa9439b6f54 100644 (file)
@@ -65,7 +65,7 @@
 
 #include <bits/functexcept.h>
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_deque.h>
index 84523ad8e4fad1ed69842036e841d2408afa5278..61c6dfa88eb10b091010cd7e7e47d672997f8fd2 100644 (file)
@@ -65,7 +65,7 @@
 
 #include <bits/functexcept.h>
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_list.h>
index 47c3ede8995d477a3658f7d1244d40eb19345fe5..b508351c8b5bbb9c6d007a76588f7b692a3e193c 100644 (file)
@@ -52,7 +52,7 @@
 #pragma GCC system_header
 
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_iterator_base_types.h> //for iterator_traits
 #include <bits/stl_uninitialized.h>
index 60636e6f0dd8abf34d3594494bf4f022ce3715cc..33eb944972714da4b0dd34c3dadaff030bddbd58 100644 (file)
@@ -65,7 +65,7 @@
 #include <bits/c++config.h>
 #include <bits/functexcept.h>
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_vector.h>
index ddae7e78fc68a13db20102e3edcb5e69a713bec6..fb111d4d4df89bc0dc010aaead7c931f6fc39f4a 100644 (file)
@@ -64,7 +64,7 @@
 #pragma GCC system_header
 
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_deque.h>
index 5738ef7ade89b6e9c5eb8bd1e5a9919dd8cafe4c..5f700495b4c39458d4706a55c284c13b5cc9291b 100644 (file)
@@ -65,7 +65,7 @@
 
 #include <bits/functexcept.h>
 #include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_vector.h>
index a788cb9369bd68004f3f8837143d9172fd64a98d..6876e288925aa344fc4415e142d487fa59ef8ee7 100644 (file)
@@ -117,6 +117,7 @@ basic_file.cc: ${glibcpp_srcdir}/@BASIC_FILE_CC@
 
 # Sources present in the src directory.
 sources = \
+       allocator-inst.cc \
        codecvt.cc \
        complex_io.cc \
        concept-inst.cc \
@@ -137,7 +138,6 @@ sources = \
        ostream-inst.cc \
        sstream-inst.cc \
        stdexcept.cc \
-       stl-inst.cc \
        streambuf-inst.cc \
        string-inst.cc \
        strstream.cc \
index 8e01572be71a7be700b31af0af5fe6ac17426310..5662b6c502fda872f16f5c5a22eee0a00c5e2e96 100644 (file)
@@ -121,6 +121,7 @@ enable_shared = @enable_shared@
 enable_static = @enable_static@
 glibcpp_CXX = @glibcpp_CXX@
 glibcpp_MOFILES = @glibcpp_MOFILES@
+glibcpp_PCHFLAGS = @glibcpp_PCHFLAGS@
 glibcpp_POFILES = @glibcpp_POFILES@
 glibcpp_basedir = @glibcpp_basedir@
 glibcpp_localedir = @glibcpp_localedir@
@@ -199,6 +200,7 @@ target_sources_extra = \
 
 # Sources present in the src directory.
 sources = \
+       allocator-inst.cc \
        codecvt.cc \
        complex_io.cc \
        concept-inst.cc \
@@ -219,7 +221,6 @@ sources = \
        ostream-inst.cc \
        sstream-inst.cc \
        stdexcept.cc \
-       stl-inst.cc \
        streambuf-inst.cc \
        string-inst.cc \
        strstream.cc \
@@ -304,15 +305,15 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I..
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-libstdc___la_OBJECTS =  codecvt.lo complex_io.lo concept-inst.lo \
-ctype.lo demangle.lo ext-inst.lo fstream-inst.lo functexcept.lo \
-globals.lo io-inst.lo ios.lo istream-inst.lo limits.lo locale.lo \
-locale-inst.lo localename.lo misc-inst.lo ostream-inst.lo \
-sstream-inst.lo stdexcept.lo stl-inst.lo streambuf-inst.lo \
-string-inst.lo strstream.lo valarray-inst.lo wstring-inst.lo \
-codecvt_members.lo collate_members.lo ctype_members.lo \
-messages_members.lo monetary_members.lo numeric_members.lo \
-time_members.lo basic_file.lo c++locale.lo
+libstdc___la_OBJECTS =  allocator-inst.lo codecvt.lo complex_io.lo \
+concept-inst.lo ctype.lo demangle.lo ext-inst.lo fstream-inst.lo \
+functexcept.lo globals.lo io-inst.lo ios.lo istream-inst.lo limits.lo \
+locale.lo locale-inst.lo localename.lo misc-inst.lo ostream-inst.lo \
+sstream-inst.lo stdexcept.lo streambuf-inst.lo string-inst.lo \
+strstream.lo valarray-inst.lo wstring-inst.lo codecvt_members.lo \
+collate_members.lo ctype_members.lo messages_members.lo \
+monetary_members.lo numeric_members.lo time_members.lo basic_file.lo \
+c++locale.lo
 CXXFLAGS = @CXXFLAGS@
 CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
 CXXLD = $(CXX)
diff --git a/libstdc++-v3/src/allocator-inst.cc b/libstdc++-v3/src/allocator-inst.cc
new file mode 100644 (file)
index 0000000..da8aeda
--- /dev/null
@@ -0,0 +1,41 @@
+// Explicit instantiation file.
+
+// Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882:
+//
+
+#include <bits/c++config.h>
+#include <memory>
+
+namespace std
+{
+  template class allocator<char>;
+  template class allocator<wchar_t>;
+} // namespace std
index 3102c91bcdeda98eec48b6874106454d7c46931d..34188c47328a07b3658b4603bade80f9f1545ed6 100644 (file)
@@ -1,6 +1,6 @@
 // 2001-11-25  Phil Edwards  <pme@gcc.gnu.org>
 //
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 
 // 20.4.1.1 allocator members
 
-#include <memory>
 #include <cstdlib>
+#include <memory>
+#include <ext/pool_allocator.h>
+#include <ext/debug_allocator.h>
+#include <ext/malloc_allocator.h>
 #include <testsuite_hooks.h>
 
-typedef std::__malloc_alloc<3>             weird_alloc;
-template class std::__malloc_alloc<3>;
-
-typedef std::__debug_alloc<weird_alloc>             debug_weird_alloc;
-template class std::__debug_alloc<weird_alloc>;
-
-typedef std::__pool_alloc<true, 3>      unshared_normal_alloc;
-template class std::__pool_alloc<true, 3>;
-
-typedef std::__pool_alloc<false, 3>     unshared_singlethreaded;
-template class std::__pool_alloc<false, 3>;
+using __gnu_cxx::__malloc_alloc;
+using __gnu_cxx::__debug_alloc;
+using __gnu_cxx::__pool_alloc;
 
-//std::malloc_alloc test_malloc_alloc;
+template class __malloc_alloc<3>;
+template class __debug_alloc<__malloc_alloc<3> >;
+template class __pool_alloc<true, 3>;
+template class __pool_alloc<false, 3>;
 
 struct big
 {
-    long f[15];
+  long f[15];
 };
 
 
@@ -63,32 +61,32 @@ operator delete(void *v) throw()
   return std::free(v);
 }
 
-
-template <typename arbitrary_SGIstyle_allocator,
-          bool uses_global_new_and_delete>
-void test()
+template<typename Alloc, bool uses_global_new_and_delete>
+void check_allocator()
 {
+  bool test = true;
   new_called = false;
   delete_called = false;
   requested = 0;
 
-  std::__allocator<big, arbitrary_SGIstyle_allocator>   a;
+  std::__allocator<big, Alloc>   a;
   big *p = a.allocate(10);
-  if (uses_global_new_and_delete)  VERIFY (requested >= (10*15*sizeof(long)));
+  if (uses_global_new_and_delete)  
+    VERIFY( requested >= (10 * 15 * sizeof(long)) );
+
   // Touch the far end of supposedly-allocated memory to check that we got
   // all of it.  Why "3"?  Because it's my favorite integer between e and pi.
   p[9].f[14] = 3;
-  VERIFY (new_called == uses_global_new_and_delete );
+  VERIFYnew_called == uses_global_new_and_delete );
   a.deallocate(p,10);
-  VERIFY (delete_called == uses_global_new_and_delete );
+  VERIFYdelete_called == uses_global_new_and_delete );
 }
 
-
 // These just help tracking down error messages.
-void test01() { test<weird_alloc,false>(); }
-void test02() { test<debug_weird_alloc,false>(); }
-void test03() { test<unshared_normal_alloc,true>(); }
-void test04() { test<unshared_singlethreaded,true>(); }
+void test01() { check_allocator<__malloc_alloc<3>, false>(); }
+void test02() { check_allocator<__debug_alloc<__malloc_alloc<3> >, false>(); }
+void test03() { check_allocator<__pool_alloc<true, 3>, true>(); }
+void test04() { check_allocator<__pool_alloc<false, 3>, true>(); }
 
 int main()
 {
@@ -96,7 +94,6 @@ int main()
   test02();
   test03();
   test04();
-
   return 0;
 }
 
index a2c1233302d3f32f056318f9be5a9154e3be5c9c..52f6028bd123ff3257873ad83e412ce7b0421e7b 100644 (file)
@@ -1,6 +1,6 @@
 // 1999-06-23 bkoz 
 
-// Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2001, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 #include <ext/rb_tree>
 #include <ext/rope>
 #include <ext/slist>
+#include <ext/debug_allocator.h>
+#include <ext/malloc_allocator.h>
+#include <ext/mt_allocator.h>
+#include <ext/pool_allocator.h>
+#include <ext/stdio_filebuf.h>
+#include <ext/stdio_sync_filebuf.h>
 
 int main() { }