std_memory.h revision 97403
197403Sobrien// <memory> -*- C++ -*- 297403Sobrien 397403Sobrien// Copyright (C) 2001, 2002 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 1897403Sobrien// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 * Copyright (c) 1997-1999 3297403Sobrien * Silicon Graphics Computer Systems, Inc. 3397403Sobrien * 3497403Sobrien * Permission to use, copy, modify, distribute and sell this software 3597403Sobrien * and its documentation for any purpose is hereby granted without fee, 3697403Sobrien * provided that the above copyright notice appear in all copies and 3797403Sobrien * that both that copyright notice and this permission notice appear 3897403Sobrien * in supporting documentation. Silicon Graphics makes no 3997403Sobrien * representations about the suitability of this software for any 4097403Sobrien * purpose. It is provided "as is" without express or implied warranty. 4197403Sobrien * 4297403Sobrien */ 4397403Sobrien 4497403Sobrien/** @file memory 4597403Sobrien * This is a Standard C++ Library header. You should @c #include this header 4697403Sobrien * in your programs, rather than any of the "st[dl]_*.h" implementation files. 4797403Sobrien */ 4897403Sobrien 4997403Sobrien#ifndef _CPP_MEMORY 5097403Sobrien#define _CPP_MEMORY 1 5197403Sobrien 5297403Sobrien#pragma GCC system_header 5397403Sobrien 5497403Sobrien#include <bits/stl_algobase.h> 5597403Sobrien#include <bits/stl_alloc.h> 5697403Sobrien#include <bits/stl_construct.h> 5797403Sobrien#include <bits/stl_iterator_base_types.h> //for iterator_traits 5897403Sobrien#include <bits/stl_uninitialized.h> 5997403Sobrien#include <bits/stl_raw_storage_iter.h> 6097403Sobrien 6197403Sobriennamespace std 6297403Sobrien{ 6397403Sobrien 6497403Sobrien /** 6597403Sobrien * @if maint 6697403Sobrien * This is a helper function. The unused second parameter exists to 6797403Sobrien * permit the real get_temporary_buffer to use template parameter deduction. 6897403Sobrien * @endif 6997403Sobrien */ 7097403Sobrien template <class _Tp> 7197403Sobrien pair<_Tp*, ptrdiff_t> 7297403Sobrien __get_temporary_buffer(ptrdiff_t __len, _Tp*) 7397403Sobrien { 7497403Sobrien if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) 7597403Sobrien __len = INT_MAX / sizeof(_Tp); 7697403Sobrien 7797403Sobrien while (__len > 0) { 7897403Sobrien _Tp* __tmp = (_Tp*) std::malloc((std::size_t)__len * sizeof(_Tp)); 7997403Sobrien if (__tmp != 0) 8097403Sobrien return pair<_Tp*, ptrdiff_t>(__tmp, __len); 8197403Sobrien __len /= 2; 8297403Sobrien } 8397403Sobrien 8497403Sobrien return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); 8597403Sobrien } 8697403Sobrien 8797403Sobrien /** 8897403Sobrien * @brief This is a mostly-useless wrapper around malloc(). 8997403Sobrien * @param len The number of objects of type Tp. 9097403Sobrien * @return See full description. 9197403Sobrien * 9297403Sobrien * Reinventing the wheel, but this time with prettier spokes! 9397403Sobrien * 9497403Sobrien * This function tries to obtain storage for @c len adjacent Tp objects. 9597403Sobrien * The objects themselves are not constructed, of course. A pair<> is 9697403Sobrien * returned containing "the buffer s address and capacity (in the units of 9797403Sobrien * sizeof(Tp)), or a pair of 0 values if no storage can be obtained." 9897403Sobrien * Note that the capacity obtained may be less than that requested if the 9997403Sobrien * memory is unavailable; you should compare len with the .second return 10097403Sobrien * value. 10197403Sobrien */ 10297403Sobrien template <class _Tp> 10397403Sobrien inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { 10497403Sobrien return __get_temporary_buffer(__len, (_Tp*) 0); 10597403Sobrien } 10697403Sobrien 10797403Sobrien /** 10897403Sobrien * @brief The companion to get_temporary_buffer(). 10997403Sobrien * @param p A buffer previously allocated by get_temporary_buffer. 11097403Sobrien * @return None. 11197403Sobrien * 11297403Sobrien * Frees the memory pointed to by p. 11397403Sobrien */ 11497403Sobrien template <class _Tp> 11597403Sobrien void return_temporary_buffer(_Tp* __p) { 11697403Sobrien std::free(__p); 11797403Sobrien } 11897403Sobrien 11997403Sobrien 12097403Sobrientemplate <class _Tp1> 12197403Sobrien struct auto_ptr_ref 12297403Sobrien{ 12397403Sobrien _Tp1* _M_ptr; 12497403Sobrien auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} 12597403Sobrien}; 12697403Sobrien 12797403Sobrien/** 12897403Sobrien * A simple smart pointer providing strict ownership semantics. (More later.) 12997403Sobrien*/ 13097403Sobrientemplate <class _Tp> 13197403Sobrien class auto_ptr 13297403Sobrien{ 13397403Sobrienprivate: 13497403Sobrien _Tp* _M_ptr; 13597403Sobrien 13697403Sobrienpublic: 13797403Sobrien typedef _Tp element_type; 13897403Sobrien 13997403Sobrien explicit auto_ptr(_Tp* __p = 0) throw() : _M_ptr(__p) {} 14097403Sobrien auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) {} 14197403Sobrien 14297403Sobrien template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) throw() 14397403Sobrien : _M_ptr(__a.release()) {} 14497403Sobrien 14597403Sobrien auto_ptr& operator=(auto_ptr& __a) throw() { 14697403Sobrien reset(__a.release()); 14797403Sobrien return *this; 14897403Sobrien } 14997403Sobrien 15097403Sobrien template <class _Tp1> 15197403Sobrien auto_ptr& operator=(auto_ptr<_Tp1>& __a) throw() { 15297403Sobrien reset(__a.release()); 15397403Sobrien return *this; 15497403Sobrien } 15597403Sobrien 15697403Sobrien // Note: The C++ standard says there is supposed to be an empty throw 15797403Sobrien // specification here, but omitting it is standard conforming. Its 15897403Sobrien // presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2) 15997403Sobrien // this is prohibited. 16097403Sobrien ~auto_ptr() { delete _M_ptr; } 16197403Sobrien 16297403Sobrien _Tp& operator*() const throw() { 16397403Sobrien return *_M_ptr; 16497403Sobrien } 16597403Sobrien _Tp* operator->() const throw() { 16697403Sobrien return _M_ptr; 16797403Sobrien } 16897403Sobrien _Tp* get() const throw() { 16997403Sobrien return _M_ptr; 17097403Sobrien } 17197403Sobrien _Tp* release() throw() { 17297403Sobrien _Tp* __tmp = _M_ptr; 17397403Sobrien _M_ptr = 0; 17497403Sobrien return __tmp; 17597403Sobrien } 17697403Sobrien void reset(_Tp* __p = 0) throw() { 17797403Sobrien if (__p != _M_ptr) { 17897403Sobrien delete _M_ptr; 17997403Sobrien _M_ptr = __p; 18097403Sobrien } 18197403Sobrien } 18297403Sobrien 18397403Sobrienpublic: 18497403Sobrien auto_ptr(auto_ptr_ref<_Tp> __ref) throw() 18597403Sobrien : _M_ptr(__ref._M_ptr) {} 18697403Sobrien 18797403Sobrien auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) throw() { 18897403Sobrien if (__ref._M_ptr != this->get()) { 18997403Sobrien delete _M_ptr; 19097403Sobrien _M_ptr = __ref._M_ptr; 19197403Sobrien } 19297403Sobrien return *this; 19397403Sobrien } 19497403Sobrien 19597403Sobrien template <class _Tp1> operator auto_ptr_ref<_Tp1>() throw() 19697403Sobrien { return auto_ptr_ref<_Tp>(this->release()); } 19797403Sobrien template <class _Tp1> operator auto_ptr<_Tp1>() throw() 19897403Sobrien { return auto_ptr<_Tp1>(this->release()); } 19997403Sobrien}; 20097403Sobrien 20197403Sobrien} // namespace std 20297403Sobrien 20397403Sobrien#endif /* _CPP_MEMORY */ 20497403Sobrien 205