summaryrefslogtreecommitdiff
path: root/libcult/cult/mm/shptr.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcult/cult/mm/shptr.hxx')
-rw-r--r--libcult/cult/mm/shptr.hxx139
1 files changed, 139 insertions, 0 deletions
diff --git a/libcult/cult/mm/shptr.hxx b/libcult/cult/mm/shptr.hxx
new file mode 100644
index 0000000..6630b1c
--- /dev/null
+++ b/libcult/cult/mm/shptr.hxx
@@ -0,0 +1,139 @@
+// file : cult/mm/Shptr.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_SHPTR_HXX
+#define CULT_MM_SHPTR_HXX
+
+#include <cult/types/fundamental.hxx>
+
+#include <cult/mm/exception.hxx>
+#include <cult/mm/bits/shptr.hxx>
+
+namespace Cult
+{
+ namespace MM
+ {
+ // Leaks resource should dec_ref fail.
+ //
+ template <typename X>
+ class Shptr : public Bits::Shptr<X>
+ {
+ typedef Bits::Shptr<X> Base;
+
+ public:
+ Shptr (X* p = 0)
+ : Base (p, locate (p, *counted), false)
+ {
+ }
+
+ Shptr (Shptr const& ap)
+ : Base (ap.p_, ap.c_)
+ {
+ }
+
+ template <typename Y>
+ Shptr (Shptr<Y> const& ap)
+ : Base (ap.p_, ap.c_)
+ {
+ }
+
+ public:
+ // After failure leaves object in destructable state.
+ //
+ Shptr&
+ operator= (Shptr const& ap)
+ {
+ this->assign (ap);
+ return *this;
+ }
+
+ template <typename Y>
+ Shptr&
+ operator= (Shptr<Y> const& ap)
+ {
+ this->assign (ap);
+ return *this;
+ }
+
+ public:
+ X*
+ operator-> () const
+ {
+ if (p_ == 0)
+ throw NullPointer ();
+
+ return p_;
+ }
+
+ X&
+ operator* () const
+ {
+ if (p_ == 0)
+ throw NullPointer ();
+
+ return *p_;
+ }
+
+ // conversion to bool
+ //
+ typedef X* (Shptr::*BooleanConvertible)() const;
+
+ operator BooleanConvertible () const throw ()
+ {
+ return p_ ? &Shptr<X>::operator-> : 0;
+ }
+
+ public:
+ X*
+ get () const throw ()
+ {
+ return p_;
+ }
+
+ X*
+ release () throw ()
+ {
+ return release_ ();
+ }
+
+ Size
+ count () const
+ {
+ if (p_ == 0)
+ throw NullPointer ();
+
+ return c_->count ();
+ }
+
+ public:
+ template<typename Y>
+ Shptr<Y>
+ d_cast () const
+ {
+ Y* p (dynamic_cast<Y*> (p_));
+ return Shptr<Y> (p, p ? c_ : 0);
+ }
+
+ private:
+ Shptr (X* p, Counter* c)
+ : Base (p, c)
+ {
+ }
+
+ template <typename>
+ friend class Shptr;
+
+ protected:
+ using Base::release_;
+
+ using Base::p_;
+ using Base::c_;
+ };
+ }
+
+ using MM::Shptr;
+}
+
+#endif // CULT_MM_SHPTR_HXX