From fb6c58e08102200b9f23e7b940130defed4ce5ea Mon Sep 17 00:00:00 2001 From: Determinant Date: Fri, 6 Jul 2018 13:41:07 -0400 Subject: add BoxObj --- include/salticidae/ref.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/include/salticidae/ref.h b/include/salticidae/ref.h index d68632d..c2dcdd3 100644 --- a/include/salticidae/ref.h +++ b/include/salticidae/ref.h @@ -30,6 +30,49 @@ namespace salticidae { +template +class BoxObj { + T *obj; + + void release() { + if (obj) delete obj; + } + + public: + template + friend BoxObj static_pointer_cast(const BoxObj &other); + operator T*() const { return obj; } + T *operator->() const { return obj; } + BoxObj(): obj(nullptr) {} + BoxObj(T *obj): obj(obj) {} + BoxObj &operator=(const BoxObj &other) = delete; + BoxObj &operator=(BoxObj &&other) { + release(); + obj = other.obj; + other.obj = nullptr; + return *this; + } + + BoxObj(const BoxObj &other) = delete; + BoxObj(BoxObj &&other): obj(other.obj) { + other.obj = nullptr; + } + + template + BoxObj(BoxObj &&other): obj(other.obj) { + other.obj = nullptr; + } + + ~BoxObj() { release(); } +}; + +template +BoxObj static_pointer_cast(BoxObj &&other) { + BoxObj box{}; + box.obj = static_cast(other.obj); + return std::move(box); +} + struct _RCCtl { size_t ref_cnt; size_t weak_cnt; @@ -122,12 +165,18 @@ class RcObjBase { friend std::hash>; template friend RcObjBase static_pointer_cast(const RcObjBase &other); + template + friend RcObjBase static_pointer_cast(RcObjBase &&other); template friend class RcObjBase; operator T*() const { return obj; } T *operator->() const { return obj; } RcObjBase(): obj(nullptr), ctl(nullptr) {} RcObjBase(T *obj): obj(obj), ctl(new R()) {} + RcObjBase(BoxObj &&box_ref): obj(box_ref.obj), ctl(new R()) { + box_ref.obj = nullptr; + } + RcObjBase &operator=(const RcObjBase &other) { release(); obj = other.obj; @@ -152,6 +201,12 @@ class RcObjBase { other.ctl = nullptr; } + template + RcObjBase(RcObjBase &&other): + obj(other.obj), ctl(other.ctl) { + other.ctl = nullptr; + } + RcObjBase(const WeakObjBase &other) { if (other.ctl && other.ctl->ref_cnt) { @@ -180,12 +235,22 @@ RcObjBase static_pointer_cast(const RcObjBase &other) { return std::move(rc); } +template +RcObjBase static_pointer_cast(RcObjBase &&other) { + RcObjBase rc{}; + rc.obj = static_cast(other.obj); + rc.ctl = other.ctl; + other.ctl = nullptr; + return std::move(rc); +} + template inline WeakObjBase::WeakObjBase(const RcObjBase &other): obj(other.obj), ctl(other.ctl) { if (ctl) ctl->add_weak(); } + template using RcObj = RcObjBase; template using WeakObj = WeakObjBase; -- cgit v1.2.3-70-g09d2