omega_h
Reliable mesh adaptation
Omega_h_memory.hpp
1 #ifndef OMEGA_H_MEMORY_HPP
2 #define OMEGA_H_MEMORY_HPP
3 
4 #include <map>
5 
6 namespace Omega_h {
7 
8 template <typename T>
9 class SharedRef {
10 public:
11  SharedRef() = default;
12 
13  template <typename... Args>
14  explicit SharedRef(Args&&... args)
15 #if defined(OMEGA_H_COMPILING_FOR_HOST)
16  : ptr_(new T(std::forward<Args>(args)...)) {
17  [[maybe_unused]] auto [itr, inserted] = refCount_.insert(std::make_pair(ptr_, 1));
18  assert(inserted);
19  }
20 #else
21  {
22  }
23 #endif
24 
25  OMEGA_H_INLINE SharedRef(const SharedRef& other) {
26 #if defined(OMEGA_H_COMPILING_FOR_HOST)
27  if (*this) {
28  decrementRefCount();
29  }
30 
31  if (!other) {
32  ptr_ = nullptr;
33  return;
34  }
35 
36  ptr_ = other.ptr_;
37  auto itr = refCount_.find(ptr_);
38  assert(itr != refCount_.end());
39  itr->second++;
40 #endif
41  }
42 
43  OMEGA_H_INLINE SharedRef(SharedRef&& other) noexcept {
44 #if defined(OMEGA_H_COMPILING_FOR_HOST)
45  if (*this) {
46  decrementRefCount();
47  }
48 
49  if (!other) {
50  ptr_ = nullptr;
51  return;
52  }
53 
54  ptr_ = other.ptr_;
55  auto itr = refCount_.find(ptr_);
56  assert(itr != refCount_.end());
57  itr->second++;
58 #endif
59  }
60 
61  SharedRef& operator=(const SharedRef& other) {
62 #if defined(OMEGA_H_COMPILING_FOR_HOST)
63  if (*this) {
64  decrementRefCount();
65  }
66 
67  if (!other) {
68  ptr_ = nullptr;
69  return *this;
70  }
71 
72  ptr_ = other.ptr_;
73  auto itr = refCount_.find(ptr_);
74  assert(itr != refCount_.end());
75  itr->second++;
76 
77 #endif
78  return *this;
79  }
80 
81  SharedRef& operator=(SharedRef&& other) noexcept {
82 #if defined(OMEGA_H_COMPILING_FOR_HOST)
83  if (*this) {
84  decrementRefCount();
85  }
86 
87  if (!other) {
88  ptr_ = nullptr;
89  return *this;
90  }
91 
92  ptr_ = other.ptr_;
93  auto itr = refCount_.find(ptr_);
94  assert(itr != refCount_.end());
95  itr->second++;
96 
97 #endif
98  return *this;
99  }
100 
101  OMEGA_H_INLINE T* get() const {
102 #if defined(OMEGA_H_COMPILING_FOR_HOST)
103  return ptr_;
104 #else
105  return nullptr;
106 #endif
107  }
108 
109  OMEGA_H_INLINE T* operator->() const {
110 #if defined(OMEGA_H_COMPILING_FOR_HOST)
111  return ptr_;
112 #else
113  return nullptr;
114 #endif
115  }
116 
117  OMEGA_H_INLINE T& operator*() const {
118 #if defined(OMEGA_H_COMPILING_FOR_HOST)
119  return *ptr_;
120 #else
121  return nullptr;
122 #endif
123  }
124 
125  OMEGA_H_INLINE ~SharedRef() {
126 #if defined(OMEGA_H_COMPILING_FOR_HOST)
127  if (*this) {
128  decrementRefCount();
129  }
130 #endif
131  }
132 
133  OMEGA_H_INLINE explicit operator bool() const {
134 #if defined(OMEGA_H_COMPILING_FOR_HOST)
135  return ptr_ != nullptr && (refCount_.find(ptr_) != refCount_.end());
136 #else
137  return false;
138 #endif
139  }
140 
141  OMEGA_H_INLINE int use_count() const {
142 #if defined(OMEGA_H_COMPILING_FOR_HOST)
143  return *this ? refCount_.find(ptr_)->second : 0;
144 #else
145  return 0;
146 #endif
147  }
148 
149 private:
150  void decrementRefCount() {
151 #if defined(OMEGA_H_COMPILING_FOR_HOST)
152  if (!*this) {
153  return;
154  }
155 
156  auto itr = refCount_.find(ptr_);
157  assert(itr != refCount_.end());
158  itr->second--;
159  if (itr->second == 0) {
160  refCount_.erase(itr);
161  delete ptr_;
162  }
163 #endif
164  }
165 
166  T* ptr_ = nullptr;
167 
168  static std::map<T*, int> refCount_;
169 };
170 
171 template <typename T>
172 std::map<T*, int> SharedRef<T>::refCount_;
173 
174 } // namespace Omega_h
175 
176 #endif // OMEGA_H_MEMORY_HPP
Definition: Omega_h_memory.hpp:9
Definition: amr_mpi_test.cpp:6