Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / libstdc++ / stl / stl_tempbuf.h
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> 
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>
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>
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>
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
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
100   void _M_initialize_buffer(const _Tp&, __true_type) {}
101   void _M_initialize_buffer(const _Tp& val, __false_type) {
102     uninitialized_fill_n(_M_buffer, _M_len, val);
103   }
104
105 public:
106   ptrdiff_t size() const { return _M_len; }
107   ptrdiff_t requested_size() const { return _M_original_len; }
108   _Tp* begin() { return _M_buffer; }
109   _Tp* end() { return _M_buffer + _M_len; }
110
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  
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.
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 {
145   temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
146     : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {}
147   ~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: