[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[paragui-users] reference-counter test
From: |
Andrew Ford |
Subject: |
[paragui-users] reference-counter test |
Date: |
Thu, 9 May 2002 10:52:02 -0700 (PDT) |
Hi guys,
This is a little test reference counter I wrote as a
"proof-of-concept" for the widget reference counter
Alex and me have been talking about. I would
appreciate it very much if you would test it on your
compilers (particularly codewarrior, which I know some
of you are using). It has been tested on gcc 2.96 and
vc6sp5. The potential problem with it is the crummy
template handling in many compilers (particularly
visual C++, which is a piece of crap, frankly). I
don't suppose anybody is using one of the borland C++
compilers are they? Does anybody happen to have any
comments, did I screw something up?
Anyway, a list of compilers I'd like to know this
works on:
codewarrior (what versions?)
intel C++
borland C++ ( 5+ )
gcc 2.95.3 and 3.x, as well as cygwin and mingw32.
maybe other unix compilers if anybody is using them :)
thanks,
Andrew.
__________________________________________________
Do You Yahoo!?
Yahoo! Shopping - Mother's Day is May 12th!
http://shopping.yahoo.com
// File: pgref.h
// reference counted (semi)smart pointers intended for paragui use.
#ifndef _PGREF_H_
#define _PGREF_H_
typedef unsigned int Uint32;
#include <functional>
#if defined( _MSC_VER )
#define PARAGUI_ANTISOCIAL_COMPILER
#endif
template< typename T > class ref
// Simple non-customizable reference-counted smart pointer for
// incidentals like file lists and other non-widgets that need to be
// cleaned up after use.
{
public:
ref( const ref &other )
{
refObject = other.refObject;
refCount = other.refCount;
++(*refCount);
}
void operator=( ref &other )
{
if( refCount != NULL )
// We're pointing to something, so release the
reference.
{
decRef();
}
refObject = other.refObject;
refCount = other.refCount;
++(*refCount);
}
~ref()
{
if( refCount != NULL ) // We haven't been reset.
{
decRef();
}
}
T& operator*()
{
return *refObject;
}
T* operator->()
{
return refObject;
}
ref() // Here be dragons. Be careful.
{}
#ifndef PARAGUI_ANTISOCIAL_COMPILER // Doesn't like these friends.
// I need to know if these work in all compilers, otherwise
we'll define the above for those compilers.
friend ref< T > createRef< T >( T *object );
friend void resetRef< T >( ref< T > &r );
friend Uint32 getRefCount< T >( const ref< T > &r );
friend T *getRealPointer< T >( const ref< T > &r );
protected:
#endif // PARAGUI_ANTISOCIAL_COMPILER
void decRef()
{
--(*refCount);
if( *refCount == 0 )
// No more referers, delete the object...
{
delete refCount;
delete refObject; // May want to use an
allocator object for this.
}
}
T *refObject;
Uint32 *refCount;
};
// The reference types shouldn't have member functions, so these are defined
outside ref.
// Think about confusing ref.reset() with ref->reset() in the pointee, for
instance.
template< typename T > ref< T > createRef( T *object )
{
ref< T > temp;
temp.refObject = object;
temp.refCount = new Uint32;
*(temp.refCount) = 1;
return temp;
}
template< typename T > Uint32 getRefCount( const ref< T > &r )
{
return *(r.refCount);
}
template< typename T > T *getRealPointer( const ref< T > &r )
{
return r.refObject;
}
template< typename T > void resetRef( ref< T > &r )
// Beware, after calling this r should be treated as uninitialized.
{
r.decRef();
r.refObject = NULL;
r.refCount = NULL;
}
template< typename T > class lessRef :
public std::binary_function< ref< T >, ref< T >, bool >
// An adaptable std::less functor for your convenience.
// I can't seem to specialize std::less< ref< T > >, thanks
// to visual C++...
{
bool operator()( ref< T > &lhs, ref< T > &rhs ) const
{
return std::less< T* >( getRealPointer( lhs ), getRealPointer(
rhs ) );
}
};
#endif // pgref.h
#include <iostream>
#include <vector>
#include <string>
#include "pgref.h"
typedef ref< int > intref;
using namespace std;
// Something a little more substantial to half-assedly test the instantiation.
typedef std::vector< std::string > filenameVect;
typedef ref< filenameVect > filenameVectRef;
void dummyFunc( filenameVectRef &fvr )
// Lets instantiate some stuff!
{
filenameVect *temp = new filenameVect;
*temp = *getRealPointer( fvr ); // Copies the pointee.
filenameVectRef fvr2 = createRef( temp ); // Now we can forget about
temp, since fvr2 owns it.
std::cerr << "How many refs? (should be 1) " << getRefCount( fvr2 ) <<
endl;
// Hmm, I've changed my mind, I don't want this anymore...
resetRef( fvr2 );
}
int main( int argc, char **argv )
{
#if defined( MWCW )
std::cerr << "Hey look! I successfully detected codewarrior!" << endl;
#endif
intref a( createRef( new int ) );
intref b( a );
intref c( a );
resetRef( c );
intref d( b );
// We've referenced four times, and reset once, so this should be three:
std::cerr << "Reference Count: (should be 3) " << getRefCount( a ) <<
endl;
std::cerr << "Here's the address of the pointee: " << getRealPointer( a
) << endl;
filenameVectRef fvr( createRef( new filenameVect( 10 ) ) );
dummyFunc( fvr );
return 0;
}
- [paragui-users] vacation & release candidate, Alexander Pipelka, 2002/05/07
- Re: [paragui-users] vacation & release candidate, Andrew Ford, 2002/05/07
- [paragui-users] PG_FileArchive patch, Andrew Ford, 2002/05/07
- Re: [paragui-users] PG_FileArchive patch, Alexander Pipelka, 2002/05/27
- Re: [paragui-users] PG_FileArchive patch, Andrew Ford, 2002/05/27
- Re: [paragui-users] PG_FileArchive patch, Alexander Pipelka, 2002/05/27
- Re: [paragui-users] PG_FileArchive patch, Andrew Ford, 2002/05/27
- Re: [paragui-users] PG_FileArchive patch, Alexander Pipelka, 2002/05/27
- Re: [paragui-users] PG_FileArchive patch, Andrew Ford, 2002/05/27