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