// 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 _STL_TEMPBUF_H
#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);
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>
inline void
/**
- * @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
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;
}
}
-_GLIBCXX_END_NAMESPACE
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
#endif /* _STL_TEMPBUF_H */