Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 1 | /* |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 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) | ||||
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 7 | */ |
8 | #ifndef TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED | ||||
9 | #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED | ||||
10 | |||||
11 | #include "catch_common.h" | ||||
12 | |||||
Phil Nash | dc2735c | 2013-03-13 08:04:50 +0000 | [diff] [blame] | 13 | #ifdef __clang__ |
14 | #pragma clang diagnostic push | ||||
15 | #pragma clang diagnostic ignored "-Wpadded" | ||||
16 | #endif | ||||
17 | |||||
Phil Nash | d0be9ed | 2012-05-15 08:02:36 +0100 | [diff] [blame] | 18 | namespace Catch { |
19 | |||||
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 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> | ||||
Phil Nash | d0be9ed | 2012-05-15 08:02:36 +0100 | [diff] [blame] | 24 | class Ptr { |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 25 | public: |
Martin Hořeňovský | 71df663 | 2017-04-25 12:41:30 +0200 | [diff] [blame] | 26 | Ptr() : m_p( nullptr ){} |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 27 | Ptr( T* p ) : m_p( p ){ |
Phil Nash | 6175697 | 2012-07-28 20:37:07 +0100 | [diff] [blame] | 28 | if( m_p ) |
29 | m_p->addRef(); | ||||
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 30 | } |
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 31 | Ptr( Ptr const& other ) : m_p( other.m_p ){ |
Phil Nash | 6175697 | 2012-07-28 20:37:07 +0100 | [diff] [blame] | 32 | if( m_p ) |
33 | m_p->addRef(); | ||||
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 34 | } |
35 | ~Ptr(){ | ||||
36 | if( m_p ) | ||||
37 | m_p->release(); | ||||
38 | } | ||||
Phil Nash | fe98123 | 2012-12-05 08:40:53 +0000 | [diff] [blame] | 39 | void reset() { |
40 | if( m_p ) | ||||
41 | m_p->release(); | ||||
Martin Hořeňovský | 71df663 | 2017-04-25 12:41:30 +0200 | [diff] [blame] | 42 | m_p = nullptr; |
Phil Nash | fe98123 | 2012-12-05 08:40:53 +0000 | [diff] [blame] | 43 | } |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 44 | Ptr& operator = ( T* p ){ |
45 | Ptr temp( p ); | ||||
46 | swap( temp ); | ||||
47 | return *this; | ||||
48 | } | ||||
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 49 | Ptr& operator = ( Ptr const& other ){ |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 50 | Ptr temp( other ); |
51 | swap( temp ); | ||||
52 | return *this; | ||||
53 | } | ||||
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 54 | void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } |
Phil Nash | 34fa25e | 2015-07-28 18:55:11 +0100 | [diff] [blame] | 55 | T* get() const{ return m_p; } |
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 56 | T& operator*() const { return *m_p; } |
57 | T* operator->() const { return m_p; } | ||||
Martin Hořeňovský | 71df663 | 2017-04-25 12:41:30 +0200 | [diff] [blame] | 58 | bool operator !() const { return m_p == nullptr; } |
Phil Nash | cc8206f | 2017-04-25 14:46:48 +0000 | [diff] [blame^] | 59 | explicit operator bool() const { return m_p != nullptr; } |
Phil Nash | f3d1f08 | 2013-07-03 19:14:59 +0100 | [diff] [blame] | 60 | |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 61 | private: |
62 | T* m_p; | ||||
63 | }; | ||||
Phil Nash | f3d1f08 | 2013-07-03 19:14:59 +0100 | [diff] [blame] | 64 | |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 65 | struct IShared : NonCopyable { |
Phil Nash | a695eb9 | 2012-08-13 07:46:10 +0100 | [diff] [blame] | 66 | virtual ~IShared(); |
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 67 | virtual void addRef() const = 0; |
68 | virtual void release() const = 0; | ||||
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 69 | }; |
Phil Nash | f3d1f08 | 2013-07-03 19:14:59 +0100 | [diff] [blame] | 70 | |
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 71 | template<typename T = IShared> |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 72 | struct SharedImpl : T { |
Phil Nash | f3d1f08 | 2013-07-03 19:14:59 +0100 | [diff] [blame] | 73 | |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 74 | SharedImpl() : m_rc( 0 ){} |
Phil Nash | 9444bbc | 2012-10-12 07:58:17 +0100 | [diff] [blame] | 75 | |
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 76 | virtual void addRef() const { |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 77 | ++m_rc; |
78 | } | ||||
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 79 | virtual void release() const { |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 80 | if( --m_rc == 0 ) |
81 | delete this; | ||||
82 | } | ||||
Phil Nash | f3d1f08 | 2013-07-03 19:14:59 +0100 | [diff] [blame] | 83 | |
Phil Nash | 7f04b56 | 2012-11-30 18:54:06 +0000 | [diff] [blame] | 84 | mutable unsigned int m_rc; |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 85 | }; |
Phil Nash | f3d1f08 | 2013-07-03 19:14:59 +0100 | [diff] [blame] | 86 | |
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 87 | } // end namespace Catch |
88 | |||||
Phil Nash | dc2735c | 2013-03-13 08:04:50 +0000 | [diff] [blame] | 89 | #ifdef __clang__ |
90 | #pragma clang diagnostic pop | ||||
91 | #endif | ||||
92 | |||||
Phil Nash | b213202 | 2012-05-04 07:55:11 +0100 | [diff] [blame] | 93 | #endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED |