197403Sobrien// Temporary buffer implementation -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 4169691Skan// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien/* 3297403Sobrien * 3397403Sobrien * Copyright (c) 1994 3497403Sobrien * Hewlett-Packard Company 3597403Sobrien * 3697403Sobrien * Permission to use, copy, modify, distribute and sell this software 3797403Sobrien * and its documentation for any purpose is hereby granted without fee, 3897403Sobrien * provided that the above copyright notice appear in all copies and 3997403Sobrien * that both that copyright notice and this permission notice appear 4097403Sobrien * in supporting documentation. Hewlett-Packard Company makes no 4197403Sobrien * representations about the suitability of this software for any 4297403Sobrien * purpose. It is provided "as is" without express or implied warranty. 4397403Sobrien * 4497403Sobrien * 4597403Sobrien * Copyright (c) 1996,1997 4697403Sobrien * Silicon Graphics Computer Systems, Inc. 4797403Sobrien * 4897403Sobrien * Permission to use, copy, modify, distribute and sell this software 4997403Sobrien * and its documentation for any purpose is hereby granted without fee, 5097403Sobrien * provided that the above copyright notice appear in all copies and 5197403Sobrien * that both that copyright notice and this permission notice appear 5297403Sobrien * in supporting documentation. Silicon Graphics makes no 5397403Sobrien * representations about the suitability of this software for any 5497403Sobrien * purpose. It is provided "as is" without express or implied warranty. 5597403Sobrien */ 5697403Sobrien 5797403Sobrien/** @file stl_tempbuf.h 5897403Sobrien * This is an internal header file, included by other library headers. 5997403Sobrien * You should not attempt to use it directly. 6097403Sobrien */ 6197403Sobrien 62132720Skan#ifndef _TEMPBUF_H 63132720Skan#define _TEMPBUF_H 1 6497403Sobrien 65132720Skan#include <memory> 66132720Skan 67169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 68169691Skan 69132720Skan /** 70132720Skan * @if maint 71132720Skan * This class is used in two places: stl_algo.h and ext/memory, 72132720Skan * where it is wrapped as the temporary_buffer class. See 73132720Skan * temporary_buffer docs for more notes. 74132720Skan * @endif 75132720Skan */ 76132720Skan template<typename _ForwardIterator, typename _Tp> 77132720Skan class _Temporary_buffer 78132720Skan { 79132720Skan // concept requirements 80132720Skan __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) 8197403Sobrien 82169691Skan public: 83132720Skan typedef _Tp value_type; 84132720Skan typedef value_type* pointer; 85132720Skan typedef pointer iterator; 86132720Skan typedef ptrdiff_t size_type; 8797403Sobrien 88132720Skan protected: 89132720Skan size_type _M_original_len; 90132720Skan size_type _M_len; 91132720Skan pointer _M_buffer; 9297403Sobrien 93132720Skan void 94132720Skan _M_initialize_buffer(const _Tp&, __true_type) { } 9597403Sobrien 96132720Skan void 97169691Skan _M_initialize_buffer(const _Tp& __val, __false_type) 98169691Skan { std::uninitialized_fill_n(_M_buffer, _M_len, __val); } 9997403Sobrien 100132720Skan public: 101132720Skan /// As per Table mumble. 102132720Skan size_type 103132720Skan size() const 104132720Skan { return _M_len; } 10597403Sobrien 106132720Skan /// Returns the size requested by the constructor; may be >size(). 107132720Skan size_type 108132720Skan requested_size() const 109132720Skan { return _M_original_len; } 11097403Sobrien 111132720Skan /// As per Table mumble. 112132720Skan iterator 113132720Skan begin() 114132720Skan { return _M_buffer; } 11597403Sobrien 116132720Skan /// As per Table mumble. 117132720Skan iterator 118132720Skan end() 119132720Skan { return _M_buffer + _M_len; } 12097403Sobrien 121132720Skan /** 122132720Skan * Constructs a temporary buffer of a size somewhere between 123132720Skan * zero and the size of the given range. 124132720Skan */ 125132720Skan _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); 126132720Skan 127132720Skan ~_Temporary_buffer() 128132720Skan { 129132720Skan std::_Destroy(_M_buffer, _M_buffer + _M_len); 130132720Skan std::return_temporary_buffer(_M_buffer); 13197403Sobrien } 13297403Sobrien 133132720Skan private: 134132720Skan // Disable copy constructor and assignment operator. 135132720Skan _Temporary_buffer(const _Temporary_buffer&); 136132720Skan 137132720Skan void 138132720Skan operator=(const _Temporary_buffer&); 139132720Skan }; 140132720Skan 141132720Skan 142132720Skan template<typename _ForwardIterator, typename _Tp> 143132720Skan _Temporary_buffer<_ForwardIterator, _Tp>:: 144132720Skan _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) 145132720Skan : _M_original_len(std::distance(__first, __last)), 146132720Skan _M_len(0), _M_buffer(0) 147132720Skan { 148132720Skan // Workaround for a __type_traits bug in the pre-7.3 compiler. 149169691Skan typedef typename std::__is_scalar<_Tp>::__type _Trivial; 150132720Skan 151132720Skan try 152132720Skan { 153132720Skan pair<pointer, size_type> __p(get_temporary_buffer< 154132720Skan value_type>(_M_original_len)); 155132720Skan _M_buffer = __p.first; 156132720Skan _M_len = __p.second; 157132720Skan if (_M_len > 0) 158132720Skan _M_initialize_buffer(*__first, _Trivial()); 159132720Skan } 160132720Skan catch(...) 161132720Skan { 162132720Skan std::return_temporary_buffer(_M_buffer); 163132720Skan _M_buffer = 0; 164132720Skan _M_len = 0; 165132720Skan __throw_exception_again; 166132720Skan } 167132720Skan } 16897403Sobrien 169169691Skan_GLIBCXX_END_NAMESPACE 170169691Skan 171132720Skan#endif /* _TEMPBUF_H */ 17297403Sobrien 173