14fee23f9Smrg // Temporary buffer implementation -*- C++ -*-
24fee23f9Smrg
3b1e83836Smrg // Copyright (C) 2001-2022 Free Software Foundation, Inc.
44fee23f9Smrg //
54fee23f9Smrg // This file is part of the GNU ISO C++ Library. This library is free
64fee23f9Smrg // software; you can redistribute it and/or modify it under the
74fee23f9Smrg // terms of the GNU General Public License as published by the
84fee23f9Smrg // Free Software Foundation; either version 3, or (at your option)
94fee23f9Smrg // any later version.
104fee23f9Smrg
114fee23f9Smrg // This library is distributed in the hope that it will be useful,
124fee23f9Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
144fee23f9Smrg // GNU General Public License for more details.
154fee23f9Smrg
164fee23f9Smrg // Under Section 7 of GPL version 3, you are granted additional
174fee23f9Smrg // permissions described in the GCC Runtime Library Exception, version
184fee23f9Smrg // 3.1, as published by the Free Software Foundation.
194fee23f9Smrg
204fee23f9Smrg // You should have received a copy of the GNU General Public License and
214fee23f9Smrg // a copy of the GCC Runtime Library Exception along with this program;
224fee23f9Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
234fee23f9Smrg // <http://www.gnu.org/licenses/>.
244fee23f9Smrg
254fee23f9Smrg /*
264fee23f9Smrg *
274fee23f9Smrg * Copyright (c) 1994
284fee23f9Smrg * Hewlett-Packard Company
294fee23f9Smrg *
304fee23f9Smrg * Permission to use, copy, modify, distribute and sell this software
314fee23f9Smrg * and its documentation for any purpose is hereby granted without fee,
324fee23f9Smrg * provided that the above copyright notice appear in all copies and
334fee23f9Smrg * that both that copyright notice and this permission notice appear
344fee23f9Smrg * in supporting documentation. Hewlett-Packard Company makes no
354fee23f9Smrg * representations about the suitability of this software for any
364fee23f9Smrg * purpose. It is provided "as is" without express or implied warranty.
374fee23f9Smrg *
384fee23f9Smrg *
394fee23f9Smrg * Copyright (c) 1996,1997
404fee23f9Smrg * Silicon Graphics Computer Systems, Inc.
414fee23f9Smrg *
424fee23f9Smrg * Permission to use, copy, modify, distribute and sell this software
434fee23f9Smrg * and its documentation for any purpose is hereby granted without fee,
444fee23f9Smrg * provided that the above copyright notice appear in all copies and
454fee23f9Smrg * that both that copyright notice and this permission notice appear
464fee23f9Smrg * in supporting documentation. Silicon Graphics makes no
474fee23f9Smrg * representations about the suitability of this software for any
484fee23f9Smrg * purpose. It is provided "as is" without express or implied warranty.
494fee23f9Smrg */
504fee23f9Smrg
5148fb7bfaSmrg /** @file bits/stl_tempbuf.h
524fee23f9Smrg * This is an internal header file, included by other library headers.
5348fb7bfaSmrg * Do not attempt to use it directly. @headername{memory}
544fee23f9Smrg */
554fee23f9Smrg
564fee23f9Smrg #ifndef _STL_TEMPBUF_H
574fee23f9Smrg #define _STL_TEMPBUF_H 1
584fee23f9Smrg
594fee23f9Smrg #include <bits/stl_algobase.h>
604fee23f9Smrg #include <bits/stl_construct.h>
614fee23f9Smrg
_GLIBCXX_VISIBILITY(default)6248fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default)
6348fb7bfaSmrg {
6448fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
654fee23f9Smrg
66fb8a8121Smrg namespace __detail
67fb8a8121Smrg {
68fb8a8121Smrg template<typename _Tp>
69fb8a8121Smrg inline void
70fb8a8121Smrg __return_temporary_buffer(_Tp* __p,
71fb8a8121Smrg size_t __len __attribute__((__unused__)))
72fb8a8121Smrg {
73fb8a8121Smrg #if __cpp_sized_deallocation
74fb8a8121Smrg ::operator delete(__p, __len * sizeof(_Tp));
75fb8a8121Smrg #else
76fb8a8121Smrg ::operator delete(__p);
77fb8a8121Smrg #endif
78fb8a8121Smrg }
79fb8a8121Smrg }
80fb8a8121Smrg
814fee23f9Smrg /**
824fee23f9Smrg * @brief Allocates a temporary buffer.
8348fb7bfaSmrg * @param __len The number of objects of type Tp.
844fee23f9Smrg * @return See full description.
854fee23f9Smrg *
864fee23f9Smrg * Reinventing the wheel, but this time with prettier spokes!
874fee23f9Smrg *
8848fb7bfaSmrg * This function tries to obtain storage for @c __len adjacent Tp
894fee23f9Smrg * objects. The objects themselves are not constructed, of course.
904fee23f9Smrg * A pair<> is returned containing <em>the buffer s address and
9148fb7bfaSmrg * capacity (in the units of sizeof(_Tp)), or a pair of 0 values if
924fee23f9Smrg * no storage can be obtained.</em> Note that the capacity obtained
934fee23f9Smrg * may be less than that requested if the memory is unavailable;
944fee23f9Smrg * you should compare len with the .second return value.
954fee23f9Smrg *
964fee23f9Smrg * Provides the nothrow exception guarantee.
974fee23f9Smrg */
984fee23f9Smrg template<typename _Tp>
99b1e83836Smrg _GLIBCXX17_DEPRECATED
1004fee23f9Smrg pair<_Tp*, ptrdiff_t>
10148fb7bfaSmrg get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT
1024fee23f9Smrg {
1034fee23f9Smrg const ptrdiff_t __max =
1044fee23f9Smrg __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
1054fee23f9Smrg if (__len > __max)
1064fee23f9Smrg __len = __max;
1074fee23f9Smrg
1084fee23f9Smrg while (__len > 0)
1094fee23f9Smrg {
1104fee23f9Smrg _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp),
1114fee23f9Smrg std::nothrow));
1124fee23f9Smrg if (__tmp != 0)
1134fee23f9Smrg return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
114b1e83836Smrg __len = __len == 1 ? 0 : ((__len + 1) / 2);
1154fee23f9Smrg }
1164fee23f9Smrg return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
1174fee23f9Smrg }
1184fee23f9Smrg
1194fee23f9Smrg /**
1204fee23f9Smrg * @brief The companion to get_temporary_buffer().
12148fb7bfaSmrg * @param __p A buffer previously allocated by get_temporary_buffer.
1224fee23f9Smrg * @return None.
1234fee23f9Smrg *
12448fb7bfaSmrg * Frees the memory pointed to by __p.
1254fee23f9Smrg */
1264fee23f9Smrg template<typename _Tp>
1274fee23f9Smrg inline void
1284fee23f9Smrg return_temporary_buffer(_Tp* __p)
129181254a7Smrg { ::operator delete(__p); }
1304fee23f9Smrg
1314fee23f9Smrg /**
1324fee23f9Smrg * This class is used in two places: stl_algo.h and ext/memory,
1334fee23f9Smrg * where it is wrapped as the temporary_buffer class. See
1344fee23f9Smrg * temporary_buffer docs for more notes.
1354fee23f9Smrg */
1364fee23f9Smrg template<typename _ForwardIterator, typename _Tp>
1374fee23f9Smrg class _Temporary_buffer
1384fee23f9Smrg {
1394fee23f9Smrg // concept requirements
1404fee23f9Smrg __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
1414fee23f9Smrg
1424fee23f9Smrg public:
1434fee23f9Smrg typedef _Tp value_type;
1444fee23f9Smrg typedef value_type* pointer;
1454fee23f9Smrg typedef pointer iterator;
1464fee23f9Smrg typedef ptrdiff_t size_type;
1474fee23f9Smrg
1484fee23f9Smrg protected:
1494fee23f9Smrg size_type _M_original_len;
1504fee23f9Smrg size_type _M_len;
1514fee23f9Smrg pointer _M_buffer;
1524fee23f9Smrg
1534fee23f9Smrg public:
1544fee23f9Smrg /// As per Table mumble.
1554fee23f9Smrg size_type
1564fee23f9Smrg size() const
1574fee23f9Smrg { return _M_len; }
1584fee23f9Smrg
1594fee23f9Smrg /// Returns the size requested by the constructor; may be >size().
1604fee23f9Smrg size_type
1614fee23f9Smrg requested_size() const
1624fee23f9Smrg { return _M_original_len; }
1634fee23f9Smrg
1644fee23f9Smrg /// As per Table mumble.
1654fee23f9Smrg iterator
1664fee23f9Smrg begin()
1674fee23f9Smrg { return _M_buffer; }
1684fee23f9Smrg
1694fee23f9Smrg /// As per Table mumble.
1704fee23f9Smrg iterator
1714fee23f9Smrg end()
1724fee23f9Smrg { return _M_buffer + _M_len; }
1734fee23f9Smrg
1744fee23f9Smrg /**
1754fee23f9Smrg * Constructs a temporary buffer of a size somewhere between
176181254a7Smrg * zero and the given length.
1774fee23f9Smrg */
178181254a7Smrg _Temporary_buffer(_ForwardIterator __seed, size_type __original_len);
1794fee23f9Smrg
1804fee23f9Smrg ~_Temporary_buffer()
1814fee23f9Smrg {
1824fee23f9Smrg std::_Destroy(_M_buffer, _M_buffer + _M_len);
183fb8a8121Smrg std::__detail::__return_temporary_buffer(_M_buffer, _M_len);
1844fee23f9Smrg }
1854fee23f9Smrg
1864fee23f9Smrg private:
1874fee23f9Smrg // Disable copy constructor and assignment operator.
1884fee23f9Smrg _Temporary_buffer(const _Temporary_buffer&);
1894fee23f9Smrg
1904fee23f9Smrg void
1914fee23f9Smrg operator=(const _Temporary_buffer&);
1924fee23f9Smrg };
1934fee23f9Smrg
19448fb7bfaSmrg
19548fb7bfaSmrg template<bool>
19648fb7bfaSmrg struct __uninitialized_construct_buf_dispatch
19748fb7bfaSmrg {
19848fb7bfaSmrg template<typename _Pointer, typename _ForwardIterator>
19948fb7bfaSmrg static void
20048fb7bfaSmrg __ucr(_Pointer __first, _Pointer __last,
20148fb7bfaSmrg _ForwardIterator __seed)
20248fb7bfaSmrg {
20348fb7bfaSmrg if (__first == __last)
20448fb7bfaSmrg return;
20548fb7bfaSmrg
20648fb7bfaSmrg _Pointer __cur = __first;
20748fb7bfaSmrg __try
20848fb7bfaSmrg {
20948fb7bfaSmrg std::_Construct(std::__addressof(*__first),
21048fb7bfaSmrg _GLIBCXX_MOVE(*__seed));
21148fb7bfaSmrg _Pointer __prev = __cur;
21248fb7bfaSmrg ++__cur;
21348fb7bfaSmrg for(; __cur != __last; ++__cur, ++__prev)
21448fb7bfaSmrg std::_Construct(std::__addressof(*__cur),
21548fb7bfaSmrg _GLIBCXX_MOVE(*__prev));
21648fb7bfaSmrg *__seed = _GLIBCXX_MOVE(*__prev);
21748fb7bfaSmrg }
21848fb7bfaSmrg __catch(...)
21948fb7bfaSmrg {
22048fb7bfaSmrg std::_Destroy(__first, __cur);
22148fb7bfaSmrg __throw_exception_again;
22248fb7bfaSmrg }
22348fb7bfaSmrg }
22448fb7bfaSmrg };
22548fb7bfaSmrg
22648fb7bfaSmrg template<>
22748fb7bfaSmrg struct __uninitialized_construct_buf_dispatch<true>
22848fb7bfaSmrg {
22948fb7bfaSmrg template<typename _Pointer, typename _ForwardIterator>
23048fb7bfaSmrg static void
23148fb7bfaSmrg __ucr(_Pointer, _Pointer, _ForwardIterator) { }
23248fb7bfaSmrg };
23348fb7bfaSmrg
23448fb7bfaSmrg // Constructs objects in the range [first, last).
23548fb7bfaSmrg // Note that while these new objects will take valid values,
23648fb7bfaSmrg // their exact value is not defined. In particular they may
23748fb7bfaSmrg // be 'moved from'.
23848fb7bfaSmrg //
23948fb7bfaSmrg // While *__seed may be altered during this algorithm, it will have
24048fb7bfaSmrg // the same value when the algorithm finishes, unless one of the
24148fb7bfaSmrg // constructions throws.
24248fb7bfaSmrg //
24348fb7bfaSmrg // Requirements: _Pointer::value_type(_Tp&&) is valid.
24448fb7bfaSmrg template<typename _Pointer, typename _ForwardIterator>
24548fb7bfaSmrg inline void
24648fb7bfaSmrg __uninitialized_construct_buf(_Pointer __first, _Pointer __last,
24748fb7bfaSmrg _ForwardIterator __seed)
24848fb7bfaSmrg {
24948fb7bfaSmrg typedef typename std::iterator_traits<_Pointer>::value_type
25048fb7bfaSmrg _ValueType;
25148fb7bfaSmrg
25248fb7bfaSmrg std::__uninitialized_construct_buf_dispatch<
25348fb7bfaSmrg __has_trivial_constructor(_ValueType)>::
25448fb7bfaSmrg __ucr(__first, __last, __seed);
25548fb7bfaSmrg }
25648fb7bfaSmrg
257*0a307195Smrg #pragma GCC diagnostic push
258*0a307195Smrg #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2594fee23f9Smrg template<typename _ForwardIterator, typename _Tp>
2604fee23f9Smrg _Temporary_buffer<_ForwardIterator, _Tp>::
261181254a7Smrg _Temporary_buffer(_ForwardIterator __seed, size_type __original_len)
262181254a7Smrg : _M_original_len(__original_len), _M_len(0), _M_buffer(0)
2634fee23f9Smrg {
264fb8a8121Smrg std::pair<pointer, size_type> __p(
265fb8a8121Smrg std::get_temporary_buffer<value_type>(_M_original_len));
266fb8a8121Smrg
267fb8a8121Smrg if (__p.first)
268fb8a8121Smrg {
2694fee23f9Smrg __try
2704fee23f9Smrg {
271fb8a8121Smrg std::__uninitialized_construct_buf(__p.first, __p.first + __p.second,
272fb8a8121Smrg __seed);
2734fee23f9Smrg _M_buffer = __p.first;
2744fee23f9Smrg _M_len = __p.second;
2754fee23f9Smrg }
2764fee23f9Smrg __catch(...)
2774fee23f9Smrg {
278fb8a8121Smrg std::__detail::__return_temporary_buffer(__p.first, __p.second);
2794fee23f9Smrg __throw_exception_again;
2804fee23f9Smrg }
2814fee23f9Smrg }
282fb8a8121Smrg }
283*0a307195Smrg #pragma GCC diagnostic pop
2844fee23f9Smrg
28548fb7bfaSmrg _GLIBCXX_END_NAMESPACE_VERSION
28648fb7bfaSmrg } // namespace
2874fee23f9Smrg
2884fee23f9Smrg #endif /* _STL_TEMPBUF_H */
289