904 lines
25 KiB
Plaintext
904 lines
25 KiB
Plaintext
|
///////////////////////////////////////////////////////////////////////////
|
||
|
// FILE: memory (Utilities for manipulating memory)
|
||
|
//
|
||
|
// =========================================================================
|
||
|
//
|
||
|
// Open Watcom Project
|
||
|
//
|
||
|
// Copyright (c) 2004-2010 The Open Watcom Contributors. All Rights Reserved.
|
||
|
//
|
||
|
// This file is automatically generated. Do not edit directly.
|
||
|
//
|
||
|
// =========================================================================
|
||
|
//
|
||
|
// Description: This header is part of the C++ standard library. It
|
||
|
// defines a number of helper templates to simplify the
|
||
|
// handling of raw memory.
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
#ifndef _MEMORY_INCLUDED
|
||
|
#define _MEMORY_INCLUDED
|
||
|
|
||
|
#ifndef _ENABLE_AUTODEPEND
|
||
|
#pragma read_only_file;
|
||
|
#endif
|
||
|
|
||
|
#ifndef __cplusplus
|
||
|
#error This header file requires C++
|
||
|
#endif
|
||
|
|
||
|
#ifndef _CSTDDEF_INCLUDED
|
||
|
#include <cstddef>
|
||
|
#endif
|
||
|
|
||
|
#ifndef _ITERATOR_INCLUDED
|
||
|
#include <iterator>
|
||
|
#endif
|
||
|
|
||
|
#ifndef _NEW_INCLUDED
|
||
|
#include <new>
|
||
|
#endif
|
||
|
|
||
|
#ifndef _TYPEINFO_INCLUDED
|
||
|
#include <typeinfo>
|
||
|
#endif
|
||
|
|
||
|
#ifndef _WC_EXCEPTION_MACROS_
|
||
|
#define _WC_EXCEPTION_MACROS_
|
||
|
#ifdef _CPPUNWIND
|
||
|
#define _WCTHROWS( __t ) throw( __t ) // Use for exception specifications.
|
||
|
#define _WCTHROW( __t ) throw( __t ) // Use for throw statements.
|
||
|
#define _WCTRY try
|
||
|
#define _WCHANDLERS 1
|
||
|
#else
|
||
|
#define _WCTHROWS( __t )
|
||
|
#define _WCTHROW( __t )
|
||
|
#define _WCTRY
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
template< class Iterator, class Type >
|
||
|
inline void _RawConstruct( Iterator ptr, const Type &value )
|
||
|
{
|
||
|
typedef typename std::iterator_traits< Iterator >::value_type value_type;
|
||
|
new ( static_cast< void * >( &*ptr ) ) value_type( value );
|
||
|
}
|
||
|
|
||
|
template< class Iterator >
|
||
|
inline void _RawDestroy( Iterator ptr )
|
||
|
{
|
||
|
typedef typename std::iterator_traits< Iterator >::value_type value_type;
|
||
|
( *ptr ).~value_type( );
|
||
|
}
|
||
|
|
||
|
namespace std {
|
||
|
|
||
|
template< class Type > class allocator;
|
||
|
|
||
|
// Allocator specialization for void
|
||
|
// *********************************
|
||
|
|
||
|
template< >
|
||
|
class allocator< void > {
|
||
|
public:
|
||
|
typedef void *pointer;
|
||
|
typedef const void *const_pointer;
|
||
|
typedef void value_type;
|
||
|
|
||
|
template< class Type2 >
|
||
|
struct rebind { typedef allocator< Type2 > other; };
|
||
|
};
|
||
|
|
||
|
// Default allocator template
|
||
|
// **************************
|
||
|
|
||
|
template< class Type >
|
||
|
class allocator {
|
||
|
public:
|
||
|
typedef std::size_t size_type;
|
||
|
typedef std::ptrdiff_t difference_type;
|
||
|
typedef Type *pointer;
|
||
|
typedef const Type *const_pointer;
|
||
|
typedef Type &reference;
|
||
|
typedef const Type &const_reference;
|
||
|
typedef Type value_type;
|
||
|
|
||
|
template< class Type2 >
|
||
|
struct rebind { typedef allocator< Type2 > other; };
|
||
|
|
||
|
allocator( )
|
||
|
{ }
|
||
|
|
||
|
allocator( const allocator & )
|
||
|
{ }
|
||
|
|
||
|
template< class Type2 >
|
||
|
allocator( const allocator< Type2 > & )
|
||
|
{ }
|
||
|
|
||
|
~allocator( )
|
||
|
{ }
|
||
|
|
||
|
pointer address( reference r ) const
|
||
|
{ return( &r ); }
|
||
|
|
||
|
const_pointer address( const_reference r ) const
|
||
|
{ return( &r ); }
|
||
|
|
||
|
pointer allocate( size_type n, allocator< void >::const_pointer = 0 )
|
||
|
{ return( reinterpret_cast< Type * >(
|
||
|
::operator new( n * sizeof( Type ) ) ) ); }
|
||
|
|
||
|
void deallocate( pointer p, size_type )
|
||
|
{ ::operator delete( reinterpret_cast< unsigned char * >( p ) ); }
|
||
|
|
||
|
size_type max_size( ) const
|
||
|
{ return 0; } // FIX ME
|
||
|
|
||
|
void construct( pointer p, const Type &value )
|
||
|
{ new ( ( void * )p ) Type( value ); }
|
||
|
|
||
|
void destroy( pointer p )
|
||
|
{ ( ( Type * )p )->~Type( ); }
|
||
|
};
|
||
|
|
||
|
// Raw storage iterator
|
||
|
// ********************
|
||
|
|
||
|
template< class OutputIterator, class Type >
|
||
|
class raw_storage_iterator
|
||
|
: public iterator< output_iterator_tag, void, void, void, void > {
|
||
|
public:
|
||
|
explicit raw_storage_iterator( OutputIterator it ) : ptr( it )
|
||
|
{ }
|
||
|
raw_storage_iterator &operator*( )
|
||
|
{ return( *this ); }
|
||
|
raw_storage_iterator &operator=( const Type & incoming )
|
||
|
{ _RawConstruct( ptr, incoming ); return( *this ); }
|
||
|
raw_storage_iterator &operator++( )
|
||
|
{ ++ptr; return( *this ); }
|
||
|
raw_storage_iterator operator++( int )
|
||
|
{ raw_storage_iterator temp( *this ); ++ptr; return( temp ); }
|
||
|
private:
|
||
|
OutputIterator ptr;
|
||
|
};
|
||
|
|
||
|
|
||
|
// Temporary Buffers
|
||
|
// *****************
|
||
|
|
||
|
// Need compiler support for explicit function template arguments.
|
||
|
|
||
|
// Templates for initializing blocks of uninitialized memory
|
||
|
// *********************************************************
|
||
|
|
||
|
template< class ForwardIterator, class Type >
|
||
|
void uninitialized_fill(
|
||
|
ForwardIterator first,
|
||
|
ForwardIterator last,
|
||
|
const Type &value )
|
||
|
{
|
||
|
typedef
|
||
|
typename iterator_traits< ForwardIterator >::value_type value_type;
|
||
|
ForwardIterator bookmark( first );
|
||
|
|
||
|
_WCTRY {
|
||
|
// Construct copies of value in the raw storage.
|
||
|
while( first != last ) {
|
||
|
_RawConstruct( first, value );
|
||
|
++first;
|
||
|
}
|
||
|
}
|
||
|
#ifdef _WCHANDLERS
|
||
|
// If an exception occurs, destroy copies that were made successfully.
|
||
|
catch( ... ) {
|
||
|
while( bookmark != first ) {
|
||
|
_RawDestroy( bookmark );
|
||
|
++bookmark;
|
||
|
}
|
||
|
throw;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class ForwardIterator, class Size, class Type >
|
||
|
void uninitialized_fill_n(
|
||
|
ForwardIterator first,
|
||
|
Size n,
|
||
|
const Type &value )
|
||
|
{
|
||
|
typedef
|
||
|
typename iterator_traits< ForwardIterator >::value_type value_type;
|
||
|
ForwardIterator bookmark( first );
|
||
|
|
||
|
_WCTRY {
|
||
|
// Construct n copies of value in raw storage.
|
||
|
while( n-- ) {
|
||
|
_RawConstruct( first, value );
|
||
|
++first;
|
||
|
}
|
||
|
}
|
||
|
#ifdef _WCHANDLERS
|
||
|
// If an exception occurs, destroy copies that were made successfully.
|
||
|
catch( ... ) {
|
||
|
while( bookmark != first ) {
|
||
|
_RawDestroy( bookmark );
|
||
|
++bookmark;
|
||
|
}
|
||
|
throw;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class InputIterator, class ForwardIterator >
|
||
|
ForwardIterator uninitialized_copy(
|
||
|
InputIterator first,
|
||
|
InputIterator last,
|
||
|
ForwardIterator dest )
|
||
|
{
|
||
|
typedef
|
||
|
typename iterator_traits< ForwardIterator >::value_type value_type;
|
||
|
ForwardIterator bookmark( dest );
|
||
|
|
||
|
_WCTRY {
|
||
|
// Copy objects from input sequence to raw storage.
|
||
|
while( first != last ) {
|
||
|
_RawConstruct( dest, *first );
|
||
|
++first;
|
||
|
++dest;
|
||
|
}
|
||
|
return( dest );
|
||
|
}
|
||
|
#ifdef _WCHANDLERS
|
||
|
// If an exception occurs, destroy copies that were made successfully.
|
||
|
catch( ... ) {
|
||
|
while( bookmark != dest ) {
|
||
|
_RawDestroy( bookmark );
|
||
|
++bookmark;
|
||
|
}
|
||
|
throw;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
// auto_ptr template
|
||
|
// *****************
|
||
|
|
||
|
template< class Type > struct auto_ptr;
|
||
|
|
||
|
template< class Type >
|
||
|
struct auto_ptr_ref {
|
||
|
auto_ptr< Type > &ref;
|
||
|
auto_ptr_ref( auto_ptr< Type > &r ) : ref( r ) { }
|
||
|
};
|
||
|
|
||
|
template< class Type >
|
||
|
class auto_ptr {
|
||
|
public:
|
||
|
typedef Type element_type;
|
||
|
|
||
|
explicit auto_ptr( Type *p = 0 ) : ptr( p )
|
||
|
{ }
|
||
|
|
||
|
auto_ptr( auto_ptr &other ) : ptr( other.release( ) )
|
||
|
{ }
|
||
|
|
||
|
template< class Type2 >
|
||
|
auto_ptr( auto_ptr< Type2 > &other ) :
|
||
|
ptr( static_cast< Type * >( other.release( ) ) )
|
||
|
{ }
|
||
|
|
||
|
auto_ptr &operator=( auto_ptr &other )
|
||
|
{ reset( other.release( ) ); return( *this ); }
|
||
|
|
||
|
template< class Type2 >
|
||
|
auto_ptr &operator=( auto_ptr< Type2 > &other )
|
||
|
{ reset( static_cast< Type * >( other.release( ) ) ); return ( *this ); }
|
||
|
|
||
|
~auto_ptr( ) _WCTHROWS( )
|
||
|
{ delete ptr; }
|
||
|
|
||
|
Type &operator*( ) const
|
||
|
{ return( *ptr ); }
|
||
|
|
||
|
Type *operator->( ) const
|
||
|
{ return( ptr ); }
|
||
|
|
||
|
Type *get( ) const
|
||
|
{ return( ptr ); }
|
||
|
|
||
|
Type *release( )
|
||
|
{ Type *tmp = ptr; ptr = 0; return( tmp ); }
|
||
|
|
||
|
void reset( Type *p = 0 ) _WCTHROWS( )
|
||
|
{ if ( ptr != p ) delete ptr; ptr = p; }
|
||
|
|
||
|
auto_ptr( auto_ptr_ref< Type > r ) : ptr( r.ref.release( ) )
|
||
|
{ }
|
||
|
|
||
|
// template< class Type2 >
|
||
|
// operator auto_ptr_ref< Type2 >( )
|
||
|
// { return( auto_ptr_ref< Type2 >( *this ); }
|
||
|
|
||
|
// template< class Type2 >
|
||
|
// operator auto_ptr< Type2 >( )
|
||
|
// { }
|
||
|
|
||
|
private:
|
||
|
Type *ptr;
|
||
|
};
|
||
|
|
||
|
|
||
|
// bad_weak_ptr class
|
||
|
// ******************
|
||
|
|
||
|
class bad_weak_ptr : public std::exception {
|
||
|
public:
|
||
|
bad_weak_ptr( ) { }
|
||
|
virtual const char *what( ) const
|
||
|
{ return "bad_weak_ptr"; }
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
// shared_ptr template
|
||
|
// *******************
|
||
|
|
||
|
template< class T > class weak_ptr;
|
||
|
template< class T > class enable_shared_from_this;
|
||
|
|
||
|
namespace detail {
|
||
|
class shared_holder;
|
||
|
template< class T > class shared_holder_ptr;
|
||
|
template< class T, class D > class shared_holder_deleter;
|
||
|
|
||
|
struct static_pointer_cast_tag { };
|
||
|
struct dynamic_pointer_cast_tag { };
|
||
|
struct const_pointer_cast_tag { };
|
||
|
}
|
||
|
|
||
|
template< class T > class shared_ptr {
|
||
|
public:
|
||
|
typedef T element_type;
|
||
|
|
||
|
// constructors
|
||
|
shared_ptr( ) : ptr( 0 ), holder( 0 ) { }
|
||
|
|
||
|
template< class Y > explicit shared_ptr( Y *p ) : ptr( p )
|
||
|
{
|
||
|
try {
|
||
|
holder = new detail::shared_holder_ptr< T >( ptr, 1 );
|
||
|
}
|
||
|
catch( ... ) {
|
||
|
delete ptr;
|
||
|
throw;
|
||
|
}
|
||
|
check_enable_shared_from_this( p );
|
||
|
}
|
||
|
|
||
|
template< class Y, class D > shared_ptr( Y *p, D d ) : ptr( p )
|
||
|
{
|
||
|
try {
|
||
|
holder = new detail::shared_holder_deleter< T, D >( ptr, d, 1 );
|
||
|
}
|
||
|
catch( ... ) {
|
||
|
d( ptr );
|
||
|
throw;
|
||
|
}
|
||
|
check_enable_shared_from_this( p );
|
||
|
}
|
||
|
|
||
|
shared_ptr( shared_ptr const &r ) : ptr( r.ptr ), holder( r.holder )
|
||
|
{
|
||
|
if( ptr && holder )
|
||
|
holder->increase_count( );
|
||
|
}
|
||
|
|
||
|
template< class Y >
|
||
|
shared_ptr( shared_ptr< Y > const &r ) : ptr( r.get( ) ), holder( r.get_holder( ) )
|
||
|
{
|
||
|
if( ptr && holder )
|
||
|
holder->increase_count( );
|
||
|
}
|
||
|
|
||
|
template< class Y >
|
||
|
explicit shared_ptr( weak_ptr< Y > const &r ) : ptr( r.get( ) ), holder( r.get_holder( ) )
|
||
|
{
|
||
|
if( r.expired( ) )
|
||
|
throw bad_weak_ptr( );
|
||
|
|
||
|
if( ptr && holder )
|
||
|
holder->increase_count( );
|
||
|
}
|
||
|
|
||
|
template< class Y > explicit shared_ptr( auto_ptr< Y > &r ) : ptr( r.get( ) )
|
||
|
{
|
||
|
holder = new detail::shared_holder_ptr< T >( ptr, 1 );
|
||
|
check_enable_shared_from_this( r.release( ) );
|
||
|
}
|
||
|
|
||
|
template< class Y >
|
||
|
shared_ptr( shared_ptr< Y > const &r, detail::static_pointer_cast_tag& ) :
|
||
|
ptr( static_cast< T* >( r.ptr ) ), holder( r.holder )
|
||
|
{
|
||
|
if( ptr && holder )
|
||
|
holder->increase_count( );
|
||
|
}
|
||
|
|
||
|
template< class Y >
|
||
|
shared_ptr( shared_ptr< Y > const &r, detail::dynamic_pointer_cast_tag& ) :
|
||
|
ptr( dynamic_cast< T* >( r.ptr ) ), holder( r.holder )
|
||
|
{
|
||
|
if( ptr && holder )
|
||
|
holder->increase_count( );
|
||
|
else
|
||
|
holder = 0;
|
||
|
}
|
||
|
|
||
|
template< class Y >
|
||
|
shared_ptr( shared_ptr< Y > const &r, detail::const_pointer_cast_tag& ) :
|
||
|
ptr( const_cast< T* >( r.ptr ) ), holder( r.holder )
|
||
|
{
|
||
|
if( ptr && holder )
|
||
|
holder->increase_count( );
|
||
|
}
|
||
|
|
||
|
// destructor
|
||
|
~shared_ptr( )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->decrease_count( );
|
||
|
}
|
||
|
|
||
|
// assignments
|
||
|
shared_ptr& operator=( shared_ptr const& r )
|
||
|
{
|
||
|
if( r.holder )
|
||
|
r.holder->increase_count( );
|
||
|
|
||
|
if( holder )
|
||
|
holder->decrease_count( );
|
||
|
|
||
|
ptr = r.ptr;
|
||
|
holder = r.holder;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< class Y > shared_ptr& operator=( shared_ptr< Y > const &r )
|
||
|
{
|
||
|
if( r.get_holder( ) )
|
||
|
r.get_holder( )->increase_count( );
|
||
|
|
||
|
if( holder )
|
||
|
holder->decrease_count( );
|
||
|
|
||
|
ptr = r.get( );
|
||
|
holder = r.get_holder( );
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< class Y > shared_ptr& operator=( auto_ptr< Y > &r )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->decrease_count( );
|
||
|
|
||
|
ptr = r.get( );
|
||
|
holder = new detail::shared_holder_ptr< T >( ptr, 1 );
|
||
|
check_enable_shared_from_this( r.release( ) );
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
// modifiers
|
||
|
void swap( shared_ptr &r )
|
||
|
{
|
||
|
T *tmp_ptr = ptr;
|
||
|
detail::shared_holder *tmp_holder = holder;
|
||
|
ptr = r.ptr;
|
||
|
holder = r.holder;
|
||
|
r.ptr = tmp_ptr;
|
||
|
r.holder = tmp_holder;
|
||
|
}
|
||
|
|
||
|
void reset( )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->decrease_count( );
|
||
|
|
||
|
ptr = 0;
|
||
|
holder = 0;
|
||
|
}
|
||
|
|
||
|
template< class Y > void reset( Y *p )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->decrease_count( );
|
||
|
|
||
|
ptr = p;
|
||
|
try {
|
||
|
holder = new detail::shared_holder_ptr< T >( ptr, 1 );
|
||
|
}
|
||
|
catch( ... ) {
|
||
|
delete ptr;
|
||
|
throw;
|
||
|
}
|
||
|
check_enable_shared_from_this( p );
|
||
|
}
|
||
|
|
||
|
template< class Y, class D > void reset( Y *p, D d )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->decrease_count( );
|
||
|
|
||
|
ptr = p;
|
||
|
try {
|
||
|
holder = new detail::shared_holder_deleter< T, D >( ptr, d, 1 );
|
||
|
}
|
||
|
catch( ... ) {
|
||
|
d( ptr );
|
||
|
throw;
|
||
|
}
|
||
|
check_enable_shared_from_this( p );
|
||
|
}
|
||
|
|
||
|
// observers
|
||
|
T *get( ) const
|
||
|
{ return ptr; }
|
||
|
|
||
|
T &operator*( ) const
|
||
|
{ return *ptr; }
|
||
|
|
||
|
T *operator->( ) const
|
||
|
{ return ptr; }
|
||
|
|
||
|
long use_count( ) const
|
||
|
{ return holder ? holder->use_count( ) : 0; }
|
||
|
|
||
|
bool unique( ) const
|
||
|
{ return holder && holder->use_count( ) == 1; }
|
||
|
|
||
|
operator bool( ) const
|
||
|
{ return ptr != 0; }
|
||
|
|
||
|
void *get_deleter( const type_info &ti ) const
|
||
|
{ return holder ? holder->get_deleter( ti ) : 0; }
|
||
|
|
||
|
detail::shared_holder *get_holder( ) const
|
||
|
{ return holder; }
|
||
|
|
||
|
private:
|
||
|
|
||
|
T *ptr;
|
||
|
detail::shared_holder *holder;
|
||
|
|
||
|
void check_enable_shared_from_this( enable_shared_from_this< T > *e )
|
||
|
{ if( e ) e->weak_this = *this; }
|
||
|
|
||
|
void check_enable_shared_from_this( void* ) { }
|
||
|
|
||
|
friend class shared_ptr;
|
||
|
friend class weak_ptr;
|
||
|
//friend template< class Y, class U >
|
||
|
//bool operator< ( shared_ptr< Y > const &, shared_ptr< U > const & );
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
template< class T, class U > bool operator==( shared_ptr< T > const &a,
|
||
|
shared_ptr< U > const &b )
|
||
|
{
|
||
|
return a.get( ) == b.get( );
|
||
|
}
|
||
|
|
||
|
template< class T, class U > bool operator!=( shared_ptr< T > const &a,
|
||
|
shared_ptr< U > const &b )
|
||
|
{
|
||
|
return a.get( ) != b.get( );
|
||
|
}
|
||
|
|
||
|
template< class T, class U > bool operator<( shared_ptr< T > const &a,
|
||
|
shared_ptr< U > const &b )
|
||
|
{
|
||
|
return a.get_holder( ) < b.get_holder( );
|
||
|
}
|
||
|
|
||
|
/*template< class E, class T, class Y >
|
||
|
basic_ostream< E, T > &operator<<( basic_ostream< E, T > &os,
|
||
|
shared_ptr< Y > const &p )
|
||
|
{
|
||
|
os << p.get( );
|
||
|
}*/
|
||
|
|
||
|
template< class T >
|
||
|
void swap( shared_ptr< T > &a, shared_ptr< T > &b )
|
||
|
{
|
||
|
a.swap( b );
|
||
|
}
|
||
|
|
||
|
/*template< class T, class U >
|
||
|
shared_ptr< T > static_pointer_cast( shared_ptr< U > const &r )
|
||
|
{
|
||
|
return shared_ptr< T >( r, detail::static_pointer_cast_tag( ) );
|
||
|
}*/
|
||
|
|
||
|
/*template< class T, class U >
|
||
|
shared_ptr< T > dynamic_pointer_cast( shared_ptr< U > const &r )
|
||
|
{
|
||
|
return shared_ptr< T >( r, detail::dynamic_pointer_cast_tag( ) );
|
||
|
}*/
|
||
|
|
||
|
/*template< class T, class U >
|
||
|
shared_ptr< T > const_pointer_cast( shared_ptr< U > const &r )
|
||
|
{
|
||
|
return shared_ptr< T >( r, detail::const_pointer_cast_tag( ) );
|
||
|
}*/
|
||
|
|
||
|
/*template< class D, class T > D *get_deleter( shared_ptr< T > const &p )
|
||
|
{
|
||
|
return static_cast< D* >( p.get_deleter( typeid( D ) ) );
|
||
|
}*/
|
||
|
|
||
|
// weak_ptr template
|
||
|
// *****************
|
||
|
|
||
|
template< class T > class weak_ptr {
|
||
|
public:
|
||
|
typedef T element_type;
|
||
|
|
||
|
// constructors
|
||
|
|
||
|
weak_ptr( ) : ptr( 0 ), holder( 0 ) { }
|
||
|
|
||
|
template< class Y >
|
||
|
weak_ptr( shared_ptr< Y > const &r ) : ptr( r.get( ) ), holder( r.get_holder( ) )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->increase_weak_count( );
|
||
|
}
|
||
|
|
||
|
weak_ptr( weak_ptr const &r ) : ptr( r.ptr ), holder( r.holder )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->increase_weak_count( );
|
||
|
}
|
||
|
|
||
|
template< class Y >
|
||
|
weak_ptr( weak_ptr< Y > const & r ) : ptr( r.get( ) ), holder( r.get_holder( ) )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->increase_weak_count( );
|
||
|
}
|
||
|
|
||
|
~weak_ptr( )
|
||
|
{
|
||
|
if( holder )
|
||
|
holder->decrease_weak_count( );
|
||
|
}
|
||
|
|
||
|
// assignment
|
||
|
|
||
|
weak_ptr &operator=( weak_ptr const &r )
|
||
|
{
|
||
|
if( r.holder )
|
||
|
r.holder->increase_weak_count( );
|
||
|
|
||
|
if( holder )
|
||
|
holder->decrease_weak_count( );
|
||
|
|
||
|
ptr = r.ptr;
|
||
|
holder = r.holder;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< class Y > weak_ptr &operator=( weak_ptr< Y > const &r )
|
||
|
{
|
||
|
if( r.get_holder( ) )
|
||
|
r.get_holder( )->increase_weak_count( );
|
||
|
|
||
|
if( holder )
|
||
|
holder->decrease_weak_count( );
|
||
|
|
||
|
ptr = r.get( );
|
||
|
holder = r.get_holder( );
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< class Y > weak_ptr &operator=( shared_ptr< Y > const &r )
|
||
|
{
|
||
|
if( r.get_holder( ) )
|
||
|
r.get_holder( )->increase_weak_count( );
|
||
|
|
||
|
if( holder )
|
||
|
holder->decrease_weak_count( );
|
||
|
|
||
|
ptr = r.get( );
|
||
|
holder = r.get_holder( );
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
// modifiers
|
||
|
|
||
|
void swap( weak_ptr &r )
|
||
|
{
|
||
|
T *tmp_ptr = ptr;
|
||
|
detail::shared_holder *tmp_holder = holder;
|
||
|
ptr = r.ptr;
|
||
|
holder = r.holder;
|
||
|
r.ptr = tmp_ptr;
|
||
|
r.holder = tmp_holder;
|
||
|
}
|
||
|
|
||
|
void reset( )
|
||
|
{ weak_ptr( ).swap( *this ); }
|
||
|
|
||
|
// observers
|
||
|
|
||
|
long use_count( ) const
|
||
|
{ return holder ? holder->use_count( ) : 0; }
|
||
|
|
||
|
bool expired( ) const
|
||
|
{ return holder ? holder->use_count( ) == 0 : true; }
|
||
|
|
||
|
shared_ptr< T > lock( ) const
|
||
|
{
|
||
|
if( expired( ) )
|
||
|
return shared_ptr< T >( );
|
||
|
else
|
||
|
{
|
||
|
shared_ptr< T > tmp( *this );
|
||
|
return tmp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
T *get( ) const
|
||
|
{ return ptr; }
|
||
|
|
||
|
detail::shared_holder *get_holder( ) const
|
||
|
{ return holder; }
|
||
|
|
||
|
private:
|
||
|
T *ptr;
|
||
|
detail::shared_holder *holder;
|
||
|
|
||
|
//friend template< class Y > class shared_ptr< Y >;
|
||
|
friend class shared_ptr;
|
||
|
//friend template< class Y > class weak_ptr;
|
||
|
friend class weak_ptr;
|
||
|
//friend template< class Y, class U >
|
||
|
//bool operator< ( weak_ptr< Y > const &, weak_ptr< U > const & );
|
||
|
};
|
||
|
|
||
|
template< class T, class U >
|
||
|
bool operator<( weak_ptr< T > const &a, weak_ptr< U > const &b )
|
||
|
{
|
||
|
return a.get_holder( ) < b.get_holder( );
|
||
|
}
|
||
|
|
||
|
template< class T >
|
||
|
void swap( weak_ptr< T > &a, weak_ptr< T > &b )
|
||
|
{
|
||
|
a.swap( b );
|
||
|
}
|
||
|
|
||
|
|
||
|
// enable_shared_from_this template
|
||
|
// ********************************
|
||
|
|
||
|
template< class T > class enable_shared_from_this {
|
||
|
protected:
|
||
|
enable_shared_from_this( ) { }
|
||
|
enable_shared_from_this( enable_shared_from_this const & ) { }
|
||
|
enable_shared_from_this &operator=( enable_shared_from_this const & )
|
||
|
{ return *this; }
|
||
|
~enable_shared_from_this( ) { }
|
||
|
|
||
|
public:
|
||
|
shared_ptr< T > shared_from_this( )
|
||
|
{
|
||
|
shared_ptr< T > tmp( weak_this );
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
shared_ptr< T const > shared_from_this( ) const
|
||
|
{
|
||
|
shared_ptr< T const > tmp( weak_this );
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
weak_ptr< T > weak_this;
|
||
|
|
||
|
friend class shared_ptr;
|
||
|
};
|
||
|
|
||
|
namespace detail {
|
||
|
|
||
|
class shared_holder {
|
||
|
public:
|
||
|
shared_holder( long _count = 0 ) : count( _count ), weak_count( 0 ) { }
|
||
|
|
||
|
long use_count( ) const
|
||
|
{ return count; }
|
||
|
|
||
|
void increase_count( )
|
||
|
{ ++count; }
|
||
|
|
||
|
void decrease_count( )
|
||
|
{
|
||
|
if( !(--count) ) {
|
||
|
delete_ptr( );
|
||
|
if( !weak_count ) {
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void increase_weak_count( )
|
||
|
{ ++weak_count; }
|
||
|
|
||
|
void decrease_weak_count( )
|
||
|
{
|
||
|
if( !(--weak_count) ) {
|
||
|
if( !count ) {
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
virtual void *get_deleter( const type_info & ) const
|
||
|
{ return 0; }
|
||
|
|
||
|
virtual ~shared_holder( ) { }
|
||
|
|
||
|
private:
|
||
|
long count;
|
||
|
long weak_count;
|
||
|
virtual void delete_ptr( ) = 0;
|
||
|
};
|
||
|
|
||
|
template< class T >
|
||
|
class shared_holder_ptr : public shared_holder {
|
||
|
public:
|
||
|
shared_holder_ptr( T *_ptr, long _count = 0 ) :
|
||
|
shared_holder( _count), ptr( _ptr ) { }
|
||
|
|
||
|
private:
|
||
|
virtual void delete_ptr( )
|
||
|
{ delete ptr; }
|
||
|
|
||
|
T *ptr;
|
||
|
};
|
||
|
|
||
|
template< class T, class D >
|
||
|
class shared_holder_deleter : public shared_holder {
|
||
|
public:
|
||
|
shared_holder_deleter( T *_ptr, D _d, long _count = 0 ) :
|
||
|
shared_holder( _count ), ptr( _ptr ), d( _d ) { }
|
||
|
|
||
|
private:
|
||
|
T *ptr;
|
||
|
D d;
|
||
|
|
||
|
virtual void delete_ptr( )
|
||
|
{ d( ptr ); }
|
||
|
|
||
|
virtual void *get_deleter( const type_info &ti ) const
|
||
|
{
|
||
|
return typeid( D ) == ti ?
|
||
|
static_cast< void* >( const_cast< D* >(&d) ) : 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // namespace detail
|
||
|
|
||
|
} // namespace std
|
||
|
|
||
|
#endif
|