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 _GLIBCXX_BEGIN_NAMESPACE(std)
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 template<typename _Tp>
00083 pair<_Tp*, ptrdiff_t>
00084 get_temporary_buffer(ptrdiff_t __len)
00085 {
00086 const ptrdiff_t __max =
00087 __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
00088 if (__len > __max)
00089 __len = __max;
00090
00091 while (__len > 0)
00092 {
00093 _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp),
00094 std::nothrow));
00095 if (__tmp != 0)
00096 return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
00097 __len /= 2;
00098 }
00099 return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 template<typename _Tp>
00110 inline void
00111 return_temporary_buffer(_Tp* __p)
00112 { ::operator delete(__p, std::nothrow); }
00113
00114
00115
00116
00117
00118
00119
00120 template<typename _ForwardIterator, typename _Tp>
00121 class _Temporary_buffer
00122 {
00123
00124 __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
00125
00126 public:
00127 typedef _Tp value_type;
00128 typedef value_type* pointer;
00129 typedef pointer iterator;
00130 typedef ptrdiff_t size_type;
00131
00132 protected:
00133 size_type _M_original_len;
00134 size_type _M_len;
00135 pointer _M_buffer;
00136
00137 public:
00138
00139 size_type
00140 size() const
00141 { return _M_len; }
00142
00143
00144 size_type
00145 requested_size() const
00146 { return _M_original_len; }
00147
00148
00149 iterator
00150 begin()
00151 { return _M_buffer; }
00152
00153
00154 iterator
00155 end()
00156 { return _M_buffer + _M_len; }
00157
00158
00159
00160
00161
00162 _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last);
00163
00164 ~_Temporary_buffer()
00165 {
00166 std::_Destroy(_M_buffer, _M_buffer + _M_len);
00167 std::return_temporary_buffer(_M_buffer);
00168 }
00169
00170 private:
00171
00172 _Temporary_buffer(const _Temporary_buffer&);
00173
00174 void
00175 operator=(const _Temporary_buffer&);
00176 };
00177
00178
00179 template<bool>
00180 struct __uninitialized_construct_buf_dispatch
00181 {
00182 template<typename _ForwardIterator, typename _Tp>
00183 static void
00184 __ucr(_ForwardIterator __first, _ForwardIterator __last,
00185 _Tp& __value)
00186 {
00187 if(__first == __last)
00188 return;
00189
00190 _ForwardIterator __cur = __first;
00191 __try
00192 {
00193 std::_Construct(std::__addressof(*__first),
00194 _GLIBCXX_MOVE(__value));
00195 _ForwardIterator __prev = __cur;
00196 ++__cur;
00197 for(; __cur != __last; ++__cur, ++__prev)
00198 std::_Construct(std::__addressof(*__cur),
00199 _GLIBCXX_MOVE(*__prev));
00200 __value = _GLIBCXX_MOVE(*__prev);
00201 }
00202 __catch(...)
00203 {
00204 std::_Destroy(__first, __cur);
00205 __throw_exception_again;
00206 }
00207 }
00208 };
00209
00210 template<>
00211 struct __uninitialized_construct_buf_dispatch<true>
00212 {
00213 template<typename _ForwardIterator, typename _Tp>
00214 static void
00215 __ucr(_ForwardIterator, _ForwardIterator, _Tp&) { }
00216 };
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 template<typename _ForwardIterator, typename _Tp>
00229 inline void
00230 __uninitialized_construct_buf(_ForwardIterator __first,
00231 _ForwardIterator __last,
00232 _Tp& __value)
00233 {
00234 typedef typename std::iterator_traits<_ForwardIterator>::value_type
00235 _ValueType;
00236
00237 std::__uninitialized_construct_buf_dispatch<
00238 __has_trivial_constructor(_ValueType)>::
00239 __ucr(__first, __last, __value);
00240 }
00241
00242 template<typename _ForwardIterator, typename _Tp>
00243 _Temporary_buffer<_ForwardIterator, _Tp>::
00244 _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
00245 : _M_original_len(std::distance(__first, __last)),
00246 _M_len(0), _M_buffer(0)
00247 {
00248 __try
00249 {
00250 std::pair<pointer, size_type> __p(std::get_temporary_buffer<
00251 value_type>(_M_original_len));
00252 _M_buffer = __p.first;
00253 _M_len = __p.second;
00254 if(_M_buffer)
00255 std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
00256 *__first);
00257 }
00258 __catch(...)
00259 {
00260 std::return_temporary_buffer(_M_buffer);
00261 _M_buffer = 0;
00262 _M_len = 0;
00263 __throw_exception_again;
00264 }
00265 }
00266
00267 _GLIBCXX_END_NAMESPACE
00268
00269 #endif
00270