// 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
// 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,
// concept requirements
__glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
- public:
+ public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef pointer iterator;
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
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(...)
{
__throw_exception_again;
}
}
-} // namespace std
-#endif /* _TEMPBUF_H */
+_GLIBCXX_END_NAMESPACE
+
+#endif /* _STL_TEMPBUF_H */