1 /* 2 * Created by Phil on 02/05/2012. 3 * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. 4 * 5 * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 */ 8 #ifndef TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED 9 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED 10 11 #include "catch_common.h" 12 13 #ifdef __clang__ 14 #pragma clang diagnostic push 15 #pragma clang diagnostic ignored "-Wpadded" 16 #endif 17 18 namespace Catch { 19 20 // An intrusive reference counting smart pointer. 21 // T must implement addRef() and release() methods 22 // typically implementing the IShared interface 23 template<typename T> 24 class Ptr { 25 public: Ptr()26 Ptr() : m_p( CATCH_NULL ){} Ptr(T * p)27 Ptr( T* p ) : m_p( p ){ 28 if( m_p ) 29 m_p->addRef(); 30 } Ptr(Ptr const & other)31 Ptr( Ptr const& other ) : m_p( other.m_p ){ 32 if( m_p ) 33 m_p->addRef(); 34 } ~Ptr()35 ~Ptr(){ 36 if( m_p ) 37 m_p->release(); 38 } reset()39 void reset() { 40 if( m_p ) 41 m_p->release(); 42 m_p = CATCH_NULL; 43 } operator =(T * p)44 Ptr& operator = ( T* p ){ 45 Ptr temp( p ); 46 swap( temp ); 47 return *this; 48 } operator =(Ptr const & other)49 Ptr& operator = ( Ptr const& other ){ 50 Ptr temp( other ); 51 swap( temp ); 52 return *this; 53 } swap(Ptr & other)54 void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } get() const55 T* get() const{ return m_p; } operator *() const56 T& operator*() const { return *m_p; } operator ->() const57 T* operator->() const { return m_p; } operator !() const58 bool operator !() const { return m_p == CATCH_NULL; } operator SafeBool::type() const59 operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } 60 61 private: 62 T* m_p; 63 }; 64 65 struct IShared : NonCopyable { 66 virtual ~IShared(); 67 virtual void addRef() const = 0; 68 virtual void release() const = 0; 69 }; 70 71 template<typename T = IShared> 72 struct SharedImpl : T { 73 SharedImplCatch::SharedImpl74 SharedImpl() : m_rc( 0 ){} 75 addRefCatch::SharedImpl76 virtual void addRef() const { 77 ++m_rc; 78 } releaseCatch::SharedImpl79 virtual void release() const { 80 if( --m_rc == 0 ) 81 delete this; 82 } 83 84 mutable unsigned int m_rc; 85 }; 86 87 } // end namespace Catch 88 89 #ifdef __clang__ 90 #pragma clang diagnostic pop 91 #endif 92 93 #endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED 94