UQTk: Uncertainty Quantification Toolkit  3.1.1
RefPtr.h
Go to the documentation of this file.
1 /* =====================================================================================
2 
3  The UQ Toolkit (UQTk) version 3.1.1
4  Copyright (2021) NTESS
5  https://www.sandia.gov/UQToolkit/
6  https://github.com/sandialabs/UQTk
7 
8  Copyright 2021 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
9  Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government
10  retains certain rights in this software.
11 
12  This file is part of The UQ Toolkit (UQTk)
13 
14  UQTk is open source software: you can redistribute it and/or modify
15  it under the terms of BSD 3-Clause License
16 
17  UQTk is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  BSD 3 Clause License for more details.
21 
22  You should have received a copy of the BSD 3 Clause License
23  along with UQTk. If not, see https://choosealicense.com/licenses/bsd-3-clause/.
24 
25  Questions? Contact the UQTk Developers at <uqtk-developers@software.sandia.gov>
26  Sandia National Laboratories, Livermore, CA, USA
27 ===================================================================================== */
28 // -*- C++ -*-
29 
30 #ifndef _utility_ref_RefPtr_
31 #define _utility_ref_RefPtr_
32 
33 #include "MyException.h"
34 #include <typeinfo> // for dynamic_cast
35 #include <unistd.h>
36 #include <stddef.h>
37 
45 template <class T>
46 class RefPtr {
47 public:
49  typedef T Type;
50 
52  RefPtr() : ptr_(NULL) {}
53 
55  RefPtr(T* p) : ptr_(p) {
56  grab();
57  }
58 
60  RefPtr(const RefPtr<T>& p) : ptr_(p.ptr_) {
61  grab();
62  }
63 
66  template <class Other>
67  RefPtr(RefPtr<Other> p) : ptr_(static_cast<T*>(p.pointee())) {
68  grab();
69  }
70 
72  ~RefPtr() {
73  release();
74  }
75 
78  if(p != ptr_) {
79  release(); // release the old pointer
80  ptr_ = p; // assign our value to this one
81  grab(); // grab this pointer
82  }
83  return *this;
84  }
85 
88  if(p.ptr_ != ptr_) {
89  release();
90  ptr_ = p.ptr_;
91  grab();
92  }
93  return *this;
94  }
95 
99  template <class Other>
100  RefPtr<T>& cast(Other* p) {
101  if(p != ptr_) {
102  release();
103 
104  //std::cout << "DEBUG: Dynamic cast from type " << typeid(p).name()
105  // << " to " << typeid(T).name() << std::endl;
106 
107  ptr_ = dynamic_cast<T*>(p);
108  if(p != NULL && ptr_ == NULL) {
109  throw MyException
110  (std::string("RefPtr::cast(Other): Failed dynamic cast from ")
111  + std::string(typeid(Other).name()) + std::string(" to ") +
112  std::string(typeid(Type).name()));
113 
114  }
115  grab();
116  }
117  return *this;
118  }
119 
123  template <class Other>
125  if(p.ptr_ != ptr_) {
126  release();
127 
128  //std::cout << "DEBUG: Dynamic cast from type "
129  // << typeid(p.pointee()).name()
130  // << " to " << typeid(T).name() << std::endl;
131 
132  ptr_ = dynamic_cast<T*>(p.pointee());
133  if(p != NULL && ptr_ == NULL) {
134  throw MyException
135  (std::string("RefPtr::cast(Other): Failed dynamic cast from ")
136  + std::string(typeid(Other).name()) + std::string(" to ") +
137  std::string(typeid(Type).name()));
138  }
139  grab();
140  }
141  return *this;
142  }
143 
146  T* operator->() const {
147  if(ptr_ == NULL) {
148  std::cerr << "RefPtr<" << typeid(T).name()
149  << ">::operator->() const invoked on a null pointer\n";
150  throw MyException("RefPtr::operator->() const");
151  }
152  return ptr_;
153  }
154 
157  T& operator*() const {
158  if(ptr_ == NULL) {
159  std::cerr << "RefPtr<" << typeid(T).name()
160  << ">::operator*() const invoked on a null pointer\n";
161  throw MyException("RefPtr::operator*() const");
162  }
163  return *ptr_;
164  }
165 
167  T* pointee() {
168  return ptr_;
169  }
170 
172  const T* pointee() const {
173  return ptr_;
174  }
175 
177  bool operator==(const T* p) const {
178  return ptr_ == p;
179  }
180 
182  bool operator==(const RefPtr<T>& p) const {
183  return ptr_ == p.pointee();
184  }
185 
187  bool operator!=(const T* p) const {
188  return ptr_ != p;
189  }
190 
192  bool operator!=(const RefPtr<T>& p) const {
193  return ptr_ != p.ptr_;
194  }
195 
197  inline bool operator<(const RefPtr<T>& p) const {
198  return ptr_ < p.ptr_;
199  }
200 
202  template <class Other>
203  bool operator<(const RefPtr<Other>& p) const {
204  return ptr_ < p.pointee();
205  }
206 
207 private:
208  T* ptr_;
209 
211  inline void grab() {
212  if(ptr_ != NULL)
213  ptr_->reference_grab();
214  }
215 
219  inline void release() {
220  if(ptr_ != NULL) {
221  if(ptr_->reference_release() == 0)
222  delete ptr_;
223  }
224  }
225 };
226 
227 #endif //_utility_ref_RefPtr_
Definition: MyException.h:40
Definition: RefPtr.h:46
void grab()
Grab a reference to the current pointee if it is not NULL.
Definition: RefPtr.h:211
RefPtr< T > & operator=(T *p)
Assign the value of this RefPtr to the given pointee.
Definition: RefPtr.h:77
RefPtr(const RefPtr< T > &p)
Construct a new RefPtr and initialize to the given RefPtr pointee.
Definition: RefPtr.h:60
bool operator<(const RefPtr< Other > &p) const
Convenience routine to sort pointer values in standard containers.
Definition: RefPtr.h:203
RefPtr< T > & cast(RefPtr< Other > p)
Definition: RefPtr.h:124
T * ptr_
Definition: RefPtr.h:208
RefPtr()
Construct a new RefPtr and initialize the pointee to NULL.
Definition: RefPtr.h:52
RefPtr< T > & cast(Other *p)
Definition: RefPtr.h:100
T Type
Make the typename that this pointer holds accessible to other objects.
Definition: RefPtr.h:49
bool operator!=(const RefPtr< T > &p) const
Test inequality.
Definition: RefPtr.h:192
bool operator==(const RefPtr< T > &p) const
Compare the value of this pointee with the pointee of the given RefPtr.
Definition: RefPtr.h:182
bool operator==(const T *p) const
Compare the pointee of this RefPtr with the given pointer.
Definition: RefPtr.h:177
T * pointee()
Return the pointee of this RefPtr.
Definition: RefPtr.h:167
T * operator->() const
Definition: RefPtr.h:146
bool operator!=(const T *p) const
Test inequality.
Definition: RefPtr.h:187
void release()
Definition: RefPtr.h:219
const T * pointee() const
Return the pointee of this RefPtr in a const context.
Definition: RefPtr.h:172
~RefPtr()
Destroy this RefPtr.
Definition: RefPtr.h:72
RefPtr< T > & operator=(const RefPtr< T > &p)
Assign the value of this RefPtr to the pointee of the given RefPtr.
Definition: RefPtr.h:87
T & operator*() const
Definition: RefPtr.h:157
RefPtr(T *p)
Construct a new RefPtr and initialize the pointee as given.
Definition: RefPtr.h:55
RefPtr(RefPtr< Other > p)
Definition: RefPtr.h:67
bool operator<(const RefPtr< T > &p) const
Convenience routine to sort pointer values in standard containers.
Definition: RefPtr.h:197