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