100db7afdSDavid E. O'Brien// Memory extensions -*- C++ -*- 200db7afdSDavid E. O'Brien 3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 400db7afdSDavid E. O'Brien// 500db7afdSDavid E. O'Brien// This file is part of the GNU ISO C++ Library. This library is free 600db7afdSDavid E. O'Brien// software; you can redistribute it and/or modify it under the 700db7afdSDavid E. O'Brien// terms of the GNU General Public License as published by the 800db7afdSDavid E. O'Brien// Free Software Foundation; either version 2, or (at your option) 900db7afdSDavid E. O'Brien// any later version. 1000db7afdSDavid E. O'Brien 1100db7afdSDavid E. O'Brien// This library is distributed in the hope that it will be useful, 1200db7afdSDavid E. O'Brien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1300db7afdSDavid E. O'Brien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1400db7afdSDavid E. O'Brien// GNU General Public License for more details. 1500db7afdSDavid E. O'Brien 1600db7afdSDavid E. O'Brien// You should have received a copy of the GNU General Public License along 1700db7afdSDavid E. O'Brien// with this library; see the file COPYING. If not, write to the Free 18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 1900db7afdSDavid E. O'Brien// USA. 2000db7afdSDavid E. O'Brien 2100db7afdSDavid E. O'Brien// As a special exception, you may use this file as part of a free software 2200db7afdSDavid E. O'Brien// library without restriction. Specifically, if other files instantiate 2300db7afdSDavid E. O'Brien// templates or use macros or inline functions from this file, or you compile 2400db7afdSDavid E. O'Brien// this file and link it with other files to produce an executable, this 2500db7afdSDavid E. O'Brien// file does not by itself cause the resulting executable to be covered by 2600db7afdSDavid E. O'Brien// the GNU General Public License. This exception does not however 2700db7afdSDavid E. O'Brien// invalidate any other reasons why the executable file might be covered by 2800db7afdSDavid E. O'Brien// the GNU General Public License. 2900db7afdSDavid E. O'Brien 3000db7afdSDavid E. O'Brien/* 3100db7afdSDavid E. O'Brien * 3200db7afdSDavid E. O'Brien * Copyright (c) 1994 3300db7afdSDavid E. O'Brien * Hewlett-Packard Company 3400db7afdSDavid E. O'Brien * 3500db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software 3600db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee, 3700db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and 3800db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear 3900db7afdSDavid E. O'Brien * in supporting documentation. Hewlett-Packard Company makes no 4000db7afdSDavid E. O'Brien * representations about the suitability of this software for any 4100db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty. 4200db7afdSDavid E. O'Brien * 4300db7afdSDavid E. O'Brien * 4400db7afdSDavid E. O'Brien * Copyright (c) 1996 4500db7afdSDavid E. O'Brien * Silicon Graphics Computer Systems, Inc. 4600db7afdSDavid E. O'Brien * 4700db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software 4800db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee, 4900db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and 5000db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear 5100db7afdSDavid E. O'Brien * in supporting documentation. Silicon Graphics makes no 5200db7afdSDavid E. O'Brien * representations about the suitability of this software for any 5300db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty. 5400db7afdSDavid E. O'Brien */ 5500db7afdSDavid E. O'Brien 5600db7afdSDavid E. O'Brien/** @file ext/memory 5700db7afdSDavid E. O'Brien * This file is a GNU extension to the Standard C++ Library (possibly 58*f8a1b7d9SAlexander Kabaev * containing extensions from the HP/SGI STL subset). 5900db7afdSDavid E. O'Brien */ 6000db7afdSDavid E. O'Brien 6100db7afdSDavid E. O'Brien#ifndef _EXT_MEMORY 62ffeaf689SAlexander Kabaev#define _EXT_MEMORY 1 6300db7afdSDavid E. O'Brien 6400db7afdSDavid E. O'Brien#pragma GCC system_header 65ffeaf689SAlexander Kabaev 6600db7afdSDavid E. O'Brien#include <memory> 6700db7afdSDavid E. O'Brien#include <bits/stl_tempbuf.h> 6800db7afdSDavid E. O'Brien 69*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 70*f8a1b7d9SAlexander Kabaev 7100db7afdSDavid E. O'Brien using std::ptrdiff_t; 7200db7afdSDavid E. O'Brien using std::pair; 7300db7afdSDavid E. O'Brien using std::__iterator_category; 7400db7afdSDavid E. O'Brien using std::_Temporary_buffer; 7500db7afdSDavid E. O'Brien 7600db7afdSDavid E. O'Brien template<typename _InputIter, typename _Size, typename _ForwardIter> 7700db7afdSDavid E. O'Brien pair<_InputIter, _ForwardIter> 7800db7afdSDavid E. O'Brien __uninitialized_copy_n(_InputIter __first, _Size __count, 79ffeaf689SAlexander Kabaev _ForwardIter __result, std::input_iterator_tag) 8000db7afdSDavid E. O'Brien { 8100db7afdSDavid E. O'Brien _ForwardIter __cur = __result; 82ffeaf689SAlexander Kabaev try 83ffeaf689SAlexander Kabaev { 8400db7afdSDavid E. O'Brien for (; __count > 0 ; --__count, ++__first, ++__cur) 8500db7afdSDavid E. O'Brien std::_Construct(&*__cur, *__first); 8600db7afdSDavid E. O'Brien return pair<_InputIter, _ForwardIter>(__first, __cur); 8700db7afdSDavid E. O'Brien } 8800db7afdSDavid E. O'Brien catch(...) 8900db7afdSDavid E. O'Brien { 9000db7afdSDavid E. O'Brien std::_Destroy(__result, __cur); 9100db7afdSDavid E. O'Brien __throw_exception_again; 9200db7afdSDavid E. O'Brien } 9300db7afdSDavid E. O'Brien } 9400db7afdSDavid E. O'Brien 9500db7afdSDavid E. O'Brien template<typename _RandomAccessIter, typename _Size, typename _ForwardIter> 9600db7afdSDavid E. O'Brien inline pair<_RandomAccessIter, _ForwardIter> 9700db7afdSDavid E. O'Brien __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, 9800db7afdSDavid E. O'Brien _ForwardIter __result, 9900db7afdSDavid E. O'Brien std::random_access_iterator_tag) 10000db7afdSDavid E. O'Brien { 10100db7afdSDavid E. O'Brien _RandomAccessIter __last = __first + __count; 102*f8a1b7d9SAlexander Kabaev return (pair<_RandomAccessIter, _ForwardIter> 103*f8a1b7d9SAlexander Kabaev (__last, std::uninitialized_copy(__first, __last, __result))); 10400db7afdSDavid E. O'Brien } 10500db7afdSDavid E. O'Brien 10600db7afdSDavid E. O'Brien template<typename _InputIter, typename _Size, typename _ForwardIter> 10700db7afdSDavid E. O'Brien inline pair<_InputIter, _ForwardIter> 10800db7afdSDavid E. O'Brien __uninitialized_copy_n(_InputIter __first, _Size __count, 109ffeaf689SAlexander Kabaev _ForwardIter __result) 110*f8a1b7d9SAlexander Kabaev { return __uninitialized_copy_n(__first, __count, __result, 111*f8a1b7d9SAlexander Kabaev __iterator_category(__first)); } 11200db7afdSDavid E. O'Brien 11300db7afdSDavid E. O'Brien /** 11400db7afdSDavid E. O'Brien * @brief Copies the range [first,last) into result. 11500db7afdSDavid E. O'Brien * @param first An input iterator. 11600db7afdSDavid E. O'Brien * @param last An input iterator. 11700db7afdSDavid E. O'Brien * @param result An output iterator. 11800db7afdSDavid E. O'Brien * @return result + (first - last) 11900db7afdSDavid E. O'Brien * @ingroup SGIextensions 12000db7afdSDavid E. O'Brien * 12100db7afdSDavid E. O'Brien * Like copy(), but does not require an initialized output range. 12200db7afdSDavid E. O'Brien */ 12300db7afdSDavid E. O'Brien template<typename _InputIter, typename _Size, typename _ForwardIter> 12400db7afdSDavid E. O'Brien inline pair<_InputIter, _ForwardIter> 12500db7afdSDavid E. O'Brien uninitialized_copy_n(_InputIter __first, _Size __count, 126ffeaf689SAlexander Kabaev _ForwardIter __result) 127*f8a1b7d9SAlexander Kabaev { return __uninitialized_copy_n(__first, __count, __result, 128*f8a1b7d9SAlexander Kabaev __iterator_category(__first)); } 129*f8a1b7d9SAlexander Kabaev 130*f8a1b7d9SAlexander Kabaev 131*f8a1b7d9SAlexander Kabaev // An alternative version of uninitialized_copy_n that constructs 132*f8a1b7d9SAlexander Kabaev // and destroys objects with a user-provided allocator. 133*f8a1b7d9SAlexander Kabaev template<typename _InputIter, typename _Size, typename _ForwardIter, 134*f8a1b7d9SAlexander Kabaev typename _Allocator> 135*f8a1b7d9SAlexander Kabaev pair<_InputIter, _ForwardIter> 136*f8a1b7d9SAlexander Kabaev __uninitialized_copy_n_a(_InputIter __first, _Size __count, 137*f8a1b7d9SAlexander Kabaev _ForwardIter __result, 138*f8a1b7d9SAlexander Kabaev _Allocator __alloc) 139ffeaf689SAlexander Kabaev { 140*f8a1b7d9SAlexander Kabaev _ForwardIter __cur = __result; 141*f8a1b7d9SAlexander Kabaev try 142*f8a1b7d9SAlexander Kabaev { 143*f8a1b7d9SAlexander Kabaev for (; __count > 0 ; --__count, ++__first, ++__cur) 144*f8a1b7d9SAlexander Kabaev __alloc.construct(&*__cur, *__first); 145*f8a1b7d9SAlexander Kabaev return pair<_InputIter, _ForwardIter>(__first, __cur); 146*f8a1b7d9SAlexander Kabaev } 147*f8a1b7d9SAlexander Kabaev catch(...) 148*f8a1b7d9SAlexander Kabaev { 149*f8a1b7d9SAlexander Kabaev std::_Destroy(__result, __cur, __alloc); 150*f8a1b7d9SAlexander Kabaev __throw_exception_again; 151*f8a1b7d9SAlexander Kabaev } 15200db7afdSDavid E. O'Brien } 15300db7afdSDavid E. O'Brien 154*f8a1b7d9SAlexander Kabaev template<typename _InputIter, typename _Size, typename _ForwardIter, 155*f8a1b7d9SAlexander Kabaev typename _Tp> 156*f8a1b7d9SAlexander Kabaev inline pair<_InputIter, _ForwardIter> 157*f8a1b7d9SAlexander Kabaev __uninitialized_copy_n_a(_InputIter __first, _Size __count, 158*f8a1b7d9SAlexander Kabaev _ForwardIter __result, 159*f8a1b7d9SAlexander Kabaev std::allocator<_Tp>) 160*f8a1b7d9SAlexander Kabaev { 161*f8a1b7d9SAlexander Kabaev return uninitialized_copy_n(__first, __count, __result); 162*f8a1b7d9SAlexander Kabaev } 16300db7afdSDavid E. O'Brien 16400db7afdSDavid E. O'Brien /** 16500db7afdSDavid E. O'Brien * This class provides similar behavior and semantics of the standard 16600db7afdSDavid E. O'Brien * functions get_temporary_buffer() and return_temporary_buffer(), but 16700db7afdSDavid E. O'Brien * encapsulated in a type vaguely resembling a standard container. 16800db7afdSDavid E. O'Brien * 16900db7afdSDavid E. O'Brien * By default, a temporary_buffer<Iter> stores space for objects of 17000db7afdSDavid E. O'Brien * whatever type the Iter iterator points to. It is constructed from a 17100db7afdSDavid E. O'Brien * typical [first,last) range, and provides the begin(), end(), size() 17200db7afdSDavid E. O'Brien * functions, as well as requested_size(). For non-trivial types, copies 17300db7afdSDavid E. O'Brien * of *first will be used to initialize the storage. 17400db7afdSDavid E. O'Brien * 17500db7afdSDavid E. O'Brien * @c malloc is used to obtain underlying storage. 17600db7afdSDavid E. O'Brien * 17700db7afdSDavid E. O'Brien * Like get_temporary_buffer(), not all the requested memory may be 17800db7afdSDavid E. O'Brien * available. Ideally, the created buffer will be large enough to hold a 17900db7afdSDavid E. O'Brien * copy of [first,last), but if size() is less than requested_size(), 18000db7afdSDavid E. O'Brien * then this didn't happen. 18100db7afdSDavid E. O'Brien * 18200db7afdSDavid E. O'Brien * @ingroup SGIextensions 18300db7afdSDavid E. O'Brien */ 184ffeaf689SAlexander Kabaev template <class _ForwardIterator, class _Tp 18500db7afdSDavid E. O'Brien = typename std::iterator_traits<_ForwardIterator>::value_type > 18600db7afdSDavid E. O'Brien struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> 18700db7afdSDavid E. O'Brien { 18800db7afdSDavid E. O'Brien /// Requests storage large enough to hold a copy of [first,last). 18900db7afdSDavid E. O'Brien temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) 19000db7afdSDavid E. O'Brien : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } 191ffeaf689SAlexander Kabaev 19200db7afdSDavid E. O'Brien /// Destroys objects and frees storage. 19300db7afdSDavid E. O'Brien ~temporary_buffer() { } 19400db7afdSDavid E. O'Brien }; 195*f8a1b7d9SAlexander Kabaev 196*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE 19700db7afdSDavid E. O'Brien 198ffeaf689SAlexander Kabaev#endif 19900db7afdSDavid E. O'Brien 200