Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef _STL_TEMPBUF_H
00058 #define _STL_TEMPBUF_H 1
00059
00060 #include <bits/stl_algobase.h>
00061 #include <bits/stl_construct.h>
00062
00063 namespace std _GLIBCXX_VISIBILITY(default)
00064 {
00065 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 template<typename _Tp>
00085 pair<_Tp*, ptrdiff_t>
00086 get_temporary_buffer(ptrdiff_t __len)
00087 {
00088 const ptrdiff_t __max =
00089 __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
00090 if (__len > __max)
00091 __len = __max;
00092
00093 while (__len > 0)
00094 {
00095 _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp),
00096 std::nothrow));
00097 if (__tmp != 0)
00098 return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
00099 __len /= 2;
00100 }
00101 return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111 template<typename _Tp>
00112 inline void
00113 return_temporary_buffer(_Tp* __p)
00114 { ::operator delete(__p, std::nothrow); }
00115
00116
00117
00118
00119
00120
00121
00122 template<typename _ForwardIterator, typename _Tp>
00123 class _Temporary_buffer
00124 {
00125
00126 __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
00127
00128 public:
00129 typedef _Tp value_type;
00130 typedef value_type* pointer;
00131 typedef pointer iterator;
00132 typedef ptrdiff_t size_type;
00133
00134 protected:
00135 size_type _M_original_len;
00136 size_type _M_len;
00137 pointer _M_buffer;
00138
00139 public:
00140
00141 size_type
00142 size() const
00143 { return _M_len; }
00144
00145
00146 size_type
00147 requested_size() const
00148 { return _M_original_len; }
00149
00150
00151 iterator
00152 begin()
00153 { return _M_buffer; }
00154
00155
00156 iterator
00157 end()
00158 { return _M_buffer + _M_len; }
00159
00160
00161
00162
00163
00164 _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last);
00165
00166 ~_Temporary_buffer()
00167 {
00168 std::_Destroy(_M_buffer, _M_buffer + _M_len);
00169 std::return_temporary_buffer(_M_buffer);
00170 }
00171
00172 private:
00173
00174 _Temporary_buffer(const _Temporary_buffer&);
00175
00176 void
00177 operator=(const _Temporary_buffer&);
00178 };
00179
00180
00181 template<bool>
00182 struct __uninitialized_construct_buf_dispatch
00183 {
00184 template<typename _ForwardIterator, typename _Tp>
00185 static void
00186 __ucr(_ForwardIterator __first, _ForwardIterator __last,
00187 _Tp& __value)
00188 {
00189 if(__first == __last)
00190 return;
00191
00192 _ForwardIterator __cur = __first;
00193 __try
00194 {
00195 std::_Construct(std::__addressof(*__first),
00196 _GLIBCXX_MOVE(__value));
00197 _ForwardIterator __prev = __cur;
00198 ++__cur;
00199 for(; __cur != __last; ++__cur, ++__prev)
00200 std::_Construct(std::__addressof(*__cur),
00201 _GLIBCXX_MOVE(*__prev));
00202 __value = _GLIBCXX_MOVE(*__prev);
00203 }
00204 __catch(...)
00205 {
00206 std::_Destroy(__first, __cur);
00207 __throw_exception_again;
00208 }
00209 }
00210 };
00211
00212 template<>
00213 struct __uninitialized_construct_buf_dispatch<true>
00214 {
00215 template<typename _ForwardIterator, typename _Tp>
00216 static void
00217 __ucr(_ForwardIterator, _ForwardIterator, _Tp&) { }
00218 };
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 template<typename _ForwardIterator, typename _Tp>
00231 inline void
00232 __uninitialized_construct_buf(_ForwardIterator __first,
00233 _ForwardIterator __last,
00234 _Tp& __value)
00235 {
00236 typedef typename std::iterator_traits<_ForwardIterator>::value_type
00237 _ValueType;
00238
00239 std::__uninitialized_construct_buf_dispatch<
00240 __has_trivial_constructor(_ValueType)>::
00241 __ucr(__first, __last, __value);
00242 }
00243
00244 template<typename _ForwardIterator, typename _Tp>
00245 _Temporary_buffer<_ForwardIterator, _Tp>::
00246 _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
00247 : _M_original_len(std::distance(__first, __last)),
00248 _M_len(0), _M_buffer(0)
00249 {
00250 __try
00251 {
00252 std::pair<pointer, size_type> __p(std::get_temporary_buffer<
00253 value_type>(_M_original_len));
00254 _M_buffer = __p.first;
00255 _M_len = __p.second;
00256 if(_M_buffer)
00257 std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
00258 *__first);
00259 }
00260 __catch(...)
00261 {
00262 std::return_temporary_buffer(_M_buffer);
00263 _M_buffer = 0;
00264 _M_len = 0;
00265 __throw_exception_again;
00266 }
00267 }
00268
00269 _GLIBCXX_END_NAMESPACE_VERSION
00270 }
00271
00272 #endif
00273