diff options
Diffstat (limited to 'libstdc++/stl/stl_tempbuf.h')
-rw-r--r-- | libstdc++/stl/stl_tempbuf.h | 141 |
1 files changed, 87 insertions, 54 deletions
diff --git a/libstdc++/stl/stl_tempbuf.h b/libstdc++/stl/stl_tempbuf.h index 9dbc238eaee..e1b2eadafcb 100644 --- a/libstdc++/stl/stl_tempbuf.h +++ b/libstdc++/stl/stl_tempbuf.h @@ -34,86 +34,119 @@ __STL_BEGIN_NAMESPACE -template <class T> -pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*) { - if (len > ptrdiff_t(INT_MAX / sizeof(T))) - len = INT_MAX / sizeof(T); - - while (len > 0) { - T* tmp = (T*) malloc((size_t)len * sizeof(T)); - if (tmp != 0) - return pair<T*, ptrdiff_t>(tmp, len); - len /= 2; +template <class _Tp> +pair<_Tp*, ptrdiff_t> +__get_temporary_buffer(ptrdiff_t __len, _Tp*) +{ + if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) + __len = INT_MAX / sizeof(_Tp); + + while (__len > 0) { + _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; } - return pair<T*, ptrdiff_t>((T*)0, 0); + return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); } -template <class T> -void return_temporary_buffer(T* p) { - free(p); +#ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS + +template <class _Tp> +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { + return __get_temporary_buffer(__len, (_Tp*) 0); } -template <class ForwardIterator, - class T -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - = iterator_traits<ForwardIterator>::value_type -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - > -class temporary_buffer { +#endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ + +// This overload is not required by the standard; it is an extension. +// It is supported for backward compatibility with the HP STL, and +// because not all compilers support the language feature (explicit +// function template arguments) that is required for the standard +// version of get_temporary_buffer. +template <class _Tp> +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +template <class _Tp> +void return_temporary_buffer(_Tp* __p) { + free(__p); +} + +template <class _ForwardIterator, class _Tp> +class _Temporary_buffer { private: - ptrdiff_t original_len; - ptrdiff_t len; - T* buffer; + ptrdiff_t _M_original_len; + ptrdiff_t _M_len; + _Tp* _M_buffer; - void allocate_buffer() { - original_len = len; - buffer = 0; + void _M_allocate_buffer() { + _M_original_len = _M_len; + _M_buffer = 0; - if (len > (ptrdiff_t)(INT_MAX / sizeof(T))) - len = INT_MAX / sizeof(T); + if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp))) + _M_len = INT_MAX / sizeof(_Tp); - while (len > 0) { - buffer = (T*) malloc(len * sizeof(T)); - if (buffer) + while (_M_len > 0) { + _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp)); + if (_M_buffer) break; - len /= 2; + _M_len /= 2; } } - void initialize_buffer(const T&, __true_type) {} - void initialize_buffer(const T& val, __false_type) { - uninitialized_fill_n(buffer, len, val); + void _M_initialize_buffer(const _Tp&, __true_type) {} + void _M_initialize_buffer(const _Tp& val, __false_type) { + uninitialized_fill_n(_M_buffer, _M_len, val); } public: - ptrdiff_t size() const { return len; } - ptrdiff_t requested_size() const { return original_len; } - T* begin() { return buffer; } - T* end() { return buffer + len; } - - temporary_buffer(ForwardIterator first, ForwardIterator last) { + ptrdiff_t size() const { return _M_len; } + ptrdiff_t requested_size() const { return _M_original_len; } + _Tp* begin() { return _M_buffer; } + _Tp* end() { return _M_buffer + _M_len; } + + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) { + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; __STL_TRY { - len = 0; - distance(first, last, len); - allocate_buffer(); - if (len > 0) - initialize_buffer(*first, - typename __type_traits<T>::has_trivial_default_constructor()); + _M_len = 0; + distance(__first, __last, _M_len); + _M_allocate_buffer(); + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); } - __STL_UNWIND(free(buffer); buffer = 0; len = 0); + __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0); } - ~temporary_buffer() { - destroy(buffer, buffer + len); - free(buffer); + ~_Temporary_buffer() { + destroy(_M_buffer, _M_buffer + _M_len); + free(_M_buffer); } private: - temporary_buffer(const temporary_buffer&) {} - void operator=(const temporary_buffer&) {} + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&) {} + void operator=(const _Temporary_buffer&) {} }; +// Class temporary_buffer is not part of the standard. It is an extension. + +template <class _ForwardIterator, + class _Tp +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + = typename iterator_traits<_ForwardIterator>::value_type +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + > +struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> +{ + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {} + ~temporary_buffer() {} +}; + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ |