Here's a port of C++'s std::auto_ptr. This type of smart pointer is useful when you need a short-lived dynamic resource. The smart pointer will destroy the pointed-to memory when it goes out of scope.
Here's the header:
Code: Select all
':: Copyright (C) 2006
':: Laanan Fisher (stylinize@gmail.com)
':: Copyright (C) 2001, 2002, 2004
':: Free Software Foundation, Inc.
':: Copyright (c) 1997-1999
':: Silicon Graphics Computer Systems, Inc.
':: This file is free software; you can redistribute it and/or modify
':: it under the terms of the GNU General Public License as published
':: by the Free Software Foundation; either version 2, or (at your option)
':: any later version.
':: This file is distributed in the hope that it will be useful,
':: but WITHOUT ANY WARRANTY; without even the implied warranty of
':: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
':: GNU General Public License for more details.
':: You should have received a copy of the GNU General Public License along
':: with this file; see the file COPYING. If not, write to the Free
':: Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
':: USA.
':: As a special exception, you may use this file as part of a free software
':: library without restriction. Specifically, if other files instantiate
':: templates or use macros or inline functions from this file, or you compile
':: this file and link it with other files to produce an executable, this
':: file does not by itself cause the resulting executable to be covered by
':: the GNU General Public License. This exception does not however
':: invalidate any other reasons why the executable file might be covered by
':: the GNU General Public License.
/'
auto_ptr.bi : port of C++'s std::auto_ptr
'/
# macro DECLARE_AUTO_PTR(T)
# ifdef DECLARED_AUTO_PTR##T
# error auto_ptr already declared for type T
# endif
# define DECLARED_AUTO_PTR##T
# ifdef DEFINED_AUTO_PTR##T
# error auto_ptr already defined for type T
# endif
/'
A smart pointer with strict-ownership semantics.
Resources are not allowed to be shared, an auto_ptr
is the sole owner of it's memory - (copying an
auto_ptr transfers ownership and invalidates the
previous auto_ptr).
'/
type auto_ptr##T
public:
':: Construct/Copy/Destroy/Assign
' Constructs an auto_ptr from a raw pointer.
declare constructor (p as T ptr = 0)
' Copy constructs an auto_ptr from another.
declare constructor (byref x as auto_ptr##T)
' Destroys an auto_ptr and any memory it owns.
declare destructor ()
' Transfers ownership of memory from another.
declare operator let (byref x as auto_ptr##T)
' Returns the address of the owned memory for lack
' of reference returns, identical to @*p.
declare function derefaddr () as T ptr
' Returns the address of the owned memory.
declare function get () as T ptr
' Releases ownership of and returns memory.
declare function release () as T ptr
' Transfers ownership from another raw pointer.
declare sub reset (p as T ptr = 0)
private:
' the raw pointer.
m_p as T ptr
end type
# endmacro '// DECLARE_AUTO_PTR
# macro DEFINE_AUTO_PTR(T)
# ifdef DEFINED_AUTO_PTR##T
# error auto_ptr already defined for type T
# endif
# ifndef DECLARED_AUTO_PTR##T
DECLARE_AUTO_PTR(T)
# endif
# define DEFINED_AUTO_PTR##T
constructor auto_ptr##T (p as T ptr)
m_p = p
end constructor
constructor auto_ptr##T (byref x as auto_ptr##T)
m_p = x.release()
end constructor
operator auto_ptr##T.let (byref x as auto_ptr##T)
reset(x.release())
end operator
destructor auto_ptr##T ()
' WORKAROUND: need NULL ptr check so dtors
' aren't called.
if (0 <> m_p) then
delete m_p
end if
end destructor
function auto_ptr##T.derefaddr () as T ptr
' assert enforces dereference semantics
ASSERT( m_p <> 0 )
function = m_p
end function
function auto_ptr##T.get () as T ptr
function = m_p
end function
function auto_ptr##T.release () as T ptr
dim tmp as T ptr = m_p
m_p = 0
function = tmp
end function
sub auto_ptr##T.reset (p as T ptr)
if (p <> m_p) then
' WORKAROUND: need NULL ptr check so dtors
' aren't called.
if (0 <> m_p) then
delete m_p
end if
m_p = p
end if
end sub
# endmacro '// DEFINE_AUTO_PTR
Code: Select all
# include "auto_ptr.bi"
type T
declare destructor ()
member as integer
end type
destructor T ()
print "T::~T()"
end destructor
' define auto_ptr for T types
DEFINE_AUTO_PTR(T)
scope
' create an auto_ptr
dim ap1 as auto_ptrT = new T
' dereference the auto_ptr
ap1.derefaddr()->member = 420
' transfer ownership of the pointer, ap1 is now
' an invalid auto_ptr
dim ap2 as auto_ptrT = ap1
print ap2.derefaddr()->member
end scope ' <-- mem is destroyed (once)