algorithm [...]: Update to SGI STL 3.11.
[gcc.git] / libstdc++ / stl / stl_tempbuf.h
index 9dbc238eaeeaa1d98a8c590f583039f9ac0c4bca..e1b2eadafcbf930d9485c1943f00d77304fb30ef 100644 (file)
 
 __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 */