stl_list.h: Rename guard macro consistently with file name.
[platform/upstream/gcc.git] / libstdc++-v3 / include / bits / stl_tempbuf.h
index 66ce240..21adc70 100644 (file)
@@ -1,6 +1,7 @@
 // Temporary buffer implementation -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -15,7 +16,7 @@
 
 // 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,
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 // USA.
 
 // As a special exception, you may use this file as part of a free software
  *  You should not attempt to use it directly.
  */
 
-#ifndef _TEMPBUF_H
-#define _TEMPBUF_H 1
+#ifndef _STL_TEMPBUF_H
+#define _STL_TEMPBUF_H 1
+
+#include <bits/stl_algobase.h>
+#include <bits/stl_construct.h>
+#include <bits/stl_uninitialized.h>
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
+  /**
+   *  @if maint
+   *  This is a helper function.  The unused second parameter exists to
+   *  permit the real get_temporary_buffer to use template parameter deduction.
+   *  @endif
+   */
+  template<typename _Tp>
+    pair<_Tp*, ptrdiff_t>
+    __get_temporary_buffer(ptrdiff_t __len, _Tp*)
+    {
+      const ptrdiff_t __max =
+       __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
+      if (__len > __max)
+       __len = __max;
+      
+      while (__len > 0) 
+       {
+         _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp), 
+                                                       std::nothrow));
+         if (__tmp != 0)
+           return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
+         __len /= 2;
+       }
+      return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
+    }
+
+  /**
+   *  @brief Allocates a temporary buffer.
+   *  @param  len  The number of objects of type Tp.
+   *  @return See full description.
+   *
+   *  Reinventing the wheel, but this time with prettier spokes!
+   *
+   *  This function tries to obtain storage for @c len adjacent Tp
+   *  objects.  The objects themselves are not constructed, of course.
+   *  A pair<> is returned containing "the buffer s address and
+   *  capacity (in the units of sizeof(Tp)), or a pair of 0 values if
+   *  no storage can be obtained."  Note that the capacity obtained
+   *  may be less than that requested if the memory is unavailable;
+   *  you should compare len with the .second return value.
+   *
+   * Provides the nothrow exception guarantee.
+   */
+  template<typename _Tp>
+    inline pair<_Tp*, ptrdiff_t>
+    get_temporary_buffer(ptrdiff_t __len)
+    { return std::__get_temporary_buffer(__len, static_cast<_Tp*>(0)); }
+
+  /**
+   *  @brief The companion to get_temporary_buffer().
+   *  @param  p  A buffer previously allocated by get_temporary_buffer.
+   *  @return   None.
+   *
+   *  Frees the memory pointed to by p.
+   */
+  template<typename _Tp>
+    inline void
+    return_temporary_buffer(_Tp* __p)
+    { ::operator delete(__p, std::nothrow); }
 
-#include <memory>
 
-namespace std
-{
   /**
    *  @if maint
    *  This class is used in two places: stl_algo.h and ext/memory,
@@ -78,7 +142,7 @@ namespace std
       // concept requirements
       __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
 
-       public:
+    public:
       typedef _Tp         value_type;
       typedef value_type* pointer;
       typedef pointer     iterator;
@@ -89,13 +153,6 @@ namespace std
       size_type  _M_len;
       pointer    _M_buffer;
 
-      void
-      _M_initialize_buffer(const _Tp&, __true_type) { }
-
-      void
-      _M_initialize_buffer(const _Tp& val, __false_type)
-      { std::uninitialized_fill_n(_M_buffer, _M_len, val); }
-
     public:
       /// As per Table mumble.
       size_type
@@ -137,24 +194,20 @@ namespace std
       operator=(const _Temporary_buffer&);
     };
 
-
   template<typename _ForwardIterator, typename _Tp>
     _Temporary_buffer<_ForwardIterator, _Tp>::
     _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
     : _M_original_len(std::distance(__first, __last)),
       _M_len(0), _M_buffer(0)
     {
-      // Workaround for a __type_traits bug in the pre-7.3 compiler.
-      typedef typename std::__is_scalar<_Tp>::__type _Trivial;
-
       try
        {
-         pair<pointer, size_type> __p(get_temporary_buffer<
-                                      value_type>(_M_original_len));
+         std::pair<pointer, size_type> __p(std::get_temporary_buffer<
+                                           value_type>(_M_original_len));
          _M_buffer = __p.first;
          _M_len = __p.second;
-         if (_M_len > 0)
-           _M_initialize_buffer(*__first, _Trivial());
+         if (!__is_pod(_Tp) && _M_len > 0)
+           std::uninitialized_fill_n(_M_buffer, _M_len, *__first);
        }
       catch(...)
        {
@@ -164,7 +217,8 @@ namespace std
          __throw_exception_again;
        }
     }
-} // namespace std
 
-#endif /* _TEMPBUF_H */
+_GLIBCXX_END_NAMESPACE
+
+#endif /* _STL_TEMPBUF_H */