197403Sobrien// Memory extensions -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 497403Sobrien// 597403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 697403Sobrien// software; you can redistribute it and/or modify it under the 797403Sobrien// terms of the GNU General Public License as published by the 897403Sobrien// Free Software Foundation; either version 2, or (at your option) 997403Sobrien// any later version. 1097403Sobrien 1197403Sobrien// This library is distributed in the hope that it will be useful, 1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1497403Sobrien// GNU General Public License for more details. 1597403Sobrien 1697403Sobrien// You should have received a copy of the GNU General Public License along 1797403Sobrien// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 1997403Sobrien// USA. 2097403Sobrien 2197403Sobrien// As a special exception, you may use this file as part of a free software 2297403Sobrien// library without restriction. Specifically, if other files instantiate 2397403Sobrien// templates or use macros or inline functions from this file, or you compile 2497403Sobrien// this file and link it with other files to produce an executable, this 2597403Sobrien// file does not by itself cause the resulting executable to be covered by 2697403Sobrien// the GNU General Public License. This exception does not however 2797403Sobrien// invalidate any other reasons why the executable file might be covered by 2897403Sobrien// the GNU General Public License. 2997403Sobrien 3097403Sobrien/* 3197403Sobrien * 3297403Sobrien * Copyright (c) 1994 3397403Sobrien * Hewlett-Packard Company 3497403Sobrien * 3597403Sobrien * Permission to use, copy, modify, distribute and sell this software 3697403Sobrien * and its documentation for any purpose is hereby granted without fee, 3797403Sobrien * provided that the above copyright notice appear in all copies and 3897403Sobrien * that both that copyright notice and this permission notice appear 3997403Sobrien * in supporting documentation. Hewlett-Packard Company makes no 4097403Sobrien * representations about the suitability of this software for any 4197403Sobrien * purpose. It is provided "as is" without express or implied warranty. 4297403Sobrien * 4397403Sobrien * 4497403Sobrien * Copyright (c) 1996 4597403Sobrien * Silicon Graphics Computer Systems, Inc. 4697403Sobrien * 4797403Sobrien * Permission to use, copy, modify, distribute and sell this software 4897403Sobrien * and its documentation for any purpose is hereby granted without fee, 4997403Sobrien * provided that the above copyright notice appear in all copies and 5097403Sobrien * that both that copyright notice and this permission notice appear 5197403Sobrien * in supporting documentation. Silicon Graphics makes no 5297403Sobrien * representations about the suitability of this software for any 5397403Sobrien * purpose. It is provided "as is" without express or implied warranty. 5497403Sobrien */ 5597403Sobrien 5697403Sobrien/** @file ext/memory 5797403Sobrien * This file is a GNU extension to the Standard C++ Library (possibly 58169691Skan * containing extensions from the HP/SGI STL subset). 5997403Sobrien */ 6097403Sobrien 6197403Sobrien#ifndef _EXT_MEMORY 62132720Skan#define _EXT_MEMORY 1 6397403Sobrien 6497403Sobrien#pragma GCC system_header 65132720Skan 6697403Sobrien#include <memory> 6797403Sobrien#include <bits/stl_tempbuf.h> 6897403Sobrien 69169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 70169691Skan 7197403Sobrien using std::ptrdiff_t; 7297403Sobrien using std::pair; 7397403Sobrien using std::__iterator_category; 7497403Sobrien using std::_Temporary_buffer; 7597403Sobrien 7697403Sobrien template<typename _InputIter, typename _Size, typename _ForwardIter> 7797403Sobrien pair<_InputIter, _ForwardIter> 7897403Sobrien __uninitialized_copy_n(_InputIter __first, _Size __count, 79132720Skan _ForwardIter __result, std::input_iterator_tag) 8097403Sobrien { 8197403Sobrien _ForwardIter __cur = __result; 82132720Skan try 83132720Skan { 84169691Skan for (; __count > 0 ; --__count, ++__first, ++__cur) 85132720Skan std::_Construct(&*__cur, *__first); 86132720Skan return pair<_InputIter, _ForwardIter>(__first, __cur); 87132720Skan } 8897403Sobrien catch(...) 8997403Sobrien { 9097403Sobrien std::_Destroy(__result, __cur); 91132720Skan __throw_exception_again; 9297403Sobrien } 9397403Sobrien } 9497403Sobrien 9597403Sobrien template<typename _RandomAccessIter, typename _Size, typename _ForwardIter> 9697403Sobrien inline pair<_RandomAccessIter, _ForwardIter> 9797403Sobrien __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, 9897403Sobrien _ForwardIter __result, 9997403Sobrien std::random_access_iterator_tag) 10097403Sobrien { 10197403Sobrien _RandomAccessIter __last = __first + __count; 102169691Skan return (pair<_RandomAccessIter, _ForwardIter> 103169691Skan (__last, std::uninitialized_copy(__first, __last, __result))); 10497403Sobrien } 10597403Sobrien 10697403Sobrien template<typename _InputIter, typename _Size, typename _ForwardIter> 10797403Sobrien inline pair<_InputIter, _ForwardIter> 10897403Sobrien __uninitialized_copy_n(_InputIter __first, _Size __count, 109132720Skan _ForwardIter __result) 110169691Skan { return __uninitialized_copy_n(__first, __count, __result, 111169691Skan __iterator_category(__first)); } 11297403Sobrien 11397403Sobrien /** 11497403Sobrien * @brief Copies the range [first,last) into result. 11597403Sobrien * @param first An input iterator. 11697403Sobrien * @param last An input iterator. 11797403Sobrien * @param result An output iterator. 11897403Sobrien * @return result + (first - last) 11997403Sobrien * @ingroup SGIextensions 12097403Sobrien * 12197403Sobrien * Like copy(), but does not require an initialized output range. 12297403Sobrien */ 12397403Sobrien template<typename _InputIter, typename _Size, typename _ForwardIter> 12497403Sobrien inline pair<_InputIter, _ForwardIter> 12597403Sobrien uninitialized_copy_n(_InputIter __first, _Size __count, 126132720Skan _ForwardIter __result) 127169691Skan { return __uninitialized_copy_n(__first, __count, __result, 128169691Skan __iterator_category(__first)); } 129169691Skan 130169691Skan 131169691Skan // An alternative version of uninitialized_copy_n that constructs 132169691Skan // and destroys objects with a user-provided allocator. 133169691Skan template<typename _InputIter, typename _Size, typename _ForwardIter, 134169691Skan typename _Allocator> 135169691Skan pair<_InputIter, _ForwardIter> 136169691Skan __uninitialized_copy_n_a(_InputIter __first, _Size __count, 137169691Skan _ForwardIter __result, 138169691Skan _Allocator __alloc) 139132720Skan { 140169691Skan _ForwardIter __cur = __result; 141169691Skan try 142169691Skan { 143169691Skan for (; __count > 0 ; --__count, ++__first, ++__cur) 144169691Skan __alloc.construct(&*__cur, *__first); 145169691Skan return pair<_InputIter, _ForwardIter>(__first, __cur); 146169691Skan } 147169691Skan catch(...) 148169691Skan { 149169691Skan std::_Destroy(__result, __cur, __alloc); 150169691Skan __throw_exception_again; 151169691Skan } 15297403Sobrien } 15397403Sobrien 154169691Skan template<typename _InputIter, typename _Size, typename _ForwardIter, 155169691Skan typename _Tp> 156169691Skan inline pair<_InputIter, _ForwardIter> 157169691Skan __uninitialized_copy_n_a(_InputIter __first, _Size __count, 158169691Skan _ForwardIter __result, 159169691Skan std::allocator<_Tp>) 160169691Skan { 161169691Skan return uninitialized_copy_n(__first, __count, __result); 162169691Skan } 16397403Sobrien 16497403Sobrien /** 16597403Sobrien * This class provides similar behavior and semantics of the standard 16697403Sobrien * functions get_temporary_buffer() and return_temporary_buffer(), but 16797403Sobrien * encapsulated in a type vaguely resembling a standard container. 16897403Sobrien * 16997403Sobrien * By default, a temporary_buffer<Iter> stores space for objects of 17097403Sobrien * whatever type the Iter iterator points to. It is constructed from a 17197403Sobrien * typical [first,last) range, and provides the begin(), end(), size() 17297403Sobrien * functions, as well as requested_size(). For non-trivial types, copies 17397403Sobrien * of *first will be used to initialize the storage. 17497403Sobrien * 17597403Sobrien * @c malloc is used to obtain underlying storage. 17697403Sobrien * 17797403Sobrien * Like get_temporary_buffer(), not all the requested memory may be 17897403Sobrien * available. Ideally, the created buffer will be large enough to hold a 17997403Sobrien * copy of [first,last), but if size() is less than requested_size(), 18097403Sobrien * then this didn't happen. 18197403Sobrien * 18297403Sobrien * @ingroup SGIextensions 18397403Sobrien */ 184132720Skan template <class _ForwardIterator, class _Tp 185169691Skan = typename std::iterator_traits<_ForwardIterator>::value_type > 186169691Skan struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> 187169691Skan { 188169691Skan /// Requests storage large enough to hold a copy of [first,last). 189169691Skan temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) 190169691Skan : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } 191169691Skan 192169691Skan /// Destroys objects and frees storage. 193169691Skan ~temporary_buffer() { } 194169691Skan }; 195132720Skan 196169691Skan_GLIBCXX_END_NAMESPACE 19797403Sobrien 198132720Skan#endif 19997403Sobrien 200