summaryrefslogtreecommitdiff
path: root/libcult/cult/mm/evptr.hxx
diff options
context:
space:
mode:
authorJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
committerJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
commita15cf65c44d5c224169c32ef5495b68c758134b7 (patch)
tree3419f58fc8e1b315ba8171910ee044c5d467c162 /libcult/cult/mm/evptr.hxx
Imported Upstream version 3.3.0.2upstream/3.3.0.2
Diffstat (limited to 'libcult/cult/mm/evptr.hxx')
-rw-r--r--libcult/cult/mm/evptr.hxx221
1 files changed, 221 insertions, 0 deletions
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 <boris@kolpackov.net>
+// 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 <cult/types/fundamental.hxx>
+
+#include <cult/mm/exception.hxx>
+#include <cult/mm/bits/evptr.hxx>
+
+#include <typeinfo> //@@ tmp
+
+namespace Cult
+{
+ namespace MM
+ {
+ // Leaks resource should dec_ref fail.
+ //
+ template <typename X>
+ class Evptr: public Bits::EvptrBase<X>
+ {
+ typedef Bits::EvptrBase<X> 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 <typename Y>
+ Evptr (Bits::Transfer<Y> const& ct)
+ : Base (ct.p_, ct.cp_, ct.c_, false)
+ {
+ Bits::Transfer<Y>& t (const_cast<Bits::Transfer<Y>&> (ct));
+
+ t.c_ = 0;
+ t.p_ = 0;
+ t.cp_ = 0;
+ }
+
+ template <typename Y>
+ Evptr (Evptr<Y> 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 <typename Y>
+ Evptr (Evptr<Y const> 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 <typename Y>
+ Evptr&
+ operator= (Evptr<Y> const& ep)
+ {
+ this->assign (ep.cp_ ? ep.cp_ : ep.p_, ep.c_);
+
+ return *this;
+ }
+
+ template <typename Y>
+ Evptr&
+ operator= (Bits::Transfer<Y> const& ct)
+ {
+ Bits::Transfer<Y>& t (const_cast<Bits::Transfer<Y>&> (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<X>
+ operator~ ()
+ {
+ Counter* c (c_);
+ X* p (p_);
+ X const* cp (cp_);
+
+ c_ = 0;
+ p_ = 0;
+ cp_ = 0;
+
+ return Bits::Transfer<X> (p, cp, c);
+ }
+
+ public:
+ using Base::p_;
+ using Base::cp_;
+ using Base::c_;
+
+ // Object pointed to by this becomes null.
+ //
+ template<typename Y>
+ Evptr<Y>
+ s_cast ()
+ {
+ if (p_)
+ {
+ Counter* c (c_);
+ Y* p (static_cast<Y*> (p_));
+
+
+ c_ = 0;
+ p_ = 0;
+ cp_ = 0;
+
+ return Evptr<Y> (p, 0, c);
+ }
+ else
+ {
+ Counter* c (c_);
+ Y const* cp (static_cast<Y const*> (cp_));
+
+ c_ = 0;
+ p_ = 0;
+ cp_ = 0;
+
+ return Evptr<Y> (0, cp, c);
+ }
+ }
+
+ // Object pointed to by this becomes null if dynamic_cast succeeds.
+ //
+ template<typename Y>
+ Evptr<Y>
+ d_cast ()
+ {
+ if (p_)
+ {
+ if (Y* p = dynamic_cast<Y*> (p_))
+ {
+ Counter* c (c_);
+
+ c_ = 0;
+ p_ = 0;
+ cp_ = 0;
+
+ return Evptr<Y> (p, 0, c);
+ }
+ }
+ else if (Y const* cp = dynamic_cast<Y const*> (cp_))
+ {
+ Counter* c (c_);
+
+ c_ = 0;
+ p_ = 0;
+ cp_ = 0;
+
+ return Evptr<Y> (0, cp, c);
+ }
+
+ return Evptr<Y> (0);
+ }
+
+
+ private:
+ Evptr (X* p, X const* cp, Counter* c) // for *_cast
+ : Base (p, cp, c, false)
+ {
+ }
+
+ private:
+ template <typename>
+ friend class Evptr;
+ };
+ }
+
+ using MM::Evptr;
+}
+
+#endif // CULT_MM_EVPTR_HXX