1 #ifndef SYMENGINE_RCP_H
2 #define SYMENGINE_RCP_H
8 #if __cplusplus <= 201703L
14 #include <symengine/symengine_config.h>
15 #include <symengine/symengine_assert.h>
17 #if defined(WITH_SYMENGINE_RCP)
19 #if defined(WITH_SYMENGINE_THREAD_SAFE)
26 #include <symengine/utilities/teuchos/Teuchos_RCP.hpp>
27 #include <symengine/utilities/teuchos/Teuchos_TypeNameTraits.hpp>
34 #if defined(WITH_SYMENGINE_RCP)
44 inline explicit Ptr(T *ptr) : ptr_(ptr)
46 SYMENGINE_ASSERT(ptr_ !=
nullptr)
48 inline Ptr(
const Ptr<T> &ptr) : ptr_(ptr.ptr_) {}
50 inline Ptr(
const Ptr<T2> &ptr) : ptr_(ptr.get())
53 Ptr<T> &operator=(
const Ptr<T> &ptr)
58 #if defined(HAVE_DEFAULT_CONSTRUCTORS)
59 inline Ptr(Ptr &&) =
default;
60 Ptr<T> &operator=(Ptr &&) =
default;
62 inline T *operator->()
const
66 inline T &operator*()
const
74 inline T *getRawPtr()
const
78 inline const Ptr<T> ptr()
const
88 inline Ptr<T> outArg(T &arg)
98 inline Ptr<T> ptrFromRef(T &arg)
113 RCP(ENull null_arg =
null) : ptr_(nullptr) {}
114 explicit RCP(T *p) : ptr_(p)
116 SYMENGINE_ASSERT(ptr_ !=
nullptr)
120 RCP(
const RCP<T> &rp) : ptr_(rp.ptr_)
127 RCP(
const RCP<T2> &r_ptr) : ptr_(r_ptr.get())
133 RCP(RCP<T> &&rp) SYMENGINE_NOEXCEPT : ptr_(rp.ptr_)
140 SYMENGINE_NOEXCEPT : ptr_(r_ptr.get())
144 ~RCP() SYMENGINE_NOEXCEPT
146 if (ptr_ !=
nullptr and --(ptr_->refcount_) == 0)
149 T *operator->()
const
151 SYMENGINE_ASSERT(ptr_ !=
nullptr)
156 SYMENGINE_ASSERT(ptr_ !=
nullptr)
165 return Ptr<T>(get());
169 return ptr_ ==
nullptr;
172 bool operator==(
const RCP<T2> &p2)
const
174 return ptr_ == p2.ptr_;
177 bool operator!=(
const RCP<T2> &p2)
const
179 return ptr_ != p2.ptr_;
182 RCP<T> &operator=(
const RCP<T> &r_ptr)
184 T *r_ptr_ptr_ = r_ptr.ptr_;
185 if (not r_ptr.is_null())
186 (r_ptr_ptr_->refcount_)++;
187 if (not is_null() and --(ptr_->refcount_) == 0)
193 RCP<T> &operator=(RCP<T> &&r_ptr)
195 std::swap(ptr_, r_ptr.ptr_);
200 if (not is_null() and --(ptr_->refcount_) == 0)
215 inline RCP<T> rcp(T *p)
220 template <
class T2,
class T1>
221 inline RCP<T2> rcp_static_cast(
const RCP<T1> &p1)
224 T2 *check =
static_cast<T2 *
>(p1.get());
225 return RCP<T2>(check);
228 template <
class T2,
class T1>
229 inline RCP<T2> rcp_dynamic_cast(
const RCP<T1> &p1)
231 if (not p1.is_null()) {
234 p =
dynamic_cast<T2 *
>(p1.get());
239 throw std::runtime_error(
"rcp_dynamic_cast: cannot convert.");
242 template <
class T2,
class T1>
243 inline RCP<T2> rcp_const_cast(
const RCP<T1> &p1)
246 T2 *check =
const_cast<T2 *
>(p1.get());
247 return RCP<T2>(check);
251 inline bool operator==(
const RCP<T> &p, ENull)
253 return p.get() ==
nullptr;
256 template <
typename T>
257 std::string typeName(
const T &t)
262 void print_stack_on_segfault();
267 using Teuchos::outArg;
268 using Teuchos::print_stack_on_segfault;
270 using Teuchos::ptrFromRef;
273 using Teuchos::rcp_const_cast;
274 using Teuchos::rcp_dynamic_cast;
275 using Teuchos::rcp_static_cast;
276 using Teuchos::typeName;
288 #if defined(WITH_SYMENGINE_RCP)
289 return rcp(
static_cast<T *
>(
this));
291 return rcp_static_cast<T>(weak_self_ptr_.create_strong());
298 #if defined(WITH_SYMENGINE_RCP)
299 return rcp(
static_cast<const T *
>(
this));
301 return rcp_static_cast<const T>(weak_self_ptr_.create_strong());
309 #if defined(WITH_SYMENGINE_RCP)
310 return rcp(
static_cast<const T2 *
>(
this));
312 return rcp_static_cast<const T2>(weak_self_ptr_.create_strong());
316 unsigned int use_count()
const
318 #if defined(WITH_SYMENGINE_RCP)
321 return weak_self_ptr_.strong_count();
327 #if defined(WITH_SYMENGINE_RCP)
338 #if defined(WITH_SYMENGINE_THREAD_SAFE)
339 mutable std::atomic<unsigned int> refcount_;
341 mutable unsigned int refcount_;
344 EnableRCPFromThis() : refcount_(0) {}
348 mutable RCP<T> weak_self_ptr_;
350 void set_weak_self_ptr(
const RCP<T> &w)
355 void set_weak_self_ptr(
const RCP<const T> &w)
const
357 weak_self_ptr_ = rcp_const_cast<T>(w);
361 #if defined(WITH_SYMENGINE_RCP)
366 template <
typename T_,
typename... Args>
367 friend inline RCP<T_> make_rcp(Args &&...args);
370 template <
typename T,
typename... Args>
371 inline RCP<T> make_rcp(Args &&...args)
373 #if defined(WITH_SYMENGINE_RCP)
374 return rcp(
new T(std::forward<Args>(args)...));
376 RCP<T> p = rcp(
new T(std::forward<Args>(args)...));
377 p->set_weak_self_ptr(p.create_weak());
RCP< const T2 > rcp_from_this_cast() const
Get RCP<T2> pointer to self (it will cast the pointer to T2)
RCP< T > rcp_from_this()
Get RCP<T> pointer to self (it will cast the pointer to T)
RCP< const T > rcp_from_this() const
Get RCP<const T> pointer to self (it will cast the pointer to const T)
Main namespace for SymEngine package.