00001 // Temporary buffer implementation -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 /* 00032 * 00033 * Copyright (c) 1994 00034 * Hewlett-Packard Company 00035 * 00036 * Permission to use, copy, modify, distribute and sell this software 00037 * and its documentation for any purpose is hereby granted without fee, 00038 * provided that the above copyright notice appear in all copies and 00039 * that both that copyright notice and this permission notice appear 00040 * in supporting documentation. Hewlett-Packard Company makes no 00041 * representations about the suitability of this software for any 00042 * purpose. It is provided "as is" without express or implied warranty. 00043 * 00044 * 00045 * Copyright (c) 1996,1997 00046 * Silicon Graphics Computer Systems, Inc. 00047 * 00048 * Permission to use, copy, modify, distribute and sell this software 00049 * and its documentation for any purpose is hereby granted without fee, 00050 * provided that the above copyright notice appear in all copies and 00051 * that both that copyright notice and this permission notice appear 00052 * in supporting documentation. Silicon Graphics makes no 00053 * representations about the suitability of this software for any 00054 * purpose. It is provided "as is" without express or implied warranty. 00055 */ 00056 00057 /** @file stl_tempbuf.h 00058 * This is an internal header file, included by other library headers. 00059 * You should not attempt to use it directly. 00060 */ 00061 00062 #ifndef _STL_TEMPBUF_H 00063 #define _STL_TEMPBUF_H 1 00064 00065 #include <bits/stl_algobase.h> 00066 #include <bits/stl_construct.h> 00067 #include <bits/stl_uninitialized.h> 00068 00069 _GLIBCXX_BEGIN_NAMESPACE(std) 00070 00071 /** 00072 * @brief Allocates a temporary buffer. 00073 * @param len The number of objects of type Tp. 00074 * @return See full description. 00075 * 00076 * Reinventing the wheel, but this time with prettier spokes! 00077 * 00078 * This function tries to obtain storage for @c len adjacent Tp 00079 * objects. The objects themselves are not constructed, of course. 00080 * A pair<> is returned containing "the buffer s address and 00081 * capacity (in the units of sizeof(Tp)), or a pair of 0 values if 00082 * no storage can be obtained." Note that the capacity obtained 00083 * may be less than that requested if the memory is unavailable; 00084 * you should compare len with the .second return value. 00085 * 00086 * Provides the nothrow exception guarantee. 00087 */ 00088 template<typename _Tp> 00089 pair<_Tp*, ptrdiff_t> 00090 get_temporary_buffer(ptrdiff_t __len) 00091 { 00092 const ptrdiff_t __max = 00093 __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp); 00094 if (__len > __max) 00095 __len = __max; 00096 00097 while (__len > 0) 00098 { 00099 _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp), 00100 std::nothrow)); 00101 if (__tmp != 0) 00102 return std::pair<_Tp*, ptrdiff_t>(__tmp, __len); 00103 __len /= 2; 00104 } 00105 return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0); 00106 } 00107 00108 /** 00109 * @brief The companion to get_temporary_buffer(). 00110 * @param p A buffer previously allocated by get_temporary_buffer. 00111 * @return None. 00112 * 00113 * Frees the memory pointed to by p. 00114 */ 00115 template<typename _Tp> 00116 inline void 00117 return_temporary_buffer(_Tp* __p) 00118 { ::operator delete(__p, std::nothrow); } 00119 00120 00121 /** 00122 * This class is used in two places: stl_algo.h and ext/memory, 00123 * where it is wrapped as the temporary_buffer class. See 00124 * temporary_buffer docs for more notes. 00125 */ 00126 template<typename _ForwardIterator, typename _Tp> 00127 class _Temporary_buffer 00128 { 00129 // concept requirements 00130 __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) 00131 00132 public: 00133 typedef _Tp value_type; 00134 typedef value_type* pointer; 00135 typedef pointer iterator; 00136 typedef ptrdiff_t size_type; 00137 00138 protected: 00139 size_type _M_original_len; 00140 size_type _M_len; 00141 pointer _M_buffer; 00142 00143 public: 00144 /// As per Table mumble. 00145 size_type 00146 size() const 00147 { return _M_len; } 00148 00149 /// Returns the size requested by the constructor; may be >size(). 00150 size_type 00151 requested_size() const 00152 { return _M_original_len; } 00153 00154 /// As per Table mumble. 00155 iterator 00156 begin() 00157 { return _M_buffer; } 00158 00159 /// As per Table mumble. 00160 iterator 00161 end() 00162 { return _M_buffer + _M_len; } 00163 00164 /** 00165 * Constructs a temporary buffer of a size somewhere between 00166 * zero and the size of the given range. 00167 */ 00168 _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); 00169 00170 ~_Temporary_buffer() 00171 { 00172 std::_Destroy(_M_buffer, _M_buffer + _M_len); 00173 std::return_temporary_buffer(_M_buffer); 00174 } 00175 00176 private: 00177 // Disable copy constructor and assignment operator. 00178 _Temporary_buffer(const _Temporary_buffer&); 00179 00180 void 00181 operator=(const _Temporary_buffer&); 00182 }; 00183 00184 template<typename _ForwardIterator, typename _Tp> 00185 _Temporary_buffer<_ForwardIterator, _Tp>:: 00186 _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) 00187 : _M_original_len(std::distance(__first, __last)), 00188 _M_len(0), _M_buffer(0) 00189 { 00190 try 00191 { 00192 std::pair<pointer, size_type> __p(std::get_temporary_buffer< 00193 value_type>(_M_original_len)); 00194 _M_buffer = __p.first; 00195 _M_len = __p.second; 00196 if (!__is_pod(_Tp) && _M_len > 0) 00197 std::uninitialized_fill_n(_M_buffer, _M_len, *__first); 00198 } 00199 catch(...) 00200 { 00201 std::return_temporary_buffer(_M_buffer); 00202 _M_buffer = 0; 00203 _M_len = 0; 00204 __throw_exception_again; 00205 } 00206 } 00207 00208 _GLIBCXX_END_NAMESPACE 00209 00210 #endif /* _STL_TEMPBUF_H */ 00211