Import gcc-4.7.2 to new vendor branch
[dragonfly.git] / contrib / gcc-4.7 / libstdc++-v3 / include / bits / stl_tempbuf.h
1 // Temporary buffer implementation -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4 // 2010, 2011
5 // Free Software Foundation, Inc.
6 //
7 // This file is part of the GNU ISO C++ Library.  This library is free
8 // software; you can redistribute it and/or modify it under the
9 // terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 3, or (at your option)
11 // any later version.
12
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17
18 // Under Section 7 of GPL version 3, you are granted additional
19 // permissions described in the GCC Runtime Library Exception, version
20 // 3.1, as published by the Free Software Foundation.
21
22 // You should have received a copy of the GNU General Public License and
23 // a copy of the GCC Runtime Library Exception along with this program;
24 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25 // <http://www.gnu.org/licenses/>.
26
27 /*
28  *
29  * Copyright (c) 1994
30  * Hewlett-Packard Company
31  *
32  * Permission to use, copy, modify, distribute and sell this software
33  * and its documentation for any purpose is hereby granted without fee,
34  * provided that the above copyright notice appear in all copies and
35  * that both that copyright notice and this permission notice appear
36  * in supporting documentation.  Hewlett-Packard Company makes no
37  * representations about the suitability of this software for any
38  * purpose.  It is provided "as is" without express or implied warranty.
39  *
40  *
41  * Copyright (c) 1996,1997
42  * Silicon Graphics Computer Systems, Inc.
43  *
44  * Permission to use, copy, modify, distribute and sell this software
45  * and its documentation for any purpose is hereby granted without fee,
46  * provided that the above copyright notice appear in all copies and
47  * that both that copyright notice and this permission notice appear
48  * in supporting documentation.  Silicon Graphics makes no
49  * representations about the suitability of this software for any
50  * purpose.  It is provided "as is" without express or implied warranty.
51  */
52
53 /** @file bits/stl_tempbuf.h
54  *  This is an internal header file, included by other library headers.
55  *  Do not attempt to use it directly. @headername{memory}
56  */
57
58 #ifndef _STL_TEMPBUF_H
59 #define _STL_TEMPBUF_H 1
60
61 #include <bits/stl_algobase.h>
62 #include <bits/stl_construct.h>
63
64 namespace std _GLIBCXX_VISIBILITY(default)
65 {
66 _GLIBCXX_BEGIN_NAMESPACE_VERSION
67
68   /**
69    *  @brief Allocates a temporary buffer.
70    *  @param  __len  The number of objects of type Tp.
71    *  @return See full description.
72    *
73    *  Reinventing the wheel, but this time with prettier spokes!
74    *
75    *  This function tries to obtain storage for @c __len adjacent Tp
76    *  objects.  The objects themselves are not constructed, of course.
77    *  A pair<> is returned containing <em>the buffer s address and
78    *  capacity (in the units of sizeof(_Tp)), or a pair of 0 values if
79    *  no storage can be obtained.</em>  Note that the capacity obtained
80    *  may be less than that requested if the memory is unavailable;
81    *  you should compare len with the .second return value.
82    *
83    * Provides the nothrow exception guarantee.
84    */
85   template<typename _Tp>
86     pair<_Tp*, ptrdiff_t>
87     get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT
88     {
89       const ptrdiff_t __max =
90         __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
91       if (__len > __max)
92         __len = __max;
93       
94       while (__len > 0) 
95         {
96           _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp), 
97                                                         std::nothrow));
98           if (__tmp != 0)
99             return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
100           __len /= 2;
101         }
102       return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
103     }
104
105   /**
106    *  @brief The companion to get_temporary_buffer().
107    *  @param  __p  A buffer previously allocated by get_temporary_buffer.
108    *  @return   None.
109    *
110    *  Frees the memory pointed to by __p.
111    */
112   template<typename _Tp>
113     inline void
114     return_temporary_buffer(_Tp* __p)
115     { ::operator delete(__p, std::nothrow); }
116
117
118   /**
119    *  This class is used in two places: stl_algo.h and ext/memory,
120    *  where it is wrapped as the temporary_buffer class.  See
121    *  temporary_buffer docs for more notes.
122    */
123   template<typename _ForwardIterator, typename _Tp>
124     class _Temporary_buffer
125     {
126       // concept requirements
127       __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
128
129     public:
130       typedef _Tp         value_type;
131       typedef value_type* pointer;
132       typedef pointer     iterator;
133       typedef ptrdiff_t   size_type;
134
135     protected:
136       size_type  _M_original_len;
137       size_type  _M_len;
138       pointer    _M_buffer;
139
140     public:
141       /// As per Table mumble.
142       size_type
143       size() const
144       { return _M_len; }
145
146       /// Returns the size requested by the constructor; may be >size().
147       size_type
148       requested_size() const
149       { return _M_original_len; }
150
151       /// As per Table mumble.
152       iterator
153       begin()
154       { return _M_buffer; }
155
156       /// As per Table mumble.
157       iterator
158       end()
159       { return _M_buffer + _M_len; }
160
161       /**
162        * Constructs a temporary buffer of a size somewhere between
163        * zero and the size of the given range.
164        */
165       _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last);
166
167       ~_Temporary_buffer()
168       {
169         std::_Destroy(_M_buffer, _M_buffer + _M_len);
170         std::return_temporary_buffer(_M_buffer);
171       }
172
173     private:
174       // Disable copy constructor and assignment operator.
175       _Temporary_buffer(const _Temporary_buffer&);
176
177       void
178       operator=(const _Temporary_buffer&);
179     };
180
181
182   template<bool>
183     struct __uninitialized_construct_buf_dispatch
184     {
185       template<typename _ForwardIterator, typename _Tp>
186         static void
187         __ucr(_ForwardIterator __first, _ForwardIterator __last,
188               _Tp& __value)
189         {
190           if(__first == __last)
191             return;
192
193           _ForwardIterator __cur = __first;
194           __try
195             {
196               std::_Construct(std::__addressof(*__first),
197                               _GLIBCXX_MOVE(__value));
198               _ForwardIterator __prev = __cur;
199               ++__cur;
200               for(; __cur != __last; ++__cur, ++__prev)
201                 std::_Construct(std::__addressof(*__cur),
202                                 _GLIBCXX_MOVE(*__prev));
203               __value = _GLIBCXX_MOVE(*__prev);
204             }
205           __catch(...)
206             {
207               std::_Destroy(__first, __cur);
208               __throw_exception_again;
209             }
210         }
211     };
212
213   template<>
214     struct __uninitialized_construct_buf_dispatch<true>
215     {
216       template<typename _ForwardIterator, typename _Tp>
217         static void
218         __ucr(_ForwardIterator, _ForwardIterator, _Tp&) { }
219     };
220
221   // Constructs objects in the range [first, last).
222   // Note that while these new objects will take valid values,
223   // their exact value is not defined. In particular they may
224   // be 'moved from'.
225   //
226   // While __value may altered during this algorithm, it will have
227   // the same value when the algorithm finishes, unless one of the
228   // constructions throws.
229   //
230   // Requirements: _ForwardIterator::value_type(_Tp&&) is valid.
231   template<typename _ForwardIterator, typename _Tp>
232     inline void
233     __uninitialized_construct_buf(_ForwardIterator __first,
234                                   _ForwardIterator __last,
235                                   _Tp& __value)
236     {
237       typedef typename std::iterator_traits<_ForwardIterator>::value_type
238         _ValueType;
239
240       std::__uninitialized_construct_buf_dispatch<
241         __has_trivial_constructor(_ValueType)>::
242           __ucr(__first, __last, __value);
243     }
244
245   template<typename _ForwardIterator, typename _Tp>
246     _Temporary_buffer<_ForwardIterator, _Tp>::
247     _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
248     : _M_original_len(std::distance(__first, __last)),
249       _M_len(0), _M_buffer(0)
250     {
251       __try
252         {
253           std::pair<pointer, size_type> __p(std::get_temporary_buffer<
254                                             value_type>(_M_original_len));
255           _M_buffer = __p.first;
256           _M_len = __p.second;
257           if(_M_buffer)
258             std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
259                                                *__first);
260         }
261       __catch(...)
262         {
263           std::return_temporary_buffer(_M_buffer);
264           _M_buffer = 0;
265           _M_len = 0;
266           __throw_exception_again;
267         }
268     }
269
270 _GLIBCXX_END_NAMESPACE_VERSION
271 } // namespace
272
273 #endif /* _STL_TEMPBUF_H */
274