2012-05-04 08:55:11 +02:00
|
|
|
/*
|
|
|
|
* Created by Phil on 02/05/2012.
|
|
|
|
* Copyright 2012 Two Blue Cubes Ltd. All rights reserved.
|
|
|
|
*
|
|
|
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
*/
|
|
|
|
#ifndef TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
|
|
|
|
#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
|
|
|
|
|
|
|
|
#include "catch_common.h"
|
|
|
|
|
2013-03-13 09:04:50 +01:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wpadded"
|
|
|
|
#endif
|
|
|
|
|
2012-05-15 09:02:36 +02:00
|
|
|
namespace Catch {
|
|
|
|
|
2012-05-04 08:55:11 +02:00
|
|
|
// An intrusive reference counting smart pointer.
|
|
|
|
// T must implement addRef() and release() methods
|
|
|
|
// typically implementing the IShared interface
|
|
|
|
template<typename T>
|
2012-05-15 09:02:36 +02:00
|
|
|
class Ptr {
|
2012-05-04 08:55:11 +02:00
|
|
|
public:
|
2017-04-25 12:41:30 +02:00
|
|
|
Ptr() : m_p( nullptr ){}
|
2012-05-04 08:55:11 +02:00
|
|
|
Ptr( T* p ) : m_p( p ){
|
2012-07-28 21:37:07 +02:00
|
|
|
if( m_p )
|
|
|
|
m_p->addRef();
|
2012-05-04 08:55:11 +02:00
|
|
|
}
|
2012-11-30 19:54:06 +01:00
|
|
|
Ptr( Ptr const& other ) : m_p( other.m_p ){
|
2012-07-28 21:37:07 +02:00
|
|
|
if( m_p )
|
|
|
|
m_p->addRef();
|
2012-05-04 08:55:11 +02:00
|
|
|
}
|
|
|
|
~Ptr(){
|
|
|
|
if( m_p )
|
|
|
|
m_p->release();
|
|
|
|
}
|
2012-12-05 09:40:53 +01:00
|
|
|
void reset() {
|
|
|
|
if( m_p )
|
|
|
|
m_p->release();
|
2017-04-25 12:41:30 +02:00
|
|
|
m_p = nullptr;
|
2012-12-05 09:40:53 +01:00
|
|
|
}
|
2012-05-04 08:55:11 +02:00
|
|
|
Ptr& operator = ( T* p ){
|
|
|
|
Ptr temp( p );
|
|
|
|
swap( temp );
|
|
|
|
return *this;
|
|
|
|
}
|
2012-11-30 19:54:06 +01:00
|
|
|
Ptr& operator = ( Ptr const& other ){
|
2012-05-04 08:55:11 +02:00
|
|
|
Ptr temp( other );
|
|
|
|
swap( temp );
|
|
|
|
return *this;
|
|
|
|
}
|
2012-11-30 19:54:06 +01:00
|
|
|
void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
|
2015-07-28 19:55:11 +02:00
|
|
|
T* get() const{ return m_p; }
|
2012-11-30 19:54:06 +01:00
|
|
|
T& operator*() const { return *m_p; }
|
|
|
|
T* operator->() const { return m_p; }
|
2017-04-25 12:41:30 +02:00
|
|
|
bool operator !() const { return m_p == nullptr; }
|
|
|
|
operator SafeBool::type() const { return SafeBool::makeSafe( m_p != nullptr ); }
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-05-04 08:55:11 +02:00
|
|
|
private:
|
|
|
|
T* m_p;
|
|
|
|
};
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-05-04 08:55:11 +02:00
|
|
|
struct IShared : NonCopyable {
|
2012-08-13 08:46:10 +02:00
|
|
|
virtual ~IShared();
|
2012-11-30 19:54:06 +01:00
|
|
|
virtual void addRef() const = 0;
|
|
|
|
virtual void release() const = 0;
|
2012-05-04 08:55:11 +02:00
|
|
|
};
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-11-30 19:54:06 +01:00
|
|
|
template<typename T = IShared>
|
2012-05-04 08:55:11 +02:00
|
|
|
struct SharedImpl : T {
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-05-04 08:55:11 +02:00
|
|
|
SharedImpl() : m_rc( 0 ){}
|
2012-10-12 08:58:17 +02:00
|
|
|
|
2012-11-30 19:54:06 +01:00
|
|
|
virtual void addRef() const {
|
2012-05-04 08:55:11 +02:00
|
|
|
++m_rc;
|
|
|
|
}
|
2012-11-30 19:54:06 +01:00
|
|
|
virtual void release() const {
|
2012-05-04 08:55:11 +02:00
|
|
|
if( --m_rc == 0 )
|
|
|
|
delete this;
|
|
|
|
}
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-11-30 19:54:06 +01:00
|
|
|
mutable unsigned int m_rc;
|
2012-05-04 08:55:11 +02:00
|
|
|
};
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-05-04 08:55:11 +02:00
|
|
|
} // end namespace Catch
|
|
|
|
|
2013-03-13 09:04:50 +01:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
#endif
|
|
|
|
|
2012-05-04 08:55:11 +02:00
|
|
|
#endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
|