/*! @file
@ id $ Id $
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
# ifndef __MRW__CHECKCXX11__
# define __MRW__CHECKCXX11__
// check if code is compiled with a new C++11 compiler
// otherwise there is a fallback wich makes everything much more compliacted
# ifndef MRW__OLD_PRE11_COMPILER
# if __cplusplus < 201103L
# if __cplusplus==1
# if __APPLE__
/// Code is compiled with old non C++11 standard compliant compiler
/** There are workarounds for old non C++11 compatible
compilers . These workarounds are deprecated , but will
remain until most compilers fully support C + + 11. So
this workaround will be removed in future releases ,
when support for C + + 11 is more common . Only rely on
this workaround , if you really have to .
Mac gcc is even worse than on other systems . */
# define MRW__OLD_PRE11_COMPILER
# warning you need a C++11 compliant compiler, on gcc: add -std=c++11
# warning emulating C++11 - this changes the way you use the library
# warning this is deprecated and will be removed in future releases
# warning refere to the library documentation for more details
# else
// __cplusplus==1 is a known bug in gcc 4.6.3
# warning your compiler has a know bug, please upgrade to gcc >= 4.7
# warning see __cplusplus in http: //gcc.gnu.org/gcc-4.7/changes.html
# endif
# else
/// Code is compiled with an old non C++11 standard compliant compiler
/** There are workarounds for old non C++11 compatible
compilers . These workarounds are deprecated , but will remain until
most compilers fully support C + + 11. So this workaround will be
removed in future releases , when support for C + + 11 is more
common . Only rely on this workaround , if you really have to . */
# define MRW__OLD_PRE11_COMPILER
# warning you need a C++11 compliant compiler, on gcc: add -std=c++11
# warning emulating C++11 - this changes the way you use the library
# warning this is deprecated and will be removed in future releases
# warning refere to the library documentation for more details
# endif
# endif
# endif
# ifdef MRW__OLD_PRE11_COMPILER
# if __cplusplus<200300L
namespace std {
// there is no std::shared_ptr in pre C++11 compilers, so we use the
// one copied from newer gcc
template < typename _Ch , typename _Tr , typename _Tp , _Lock_policy _Lp >
inline std : : basic_ostream < _Ch , _Tr > &
operator < < ( std : : basic_ostream < _Ch , _Tr > & __os ,
const __shared_ptr < _Tp , _Lp > & __p )
{
__os < < __p . get ( ) ;
return __os ;
}
template < typename _Del , typename _Tp , _Lock_policy _Lp >
inline _Del *
get_deleter ( const __shared_ptr < _Tp , _Lp > & __p ) noexcept
{
# ifdef __GXX_RTTI
return static_cast < _Del * > ( __p . _M_get_deleter ( typeid ( _Del ) ) ) ;
# else
return 0 ;
# endif
}
template < typename _Tp > class shared_ptr : public __shared_ptr < _Tp > {
public :
constexpr shared_ptr ( ) noexcept : __shared_ptr < _Tp > ( ) { }
shared_ptr ( const shared_ptr & ) noexcept = default ;
template < typename _Tp1 > explicit shared_ptr ( _Tp1 * __p )
: __shared_ptr < _Tp > ( __p ) { }
template < typename _Tp1 , typename _Deleter >
shared_ptr ( _Tp1 * __p , _Deleter __d )
: __shared_ptr < _Tp > ( __p , __d ) { }
template < typename _Deleter >
shared_ptr ( nullptr_t __p , _Deleter __d )
: __shared_ptr < _Tp > ( __p , __d ) { }
template < typename _Tp1 , typename _Deleter , typename _Alloc >
shared_ptr ( _Tp1 * __p , _Deleter __d , _Alloc __a )
: __shared_ptr < _Tp > ( __p , __d , std : : move ( __a ) ) { }
template < typename _Deleter , typename _Alloc >
shared_ptr ( nullptr_t __p , _Deleter __d , _Alloc __a )
: __shared_ptr < _Tp > ( __p , __d , std : : move ( __a ) ) { }
template < typename _Tp1 >
shared_ptr ( const shared_ptr < _Tp1 > & __r , _Tp * __p ) noexcept
: __shared_ptr < _Tp > ( __r , __p ) { }
template < typename _Tp1 , typename = typename
std : : enable_if < std : : is_convertible < _Tp1 * , _Tp * > : : value > : : type >
shared_ptr ( const shared_ptr < _Tp1 > & __r ) noexcept
: __shared_ptr < _Tp > ( __r ) { }
shared_ptr ( shared_ptr & & __r ) noexcept
: __shared_ptr < _Tp > ( std : : move ( __r ) ) { }
template < typename _Tp1 , typename = typename
std : : enable_if < std : : is_convertible < _Tp1 * , _Tp * > : : value > : : type >
shared_ptr ( shared_ptr < _Tp1 > & & __r ) noexcept
: __shared_ptr < _Tp > ( std : : move ( __r ) ) { }
template < typename _Tp1 >
explicit shared_ptr ( const weak_ptr < _Tp1 > & __r )
: __shared_ptr < _Tp > ( __r ) { }
template < typename _Tp1 , typename _Del >
shared_ptr ( std : : unique_ptr < _Tp1 , _Del > & & __r )
: __shared_ptr < _Tp > ( std : : move ( __r ) ) { }
constexpr shared_ptr ( nullptr_t __p ) noexcept
: __shared_ptr < _Tp > ( __p ) { }
shared_ptr & operator = ( const shared_ptr & ) noexcept = default ;
template < typename _Tp1 >
shared_ptr & operator = ( const shared_ptr < _Tp1 > & __r ) noexcept {
this - > __shared_ptr < _Tp > : : operator = ( __r ) ;
return * this ;
}
shared_ptr & operator = ( shared_ptr & & __r ) noexcept {
this - > __shared_ptr < _Tp > : : operator = ( std : : move ( __r ) ) ;
return * this ;
}
template < class _Tp1 >
shared_ptr & operator = ( shared_ptr < _Tp1 > & & __r ) noexcept {
this - > __shared_ptr < _Tp > : : operator = ( std : : move ( __r ) ) ;
return * this ;
}
template < typename _Tp1 , typename _Del >
shared_ptr & operator = ( std : : unique_ptr < _Tp1 , _Del > & & __r ) {
this - > __shared_ptr < _Tp > : : operator = ( std : : move ( __r ) ) ;
return * this ;
}
private :
template < typename _Alloc , typename . . . _Args >
shared_ptr ( _Sp_make_shared_tag __tag , const _Alloc & __a ,
_Args & & . . . __args )
: __shared_ptr < _Tp > ( __tag , __a ,
std : : forward < _Args > ( __args ) . . . ) { }
template < typename _Tp1 , typename _Alloc , typename . . . _Args >
friend shared_ptr < _Tp1 >
allocate_shared ( const _Alloc & __a , _Args & & . . . __args ) ;
} ;
template < typename _Tp1 , typename _Tp2 >
inline bool operator = = ( const shared_ptr < _Tp1 > & __a ,
const shared_ptr < _Tp2 > & __b ) noexcept {
return __a . get ( ) = = __b . get ( ) ;
}
template < typename _Tp >
inline bool operator = = ( const shared_ptr < _Tp > & __a ,
nullptr_t ) noexcept {
return ! __a ;
}
template < typename _Tp >
inline bool operator = = ( nullptr_t ,
const shared_ptr < _Tp > & __a ) noexcept {
return ! __a ;
}
template < typename _Tp1 , typename _Tp2 >
inline bool operator ! = ( const shared_ptr < _Tp1 > & __a ,
const shared_ptr < _Tp2 > & __b ) noexcept {
return __a . get ( ) ! = __b . get ( ) ;
}
template < typename _Tp >
inline bool operator ! = ( const shared_ptr < _Tp > & __a ,
nullptr_t ) noexcept {
return ( bool ) __a ;
}
template < typename _Tp >
inline bool operator ! = ( nullptr_t ,
const shared_ptr < _Tp > & __a ) noexcept {
return ( bool ) __a ;
}
template < typename _Tp1 , typename _Tp2 >
inline bool operator < ( const shared_ptr < _Tp1 > & __a ,
const shared_ptr < _Tp2 > & __b ) noexcept {
typedef typename std : : common_type < _Tp1 * , _Tp2 * > : : type _CT ;
return std : : less < _CT > ( ) ( __a . get ( ) , __b . get ( ) ) ;
}
template < typename _Tp >
inline bool
operator < ( const shared_ptr < _Tp > & __a , nullptr_t ) noexcept
{ return std : : less < _Tp * > ( ) ( __a . get ( ) , nullptr ) ; }
template < typename _Tp >
inline bool
operator < ( nullptr_t , const shared_ptr < _Tp > & __a ) noexcept
{ return std : : less < _Tp * > ( ) ( nullptr , __a . get ( ) ) ; }
template < typename _Tp1 , typename _Tp2 >
inline bool
operator < = ( const shared_ptr < _Tp1 > & __a ,
const shared_ptr < _Tp2 > & __b ) noexcept
{ return ! ( __b < __a ) ; }
template < typename _Tp >
inline bool
operator < = ( const shared_ptr < _Tp > & __a , nullptr_t ) noexcept
{ return ! ( nullptr < __a ) ; }
template < typename _Tp >
inline bool
operator < = ( nullptr_t , const shared_ptr < _Tp > & __a ) noexcept
{ return ! ( __a < nullptr ) ; }
template < typename _Tp1 , typename _Tp2 >
inline bool
operator > ( const shared_ptr < _Tp1 > & __a ,
const shared_ptr < _Tp2 > & __b ) noexcept
{ return ( __b < __a ) ; }
template < typename _Tp >
inline bool
operator > ( const shared_ptr < _Tp > & __a , nullptr_t ) noexcept
{ return std : : less < _Tp * > ( ) ( nullptr , __a . get ( ) ) ; }
template < typename _Tp >
inline bool
operator > ( nullptr_t , const shared_ptr < _Tp > & __a ) noexcept
{ return std : : less < _Tp * > ( ) ( __a . get ( ) , nullptr ) ; }
template < typename _Tp1 , typename _Tp2 >
inline bool
operator > = ( const shared_ptr < _Tp1 > & __a ,
const shared_ptr < _Tp2 > & __b ) noexcept
{ return ! ( __a < __b ) ; }
template < typename _Tp >
inline bool
operator > = ( const shared_ptr < _Tp > & __a , nullptr_t ) noexcept
{ return ! ( __a < nullptr ) ; }
template < typename _Tp >
inline bool
operator > = ( nullptr_t , const shared_ptr < _Tp > & __a ) noexcept
{ return ! ( nullptr < __a ) ; }
template < typename _Tp >
struct less < shared_ptr < _Tp > > : public _Sp_less < shared_ptr < _Tp > >
{ } ;
// 20.7.2.2.8 shared_ptr specialized algorithms.
template < typename _Tp >
inline void
swap ( shared_ptr < _Tp > & __a , shared_ptr < _Tp > & __b ) noexcept
{ __a . swap ( __b ) ; }
// 20.7.2.2.9 shared_ptr casts.
template < typename _Tp , typename _Tp1 >
inline shared_ptr < _Tp >
static_pointer_cast ( const shared_ptr < _Tp1 > & __r ) noexcept
{ return shared_ptr < _Tp > ( __r , static_cast < _Tp * > ( __r . get ( ) ) ) ; }
template < typename _Tp , typename _Tp1 >
inline shared_ptr < _Tp >
const_pointer_cast ( const shared_ptr < _Tp1 > & __r ) noexcept
{ return shared_ptr < _Tp > ( __r , const_cast < _Tp * > ( __r . get ( ) ) ) ; }
template < typename _Tp , typename _Tp1 >
inline shared_ptr < _Tp >
dynamic_pointer_cast ( const shared_ptr < _Tp1 > & __r ) noexcept
{
if ( _Tp * __p = dynamic_cast < _Tp * > ( __r . get ( ) ) )
return shared_ptr < _Tp > ( __r , __p ) ;
return shared_ptr < _Tp > ( ) ;
}
/**
* @ brief A smart pointer with weak semantics .
*
* With forwarding constructors and assignment operators .
*/
template < typename _Tp >
class weak_ptr : public __weak_ptr < _Tp >
{
public :
constexpr weak_ptr ( ) noexcept
: __weak_ptr < _Tp > ( ) { }
template < typename _Tp1 , typename = typename
std : : enable_if < std : : is_convertible < _Tp1 * , _Tp * > : : value > : : type >
weak_ptr ( const weak_ptr < _Tp1 > & __r ) noexcept
: __weak_ptr < _Tp > ( __r ) { }
template < typename _Tp1 , typename = typename
std : : enable_if < std : : is_convertible < _Tp1 * , _Tp * > : : value > : : type >
weak_ptr ( const shared_ptr < _Tp1 > & __r ) noexcept
: __weak_ptr < _Tp > ( __r ) { }
template < typename _Tp1 >
weak_ptr &
operator = ( const weak_ptr < _Tp1 > & __r ) noexcept
{
this - > __weak_ptr < _Tp > : : operator = ( __r ) ;
return * this ;
}
template < typename _Tp1 >
weak_ptr &
operator = ( const shared_ptr < _Tp1 > & __r ) noexcept
{
this - > __weak_ptr < _Tp > : : operator = ( __r ) ;
return * this ;
}
shared_ptr < _Tp >
lock ( ) const noexcept
{
# ifdef __GTHREADS
if ( this - > expired ( ) )
return shared_ptr < _Tp > ( ) ;
__try
{
return shared_ptr < _Tp > ( * this ) ;
}
__catch ( const bad_weak_ptr & )
{
return shared_ptr < _Tp > ( ) ;
}
# else
return this - > expired ( ) ? shared_ptr < _Tp > ( ) : shared_ptr < _Tp > ( * this ) ;
# endif
}
} ;
// 20.7.2.3.6 weak_ptr specialized algorithms.
template < typename _Tp >
inline void
swap ( weak_ptr < _Tp > & __a , weak_ptr < _Tp > & __b ) noexcept
{ __a . swap ( __b ) ; }
/// Primary template owner_less
template < typename _Tp >
struct owner_less ;
/// Partial specialization of owner_less for shared_ptr.
template < typename _Tp >
struct owner_less < shared_ptr < _Tp > >
: public _Sp_owner_less < shared_ptr < _Tp > , weak_ptr < _Tp > >
{ } ;
/// Partial specialization of owner_less for weak_ptr.
template < typename _Tp >
struct owner_less < weak_ptr < _Tp > >
: public _Sp_owner_less < weak_ptr < _Tp > , shared_ptr < _Tp > >
{ } ;
/**
* @ brief Base class allowing use of member function shared_from_this .
*/
template < typename _Tp >
class enable_shared_from_this
{
protected :
constexpr enable_shared_from_this ( ) noexcept { }
enable_shared_from_this ( const enable_shared_from_this & ) noexcept { }
enable_shared_from_this &
operator = ( const enable_shared_from_this & ) noexcept
{ return * this ; }
~ enable_shared_from_this ( ) { }
public :
shared_ptr < _Tp >
shared_from_this ( )
{ return shared_ptr < _Tp > ( this - > _M_weak_this ) ; }
shared_ptr < const _Tp >
shared_from_this ( ) const
{ return shared_ptr < const _Tp > ( this - > _M_weak_this ) ; }
private :
template < typename _Tp1 >
void
_M_weak_assign ( _Tp1 * __p , const __shared_count < > & __n ) const noexcept
{ _M_weak_this . _M_assign ( __p , __n ) ; }
template < typename _Tp1 >
friend void
__enable_shared_from_this_helper ( const __shared_count < > & __pn ,
const enable_shared_from_this * __pe ,
const _Tp1 * __px ) noexcept
{
if ( __pe ! = 0 )
__pe - > _M_weak_assign ( const_cast < _Tp1 * > ( __px ) , __pn ) ;
}
mutable weak_ptr < _Tp > _M_weak_this ;
} ;
template < typename _Tp , typename _Alloc , typename . . . _Args >
inline shared_ptr < _Tp >
allocate_shared ( const _Alloc & __a , _Args & & . . . __args )
{
return shared_ptr < _Tp > ( _Sp_make_shared_tag ( ) , __a ,
std : : forward < _Args > ( __args ) . . . ) ;
}
template < typename _Tp , typename . . . _Args >
inline shared_ptr < _Tp >
make_shared ( _Args & & . . . __args )
{
typedef typename std : : remove_const < _Tp > : : type _Tp_nc ;
return std : : allocate_shared < _Tp > ( std : : allocator < _Tp_nc > ( ) ,
std : : forward < _Args > ( __args ) . . . ) ;
}
template < typename _Tp >
struct hash < shared_ptr < _Tp > >
: public __hash_base < size_t , shared_ptr < _Tp > >
{
size_t
operator ( ) ( const shared_ptr < _Tp > & __s ) const noexcept
{ return std : : hash < _Tp * > ( ) ( __s . get ( ) ) ; }
} ;
// auto_ptr is deprecated in favour of unique_ptr, simulate unique_ptr
template < typename T > class unique_ptr : public std : : auto_ptr < T > {
public :
explicit unique_ptr ( ) : auto_ptr < T > ( ) { }
explicit unique_ptr ( T * p ) : auto_ptr < T > ( p ) { }
} ;
} ;
# endif
# endif
# endif