]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/bits/stl_tempbuf.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / stl_tempbuf.h
index 46c733feb5c3b845f01e1015399ab0b30e53cf40..03b4cd29ffed6b74951e080739e282136f11bd6b 100644 (file)
@@ -1,12 +1,11 @@
 // Temporary buffer implementation -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
-// Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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)
+// Free Software Foundation; either version 3, or (at your option)
 // any later version.
 
 // This library is distributed in the hope that it will be useful,
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
 
-// 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.
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
 
 /*
  *
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-/** @file stl_tempbuf.h
+/** @file bits/stl_tempbuf.h
  *  This is an internal header file, included by other library headers.
- *  You should not attempt to use it directly.
+ *  Do not attempt to use it directly. @headername{memory}
  */
 
-#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)
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /**
-   *  @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
+   *  @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 <em>the buffer s address and
+   *  capacity (in the units of sizeof(_Tp)), or a pair of 0 values if
+   *  no storage can be obtained.</em>  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>
     pair<_Tp*, ptrdiff_t>
-    __get_temporary_buffer(ptrdiff_t __len, _Tp*)
+    get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT
     {
       const ptrdiff_t __max =
        __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
@@ -94,47 +100,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       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.
+   *  @param  __p  A buffer previously allocated by get_temporary_buffer.
    *  @return   None.
    *
-   *  Frees the memory pointed to by p.
+   *  Frees the memory pointed to by __p.
    */
   template<typename _Tp>
-    void
+    inline void
     return_temporary_buffer(_Tp* __p)
-    { ::operator delete(__p, nothrow); }
+    { ::operator delete(__p, std::nothrow); }
 
 
   /**
-   *  @if maint
    *  This class is used in two places: stl_algo.h and ext/memory,
    *  where it is wrapped as the temporary_buffer class.  See
    *  temporary_buffer docs for more notes.
-   *  @endif
    */
   template<typename _ForwardIterator, typename _Tp>
     class _Temporary_buffer
@@ -194,22 +176,86 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       operator=(const _Temporary_buffer&);
     };
 
+
+  template<bool>
+    struct __uninitialized_construct_buf_dispatch
+    {
+      template<typename _Pointer, typename _ForwardIterator>
+        static void
+        __ucr(_Pointer __first, _Pointer __last,
+             _ForwardIterator __seed)
+        {
+         if(__first == __last)
+           return;
+
+         _Pointer __cur = __first;
+         __try
+           {
+             std::_Construct(std::__addressof(*__first),
+                             _GLIBCXX_MOVE(*__seed));
+             _Pointer __prev = __cur;
+             ++__cur;
+             for(; __cur != __last; ++__cur, ++__prev)
+               std::_Construct(std::__addressof(*__cur),
+                               _GLIBCXX_MOVE(*__prev));
+             *__seed = _GLIBCXX_MOVE(*__prev);
+           }
+         __catch(...)
+           {
+             std::_Destroy(__first, __cur);
+             __throw_exception_again;
+           }
+       }
+    };
+
+  template<>
+    struct __uninitialized_construct_buf_dispatch<true>
+    {
+      template<typename _Pointer, typename _ForwardIterator>
+        static void
+        __ucr(_Pointer, _Pointer, _ForwardIterator) { }
+    };
+
+  // Constructs objects in the range [first, last).
+  // Note that while these new objects will take valid values,
+  // their exact value is not defined. In particular they may
+  // be 'moved from'.
+  //
+  // While *__seed may be altered during this algorithm, it will have
+  // the same value when the algorithm finishes, unless one of the
+  // constructions throws.
+  //
+  // Requirements: _Pointer::value_type(_Tp&&) is valid.
+  template<typename _Pointer, typename _ForwardIterator>
+    inline void
+    __uninitialized_construct_buf(_Pointer __first, _Pointer __last,
+                                 _ForwardIterator __seed)
+    {
+      typedef typename std::iterator_traits<_Pointer>::value_type
+       _ValueType;
+
+      std::__uninitialized_construct_buf_dispatch<
+        __has_trivial_constructor(_ValueType)>::
+         __ucr(__first, __last, __seed);
+    }
+
   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)
     {
-      try
+      __try
        {
          std::pair<pointer, size_type> __p(std::get_temporary_buffer<
                                            value_type>(_M_original_len));
          _M_buffer = __p.first;
          _M_len = __p.second;
-         if (!__is_pod(_Tp) && _M_len > 0)
-           std::uninitialized_fill_n(_M_buffer, _M_len, *__first);
+         if (_M_buffer)
+           std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
+                                              __first);
        }
-      catch(...)
+      __catch(...)
        {
          std::return_temporary_buffer(_M_buffer);
          _M_buffer = 0;
@@ -218,7 +264,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        }
     }
 
-_GLIBCXX_END_NAMESPACE
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
 
-#endif /* _TEMPBUF_H */
+#endif /* _STL_TEMPBUF_H */