1/*
2 *
3 * Copyright (c) 1994
4 * Hewlett-Packard Company
5 *
6 * Copyright (c) 1996,1997
7 * Silicon Graphics Computer Systems, Inc.
8 *
9 * Copyright (c) 1997
10 * Moscow Center for SPARC Technology
11 *
12 * Copyright (c) 1999
13 * Boris Fomitchev
14 *
15 * This material is provided "as is", with absolutely no warranty expressed
16 * or implied. Any use is at your own risk.
17 *
18 * Permission to use or copy this software for any purpose is hereby granted
19 * without fee, provided the above notices are retained on all copies.
20 * Permission to modify the code and to distribute modified code is granted,
21 * provided the above notices are retained, and a notice that the code was
22 * modified is included with the above copyright notice.
23 *
24 */
25
26/* NOTE: This is an internal header file, included by other STL headers.
27 *   You should not attempt to use it directly.
28 */
29
30#ifndef _STLP_INTERNAL_TEMPBUF_H
31#define _STLP_INTERNAL_TEMPBUF_H
32
33#ifndef _STLP_CLIMITS
34#  include <climits>
35#endif
36
37#ifndef _STLP_INTERNAL_CSTDLIB
38#  include <stl/_cstdlib.h>
39#endif
40
41#ifndef _STLP_INTERNAL_UNINITIALIZED_H
42#  include <stl/_uninitialized.h>
43#endif
44
45_STLP_BEGIN_NAMESPACE
46
47template <class _Tp>
48pair<_Tp*, ptrdiff_t>  _STLP_CALL
49__get_temporary_buffer(ptrdiff_t __len, _Tp*);
50
51#ifndef _STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS
52
53template <class _Tp>
54inline pair<_Tp*, ptrdiff_t>  _STLP_CALL get_temporary_buffer(ptrdiff_t __len) {
55  return __get_temporary_buffer(__len, (_Tp*) 0);
56}
57
58# if ! defined(_STLP_NO_EXTENSIONS)
59// This overload is not required by the standard; it is an extension.
60// It is supported for backward compatibility with the HP STL, and
61// because not all compilers support the language feature (explicit
62// function template arguments) that is required for the standard
63// version of get_temporary_buffer.
64template <class _Tp>
65inline pair<_Tp*, ptrdiff_t>  _STLP_CALL
66get_temporary_buffer(ptrdiff_t __len, _Tp*) {
67  return __get_temporary_buffer(__len, (_Tp*) 0);
68}
69# endif
70#endif
71
72template <class _Tp>
73inline void  _STLP_CALL return_temporary_buffer(_Tp* __p) {
74// SunPro brain damage
75  free((char*)__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&, const __true_type&) {}
101  void _M_initialize_buffer(const _Tp& val, const __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    // Workaround for a __type_traits bug in the pre-7.3 compiler.
113#   if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION < 730
114    typedef typename __type_traits<_Tp>::is_POD_type _Trivial;
115#   else
116    typedef typename __type_traits<_Tp>::has_trivial_default_constructor  _Trivial;
117#   endif
118    _STLP_TRY {
119      _M_len = _STLP_STD::distance(__first, __last);
120      _M_allocate_buffer();
121      if (_M_len > 0)
122        _M_initialize_buffer(*__first, _Trivial());
123    }
124    _STLP_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0)
125  }
126
127  ~_Temporary_buffer() {
128    _STLP_STD::_Destroy_Range(_M_buffer, _M_buffer + _M_len);
129    free(_M_buffer);
130  }
131
132private:
133  // Disable copy constructor and assignment operator.
134  _Temporary_buffer(const _Temporary_buffer<_ForwardIterator, _Tp>&) {}
135  void operator=(const _Temporary_buffer<_ForwardIterator, _Tp>&) {}
136};
137
138# ifndef _STLP_NO_EXTENSIONS
139
140// Class temporary_buffer is not part of the standard.  It is an extension.
141
142template <class _ForwardIterator,
143          class _Tp
144#ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
145                    = typename iterator_traits<_ForwardIterator>::value_type
146#endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
147         >
148struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp>
149{
150  temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
151    : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {}
152  ~temporary_buffer() {}
153};
154
155# endif /* _STLP_NO_EXTENSIONS */
156
157_STLP_END_NAMESPACE
158
159# ifndef _STLP_LINK_TIME_INSTANTIATION
160#  include <stl/_tempbuf.c>
161# endif
162
163#endif /* _STLP_INTERNAL_TEMPBUF_H */
164
165// Local Variables:
166// mode:C++
167// End:
168