xref: /haiku/headers/cpp/stl_tempbuf.h (revision f2ced752a08ff5d2618826bcd3ae3976c9f3e92e)
1 /*
2  *
3  * Copyright (c) 1994
4  * Hewlett-Packard Company
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Hewlett-Packard Company makes no
11  * representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  *
15  * Copyright (c) 1996,1997
16  * Silicon Graphics Computer Systems, Inc.
17  *
18  * Permission to use, copy, modify, distribute and sell this software
19  * and its documentation for any purpose is hereby granted without fee,
20  * provided that the above copyright notice appear in all copies and
21  * that both that copyright notice and this permission notice appear
22  * in supporting documentation.  Silicon Graphics makes no
23  * representations about the suitability of this software for any
24  * purpose.  It is provided "as is" without express or implied warranty.
25  */
26 
27 /* NOTE: This is an internal header file, included by other STL headers.
28  *   You should not attempt to use it directly.
29  */
30 
31 #ifndef __SGI_STL_INTERNAL_TEMPBUF_H
32 #define __SGI_STL_INTERNAL_TEMPBUF_H
33 
34 
35 __STL_BEGIN_NAMESPACE
36 
37 template <class _Tp>
38 pair<_Tp*, ptrdiff_t>
__get_temporary_buffer(ptrdiff_t __len,_Tp *)39 __get_temporary_buffer(ptrdiff_t __len, _Tp*)
40 {
41   if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp)))
42     __len = INT_MAX / sizeof(_Tp);
43 
44   while (__len > 0) {
45     _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp));
46     if (__tmp != 0)
47       return pair<_Tp*, ptrdiff_t>(__tmp, __len);
48     __len /= 2;
49   }
50 
51   return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0);
52 }
53 
54 #ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS
55 
56 template <class _Tp>
get_temporary_buffer(ptrdiff_t __len)57 inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) {
58   return __get_temporary_buffer(__len, (_Tp*) 0);
59 }
60 
61 #endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */
62 
63 // This overload is not required by the standard; it is an extension.
64 // It is supported for backward compatibility with the HP STL, and
65 // because not all compilers support the language feature (explicit
66 // function template arguments) that is required for the standard
67 // version of get_temporary_buffer.
68 template <class _Tp>
get_temporary_buffer(ptrdiff_t __len,_Tp *)69 inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) {
70   return __get_temporary_buffer(__len, (_Tp*) 0);
71 }
72 
73 template <class _Tp>
return_temporary_buffer(_Tp * __p)74 void return_temporary_buffer(_Tp* __p) {
75   free(__p);
76 }
77 
78 template <class _ForwardIterator, class _Tp>
79 class _Temporary_buffer {
80 private:
81   ptrdiff_t  _M_original_len;
82   ptrdiff_t  _M_len;
83   _Tp*       _M_buffer;
84 
_M_allocate_buffer()85   void _M_allocate_buffer() {
86     _M_original_len = _M_len;
87     _M_buffer = 0;
88 
89     if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp)))
90       _M_len = INT_MAX / sizeof(_Tp);
91 
92     while (_M_len > 0) {
93       _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp));
94       if (_M_buffer)
95         break;
96       _M_len /= 2;
97     }
98   }
99 
_M_initialize_buffer(const _Tp &,__true_type)100   void _M_initialize_buffer(const _Tp&, __true_type) {}
_M_initialize_buffer(const _Tp & val,__false_type)101   void _M_initialize_buffer(const _Tp& val, __false_type) {
102     uninitialized_fill_n(_M_buffer, _M_len, val);
103   }
104 
105 public:
size()106   ptrdiff_t size() const { return _M_len; }
requested_size()107   ptrdiff_t requested_size() const { return _M_original_len; }
begin()108   _Tp* begin() { return _M_buffer; }
end()109   _Tp* end() { return _M_buffer + _M_len; }
110 
_Temporary_buffer(_ForwardIterator __first,_ForwardIterator __last)111   _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) {
112     typedef typename __type_traits<_Tp>::has_trivial_default_constructor
113             _Trivial;
114     __STL_TRY {
115       _M_len = 0;
116       distance(__first, __last, _M_len);
117       _M_allocate_buffer();
118       if (_M_len > 0)
119         _M_initialize_buffer(*__first, _Trivial());
120     }
121     __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0);
122   }
123 
~_Temporary_buffer()124   ~_Temporary_buffer() {
125     destroy(_M_buffer, _M_buffer + _M_len);
126     free(_M_buffer);
127   }
128 
129 private:
130   // Disable copy constructor and assignment operator.
_Temporary_buffer(const _Temporary_buffer &)131   _Temporary_buffer(const _Temporary_buffer&) {}
132   void operator=(const _Temporary_buffer&) {}
133 };
134 
135 // Class temporary_buffer is not part of the standard.  It is an extension.
136 
137 template <class _ForwardIterator,
138           class _Tp
139 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
140                     = typename iterator_traits<_ForwardIterator>::value_type
141 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
142          >
143 struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp>
144 {
temporary_buffertemporary_buffer145   temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
146     : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {}
~temporary_buffertemporary_buffer147   ~temporary_buffer() {}
148 };
149 
150 __STL_END_NAMESPACE
151 
152 #endif /* __SGI_STL_INTERNAL_TEMPBUF_H */
153 
154 // Local Variables:
155 // mode:C++
156 // End:
157