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
37template <class _Tp>
38pair<_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
56template <class _Tp>
57inline 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.
68template <class _Tp>
69inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) {
70  return __get_temporary_buffer(__len, (_Tp*) 0);
71}
72
73template <class _Tp>
74void return_temporary_buffer(_Tp* __p) {
75  free(__p);
76}
77
78template <class _ForwardIterator, class _Tp>
79class _Temporary_buffer {
80private:
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
105public:
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
129private:
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
137template <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         >
143struct 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:
157