stl_tempbuf.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. // Temporary buffer implementation -*- C++ -*-
  2. // Copyright (C) 2001-2018 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /*
  21. *
  22. * Copyright (c) 1994
  23. * Hewlett-Packard Company
  24. *
  25. * Permission to use, copy, modify, distribute and sell this software
  26. * and its documentation for any purpose is hereby granted without fee,
  27. * provided that the above copyright notice appear in all copies and
  28. * that both that copyright notice and this permission notice appear
  29. * in supporting documentation. Hewlett-Packard Company makes no
  30. * representations about the suitability of this software for any
  31. * purpose. It is provided "as is" without express or implied warranty.
  32. *
  33. *
  34. * Copyright (c) 1996,1997
  35. * Silicon Graphics Computer Systems, Inc.
  36. *
  37. * Permission to use, copy, modify, distribute and sell this software
  38. * and its documentation for any purpose is hereby granted without fee,
  39. * provided that the above copyright notice appear in all copies and
  40. * that both that copyright notice and this permission notice appear
  41. * in supporting documentation. Silicon Graphics makes no
  42. * representations about the suitability of this software for any
  43. * purpose. It is provided "as is" without express or implied warranty.
  44. */
  45. /** @file bits/stl_tempbuf.h
  46. * This is an internal header file, included by other library headers.
  47. * Do not attempt to use it directly. @headername{memory}
  48. */
  49. #ifndef _STL_TEMPBUF_H
  50. #define _STL_TEMPBUF_H 1
  51. #include <bits/stl_algobase.h>
  52. #include <bits/stl_construct.h>
  53. namespace std _GLIBCXX_VISIBILITY(default)
  54. {
  55. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  56. /**
  57. * @brief Allocates a temporary buffer.
  58. * @param __len The number of objects of type Tp.
  59. * @return See full description.
  60. *
  61. * Reinventing the wheel, but this time with prettier spokes!
  62. *
  63. * This function tries to obtain storage for @c __len adjacent Tp
  64. * objects. The objects themselves are not constructed, of course.
  65. * A pair<> is returned containing <em>the buffer s address and
  66. * capacity (in the units of sizeof(_Tp)), or a pair of 0 values if
  67. * no storage can be obtained.</em> Note that the capacity obtained
  68. * may be less than that requested if the memory is unavailable;
  69. * you should compare len with the .second return value.
  70. *
  71. * Provides the nothrow exception guarantee.
  72. */
  73. template<typename _Tp>
  74. pair<_Tp*, ptrdiff_t>
  75. get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT
  76. {
  77. const ptrdiff_t __max =
  78. __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
  79. if (__len > __max)
  80. __len = __max;
  81. while (__len > 0)
  82. {
  83. _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp),
  84. std::nothrow));
  85. if (__tmp != 0)
  86. return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
  87. __len /= 2;
  88. }
  89. return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
  90. }
  91. /**
  92. * @brief The companion to get_temporary_buffer().
  93. * @param __p A buffer previously allocated by get_temporary_buffer.
  94. * @return None.
  95. *
  96. * Frees the memory pointed to by __p.
  97. */
  98. template<typename _Tp>
  99. inline void
  100. return_temporary_buffer(_Tp* __p)
  101. { ::operator delete(__p, std::nothrow); }
  102. /**
  103. * This class is used in two places: stl_algo.h and ext/memory,
  104. * where it is wrapped as the temporary_buffer class. See
  105. * temporary_buffer docs for more notes.
  106. */
  107. template<typename _ForwardIterator, typename _Tp>
  108. class _Temporary_buffer
  109. {
  110. // concept requirements
  111. __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
  112. public:
  113. typedef _Tp value_type;
  114. typedef value_type* pointer;
  115. typedef pointer iterator;
  116. typedef ptrdiff_t size_type;
  117. protected:
  118. size_type _M_original_len;
  119. size_type _M_len;
  120. pointer _M_buffer;
  121. public:
  122. /// As per Table mumble.
  123. size_type
  124. size() const
  125. { return _M_len; }
  126. /// Returns the size requested by the constructor; may be >size().
  127. size_type
  128. requested_size() const
  129. { return _M_original_len; }
  130. /// As per Table mumble.
  131. iterator
  132. begin()
  133. { return _M_buffer; }
  134. /// As per Table mumble.
  135. iterator
  136. end()
  137. { return _M_buffer + _M_len; }
  138. /**
  139. * Constructs a temporary buffer of a size somewhere between
  140. * zero and the size of the given range.
  141. */
  142. _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last);
  143. ~_Temporary_buffer()
  144. {
  145. std::_Destroy(_M_buffer, _M_buffer + _M_len);
  146. std::return_temporary_buffer(_M_buffer);
  147. }
  148. private:
  149. // Disable copy constructor and assignment operator.
  150. _Temporary_buffer(const _Temporary_buffer&);
  151. void
  152. operator=(const _Temporary_buffer&);
  153. };
  154. template<bool>
  155. struct __uninitialized_construct_buf_dispatch
  156. {
  157. template<typename _Pointer, typename _ForwardIterator>
  158. static void
  159. __ucr(_Pointer __first, _Pointer __last,
  160. _ForwardIterator __seed)
  161. {
  162. if(__first == __last)
  163. return;
  164. _Pointer __cur = __first;
  165. __try
  166. {
  167. std::_Construct(std::__addressof(*__first),
  168. _GLIBCXX_MOVE(*__seed));
  169. _Pointer __prev = __cur;
  170. ++__cur;
  171. for(; __cur != __last; ++__cur, ++__prev)
  172. std::_Construct(std::__addressof(*__cur),
  173. _GLIBCXX_MOVE(*__prev));
  174. *__seed = _GLIBCXX_MOVE(*__prev);
  175. }
  176. __catch(...)
  177. {
  178. std::_Destroy(__first, __cur);
  179. __throw_exception_again;
  180. }
  181. }
  182. };
  183. template<>
  184. struct __uninitialized_construct_buf_dispatch<true>
  185. {
  186. template<typename _Pointer, typename _ForwardIterator>
  187. static void
  188. __ucr(_Pointer, _Pointer, _ForwardIterator) { }
  189. };
  190. // Constructs objects in the range [first, last).
  191. // Note that while these new objects will take valid values,
  192. // their exact value is not defined. In particular they may
  193. // be 'moved from'.
  194. //
  195. // While *__seed may be altered during this algorithm, it will have
  196. // the same value when the algorithm finishes, unless one of the
  197. // constructions throws.
  198. //
  199. // Requirements: _Pointer::value_type(_Tp&&) is valid.
  200. template<typename _Pointer, typename _ForwardIterator>
  201. inline void
  202. __uninitialized_construct_buf(_Pointer __first, _Pointer __last,
  203. _ForwardIterator __seed)
  204. {
  205. typedef typename std::iterator_traits<_Pointer>::value_type
  206. _ValueType;
  207. std::__uninitialized_construct_buf_dispatch<
  208. __has_trivial_constructor(_ValueType)>::
  209. __ucr(__first, __last, __seed);
  210. }
  211. template<typename _ForwardIterator, typename _Tp>
  212. _Temporary_buffer<_ForwardIterator, _Tp>::
  213. _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
  214. : _M_original_len(std::distance(__first, __last)),
  215. _M_len(0), _M_buffer(0)
  216. {
  217. __try
  218. {
  219. std::pair<pointer, size_type> __p(std::get_temporary_buffer<
  220. value_type>(_M_original_len));
  221. _M_buffer = __p.first;
  222. _M_len = __p.second;
  223. if (_M_buffer)
  224. std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
  225. __first);
  226. }
  227. __catch(...)
  228. {
  229. std::return_temporary_buffer(_M_buffer);
  230. _M_buffer = 0;
  231. _M_len = 0;
  232. __throw_exception_again;
  233. }
  234. }
  235. _GLIBCXX_END_NAMESPACE_VERSION
  236. } // namespace
  237. #endif /* _STL_TEMPBUF_H */