Geophysical Inversion and Modelling Library v1.5.4
Loading...
Searching...
No Matches
refCountPtr.h
1/******************************************************************************
2 * Copyright (C) 2014-2024 by the GIMLi development team *
3 * Carsten Rücker carsten@resistivity.net *
4 * *
5 * Licensed under the Apache License, Version 2.0 (the "License"); *
6 * you may not use this file except in compliance with the License. *
7 * You may obtain a copy of the License at *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14 * See the License for the specific language governing permissions and *
15 * limitations under the License. *
16 * *
17 ******************************************************************************/
18
19#ifndef _GIMLI_REFCOUNTPTR__H
20#define _GIMLI_REFCOUNTPTR__H
21
22#include "gimli.h"
23
24namespace GIMLI{
25
26// Base class for reference counted objects
27// Scott Meyers: More Effective C++ Item 29 Source Code
28class RCObject {
29public:
30 void addReference(){
31 __M
32 ++refCount_;
33 }
34
35 void removeReference(){
36 __M
37 if (--refCount_ == 0) delete this;
38 }
39
40 void markUnshareable(){
41 shareable_ = false;
42 }
43
44 bool isShareable() const{
45 return shareable_;
46 }
47
48 bool isShared() const {
49 return refCount_ > 1;
50 }
51
52protected:
53 RCObject()
54 : refCount_(0), shareable_(true) {}
55
56 RCObject(const RCObject& rhs)
57 : refCount_(0), shareable_(true) {}
58
59 RCObject& operator=(const RCObject& rhs){
60 return *this;
61 }
62
63 virtual ~RCObject() = 0;
64
65private:
66 Index refCount_;
67 bool shareable_;
68};
69
70 //*! Template class for smart pointers-to-T objects;
74template<class T > class RefCountIPtr {
75public:
76
77 RefCountIPtr(T * realPtr = 0)
78 : counter_(new CountHolder){
79 counter_->pointee_ = realPtr;
80 init_();
81 }
82
83 RefCountIPtr(const RefCountIPtr & rhs)
84 : counter_(rhs.counter_){
85 init_();
86 }
87
88 RefCountIPtr(RefCountIPtr & rhs)
89 : counter_(rhs.counter_){
90 THROW_TO_IMPL
91 }
92
93 ~RefCountIPtr(){
94 counter_->removeReference();
95 }
96
97 RefCountIPtr & operator = (const RefCountIPtr & rhs){
98 __M
99 if (counter_ != rhs.counter_) {
100 counter_->removeReference();
101 counter_ = rhs.counter_;
102 init_();
103 }
104 return *this;
105 }
106
107 RefCountIPtr & operator = (RefCountIPtr & rhs){
108 __M
109 if (counter_ != rhs.counter_) {
110 counter_->removeReference();
111 counter_ = rhs.counter_;
112 init_();
113 }
114 THROW_TO_IMPL
115 return *this;
116 }
117
118 T * operator->() {
119 __M
120 THROW_TO_IMPL
121 return counter_->pointee_;
122 }
123
124 T * operator->() const{
125 __M
126 return counter_->pointee_;
127 }
128
129 T & operator*(){
130 __M
131 THROW_TO_IMPL
132 return *counter_->pointee_;
133 }
134
135 T & operator*() const {
136 __M
137 return *counter_->pointee_;
138 }
139
140private:
141 struct CountHolder : public RCObject {
142 ~CountHolder() { delete pointee_; }
143 T * pointee_;
144 };
145
146 void init_(){
147 if (counter_->isShareable() == false) {
148 T *oldValue = counter_->pointee_;
149 counter_ = new CountHolder;
150 counter_->pointee_ = oldValue ? new T(*oldValue) : 0;
151 }
152 counter_->addReference();
153 }
154
155 CountHolder *counter_;
156
157};
158
159} // namespace GIMLI
160
161#endif //_GIMLI_REFCOUNTPTR__H
Definition refCountPtr.h:28
GIMLi main namespace for the Geophyiscal Inversion and Modelling Library.
Definition baseentity.h:24