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 #ifndef __SGI_STL_INTERNAL_TEMPBUF_H
00032 #define __SGI_STL_INTERNAL_TEMPBUF_H
00033
00034 namespace std
00035 {
00036
00037 template <class _Tp>
00038 pair<_Tp*, ptrdiff_t>
00039 __get_temporary_buffer(ptrdiff_t __len, _Tp*)
00040 {
00041 if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp)))
00042 __len = INT_MAX / sizeof(_Tp);
00043
00044 while (__len > 0) {
00045 _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp));
00046 if (__tmp != 0)
00047 return pair<_Tp*, ptrdiff_t>(__tmp, __len);
00048 __len /= 2;
00049 }
00050
00051 return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0);
00052 }
00053
00054 template <class _Tp>
00055 inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) {
00056 return __get_temporary_buffer(__len, (_Tp*) 0);
00057 }
00058
00059
00060
00061
00062
00063
00064 template <class _Tp>
00065 inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) {
00066 return __get_temporary_buffer(__len, (_Tp*) 0);
00067 }
00068
00069 template <class _Tp>
00070 void return_temporary_buffer(_Tp* __p) {
00071 free(__p);
00072 }
00073
00074 template <class _ForwardIterator, class _Tp>
00075 class _Temporary_buffer {
00076 private:
00077 ptrdiff_t _M_original_len;
00078 ptrdiff_t _M_len;
00079 _Tp* _M_buffer;
00080
00081 void _M_allocate_buffer() {
00082 _M_original_len = _M_len;
00083 _M_buffer = 0;
00084
00085 if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp)))
00086 _M_len = INT_MAX / sizeof(_Tp);
00087
00088 while (_M_len > 0) {
00089 _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp));
00090 if (_M_buffer)
00091 break;
00092 _M_len /= 2;
00093 }
00094 }
00095
00096 void _M_initialize_buffer(const _Tp&, __true_type) {}
00097 void _M_initialize_buffer(const _Tp& val, __false_type) {
00098 uninitialized_fill_n(_M_buffer, _M_len, val);
00099 }
00100
00101 public:
00102 ptrdiff_t size() const { return _M_len; }
00103 ptrdiff_t requested_size() const { return _M_original_len; }
00104 _Tp* begin() { return _M_buffer; }
00105 _Tp* end() { return _M_buffer + _M_len; }
00106
00107 _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) {
00108
00109 typedef typename __type_traits<_Tp>::has_trivial_default_constructor
00110 _Trivial;
00111
00112 __STL_TRY {
00113 _M_len = 0;
00114 distance(__first, __last, _M_len);
00115 _M_allocate_buffer();
00116 if (_M_len > 0)
00117 _M_initialize_buffer(*__first, _Trivial());
00118 }
00119 __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0);
00120 }
00121
00122 ~_Temporary_buffer() {
00123 destroy(_M_buffer, _M_buffer + _M_len);
00124 free(_M_buffer);
00125 }
00126
00127 private:
00128
00129 _Temporary_buffer(const _Temporary_buffer&) {}
00130 void operator=(const _Temporary_buffer&) {}
00131 };
00132
00133
00134
00135 template <class _ForwardIterator,
00136 class _Tp
00137 = typename iterator_traits<_ForwardIterator>::value_type
00138 >
00139 struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp>
00140 {
00141 temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
00142 : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {}
00143 ~temporary_buffer() {}
00144 };
00145
00146 }
00147
00148 #endif
00149
00150
00151
00152