blob: 2817ddd1cc6f85e1e7038bdf35a8e78e129207fb [file] [log] [blame]
Phil Nashb2132022012-05-04 07:55:11 +01001/*
Phil Nashb2132022012-05-04 07:55:11 +01002 * 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)
Phil Nashb2132022012-05-04 07:55:11 +01007 */
8#ifndef TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
9#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
10
11#include "catch_common.h"
12
Phil Nashd0be9ed2012-05-15 08:02:36 +010013namespace Catch {
14
Phil Nashb2132022012-05-04 07:55:11 +010015 // An intrusive reference counting smart pointer.
16 // T must implement addRef() and release() methods
17 // typically implementing the IShared interface
18 template<typename T>
Phil Nashd0be9ed2012-05-15 08:02:36 +010019 class Ptr {
Phil Nashb2132022012-05-04 07:55:11 +010020 public:
21 Ptr() : m_p( NULL ){}
22 Ptr( T* p ) : m_p( p ){
Phil Nash61756972012-07-28 20:37:07 +010023 if( m_p )
24 m_p->addRef();
Phil Nashb2132022012-05-04 07:55:11 +010025 }
Phil Nash7f04b562012-11-30 18:54:06 +000026 Ptr( Ptr const& other ) : m_p( other.m_p ){
Phil Nash61756972012-07-28 20:37:07 +010027 if( m_p )
28 m_p->addRef();
Phil Nashb2132022012-05-04 07:55:11 +010029 }
30 ~Ptr(){
31 if( m_p )
32 m_p->release();
33 }
Phil Nashfe981232012-12-05 08:40:53 +000034 void reset() {
35 if( m_p )
36 m_p->release();
37 m_p = NULL;
38 }
Phil Nashb2132022012-05-04 07:55:11 +010039 Ptr& operator = ( T* p ){
40 Ptr temp( p );
41 swap( temp );
42 return *this;
43 }
Phil Nash7f04b562012-11-30 18:54:06 +000044 Ptr& operator = ( Ptr const& other ){
Phil Nashb2132022012-05-04 07:55:11 +010045 Ptr temp( other );
46 swap( temp );
47 return *this;
48 }
Phil Nash7f04b562012-11-30 18:54:06 +000049 void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
50 T* get() { return m_p; }
51 const T* get() const{ return m_p; }
52 T& operator*() const { return *m_p; }
53 T* operator->() const { return m_p; }
54 bool operator !() const { return m_p == NULL; }
Phil Nashfe981232012-12-05 08:40:53 +000055 operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
Phil Nashb2132022012-05-04 07:55:11 +010056
57 private:
58 T* m_p;
59 };
60
61 struct IShared : NonCopyable {
Phil Nasha695eb92012-08-13 07:46:10 +010062 virtual ~IShared();
Phil Nash7f04b562012-11-30 18:54:06 +000063 virtual void addRef() const = 0;
64 virtual void release() const = 0;
Phil Nashb2132022012-05-04 07:55:11 +010065 };
66
Phil Nash7f04b562012-11-30 18:54:06 +000067 template<typename T = IShared>
Phil Nashb2132022012-05-04 07:55:11 +010068 struct SharedImpl : T {
69
70 SharedImpl() : m_rc( 0 ){}
Phil Nash9444bbc2012-10-12 07:58:17 +010071
Phil Nash7f04b562012-11-30 18:54:06 +000072 virtual void addRef() const {
Phil Nashb2132022012-05-04 07:55:11 +010073 ++m_rc;
74 }
Phil Nash7f04b562012-11-30 18:54:06 +000075 virtual void release() const {
Phil Nashb2132022012-05-04 07:55:11 +010076 if( --m_rc == 0 )
77 delete this;
78 }
79
Phil Nash7f04b562012-11-30 18:54:06 +000080 mutable unsigned int m_rc;
Phil Nashb2132022012-05-04 07:55:11 +010081 };
82
83} // end namespace Catch
84
85#endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED