From a15cf65c44d5c224169c32ef5495b68c758134b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 18 May 2014 16:08:14 +0200 Subject: Imported Upstream version 3.3.0.2 --- libcult/cult/mm/evptr.hxx | 221 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 libcult/cult/mm/evptr.hxx (limited to 'libcult/cult/mm/evptr.hxx') diff --git a/libcult/cult/mm/evptr.hxx b/libcult/cult/mm/evptr.hxx new file mode 100644 index 0000000..ed0bd93 --- /dev/null +++ b/libcult/cult/mm/evptr.hxx @@ -0,0 +1,221 @@ +// file : cult/mm/evptr.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_MM_EVPTR_HXX +#define CULT_MM_EVPTR_HXX + +#include + +#include +#include + +#include //@@ tmp + +namespace Cult +{ + namespace MM + { + // Leaks resource should dec_ref fail. + // + template + class Evptr: public Bits::EvptrBase + { + typedef Bits::EvptrBase Base; + + public: + Evptr (X* p = 0) + : Base (p, 0, locate (p, *counted)) + { + } + + Evptr (Evptr const& ep) + : Base (0, ep.cp_ ? ep.cp_ : ep.p_, ep.c_) + { + } + + template + Evptr (Bits::Transfer const& ct) + : Base (ct.p_, ct.cp_, ct.c_, false) + { + Bits::Transfer& t (const_cast&> (ct)); + + t.c_ = 0; + t.p_ = 0; + t.cp_ = 0; + } + + template + Evptr (Evptr const& ep) + : Base (0, ep.cp_ ? ep.cp_ : ep.p_, ep.c_) + { + //@@ + //printf ("X : %s\n", typeid (X).name ()); + //printf ("Y : %s\n", typeid (Y).name ()); + } + + template + Evptr (Evptr const& ep) + : Base (0, ep.cp_ ? ep.cp_ : ep.p_, ep.c_) + { + //@@ + //printf ("X : %s\n", typeid (X).name ()); + //printf ("Y : %s const\n", typeid (Y).name ()); + } + + public: + // After failure leaves object in destructable state. + // + Evptr& + operator= (Evptr const& ep) + { + this->assign (ep.cp_ ? ep.cp_ : ep.p_, ep.c_); + + return *this; + } + + template + Evptr& + operator= (Evptr const& ep) + { + this->assign (ep.cp_ ? ep.cp_ : ep.p_, ep.c_); + + return *this; + } + + template + Evptr& + operator= (Bits::Transfer const& ct) + { + Bits::Transfer& t (const_cast&> (ct)); + + transfer (t.p_, t.cp_, t.c_); + + t.c_ = 0; + t.p_ = 0; + t.cp_ = 0; + + return *this; + } + + protected: + using Base::get_; + + public: + X* + operator-> () const + { + if (X* p = get_ ()) return p; + + throw NullPointer (); + } + + X& + operator* () const + { + if (X* p = get_ ()) return *p; + + throw NullPointer (); + } + + Bits::Transfer + operator~ () + { + Counter* c (c_); + X* p (p_); + X const* cp (cp_); + + c_ = 0; + p_ = 0; + cp_ = 0; + + return Bits::Transfer (p, cp, c); + } + + public: + using Base::p_; + using Base::cp_; + using Base::c_; + + // Object pointed to by this becomes null. + // + template + Evptr + s_cast () + { + if (p_) + { + Counter* c (c_); + Y* p (static_cast (p_)); + + + c_ = 0; + p_ = 0; + cp_ = 0; + + return Evptr (p, 0, c); + } + else + { + Counter* c (c_); + Y const* cp (static_cast (cp_)); + + c_ = 0; + p_ = 0; + cp_ = 0; + + return Evptr (0, cp, c); + } + } + + // Object pointed to by this becomes null if dynamic_cast succeeds. + // + template + Evptr + d_cast () + { + if (p_) + { + if (Y* p = dynamic_cast (p_)) + { + Counter* c (c_); + + c_ = 0; + p_ = 0; + cp_ = 0; + + return Evptr (p, 0, c); + } + } + else if (Y const* cp = dynamic_cast (cp_)) + { + Counter* c (c_); + + c_ = 0; + p_ = 0; + cp_ = 0; + + return Evptr (0, cp, c); + } + + return Evptr (0); + } + + + private: + Evptr (X* p, X const* cp, Counter* c) // for *_cast + : Base (p, cp, c, false) + { + } + + private: + template + friend class Evptr; + }; + } + + using MM::Evptr; +} + +#endif // CULT_MM_EVPTR_HXX -- cgit v1.2.3