summaryrefslogtreecommitdiff
path: root/libcult/cult/mm
diff options
context:
space:
mode:
Diffstat (limited to 'libcult/cult/mm')
-rw-r--r--libcult/cult/mm/arch/generic/counter.hxx45
-rw-r--r--libcult/cult/mm/arch/generic/counter.ixx47
-rw-r--r--libcult/cult/mm/arch/i386/counter.hxx43
-rw-r--r--libcult/cult/mm/arch/i386/counter.ixx46
-rw-r--r--libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.hxx43
-rw-r--r--libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.ixx46
-rw-r--r--libcult/cult/mm/bits/evptr.hxx379
-rw-r--r--libcult/cult/mm/bits/shptr.hxx85
-rw-r--r--libcult/cult/mm/buffer.cxx140
-rw-r--r--libcult/cult/mm/buffer.hxx80
-rw-r--r--libcult/cult/mm/counter.cxx14
-rw-r--r--libcult/cult/mm/counter.hxx79
-rw-r--r--libcult/cult/mm/counter.ixx38
-rw-r--r--libcult/cult/mm/evptr.hxx221
-rw-r--r--libcult/cult/mm/exception.hxx31
-rw-r--r--libcult/cult/mm/new.cxx192
-rw-r--r--libcult/cult/mm/new.hxx297
-rw-r--r--libcult/cult/mm/new.ixx36
-rw-r--r--libcult/cult/mm/shptr.hxx139
-rw-r--r--libcult/cult/mm/static-ptr.hxx75
20 files changed, 0 insertions, 2076 deletions
diff --git a/libcult/cult/mm/arch/generic/counter.hxx b/libcult/cult/mm/arch/generic/counter.hxx
deleted file mode 100644
index 6a26759..0000000
--- a/libcult/cult/mm/arch/generic/counter.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
-// file : cult/mm/arch/generic/counter.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_ARCH_GENERIC_COUNTER_HXX
-#define CULT_MM_ARCH_GENERIC_COUNTER_HXX
-
-#include <cult/types/fundamental.hxx>
-#include <cult/sched/spin.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- class Counter: public NonCopyable
- {
- public:
- Counter ();
-
- // After failure assume the counter has its old value.
- //
- Void
- inc_ref ();
-
-
- // After failure assume the counter has its new value.
- //
- Boolean
- dec_ref ();
-
-
- Size
- count () const;
-
- private:
- Size value_;
- mutable Sched::Spin spin_;
- };
- }
-}
-
-#include <cult/mm/arch/generic/counter.ixx>
-
-#endif // CULT_MM_ARCH_GENERIC_COUNTER_HXX
diff --git a/libcult/cult/mm/arch/generic/counter.ixx b/libcult/cult/mm/arch/generic/counter.ixx
deleted file mode 100644
index 648d28a..0000000
--- a/libcult/cult/mm/arch/generic/counter.ixx
+++ /dev/null
@@ -1,47 +0,0 @@
-// file : cult/mm/arch/generic/counter.ixx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <cult/sched/lock.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- inline
- Counter::
- Counter ()
- : value_ (1)
- {
- }
-
- inline
- Void Counter::
- inc_ref ()
- {
- Sched::Lock l (spin_);
-
- ++value_;
- }
-
- inline
- Boolean Counter::
- dec_ref ()
- {
- Sched::Lock l (spin_);
-
- return --value_ == 0;
-
- }
-
- inline
- Size Counter::
- count () const
- {
- Sched::Lock l (spin_);
-
- return value_;
- }
- }
-}
diff --git a/libcult/cult/mm/arch/i386/counter.hxx b/libcult/cult/mm/arch/i386/counter.hxx
deleted file mode 100644
index 21f5f63..0000000
--- a/libcult/cult/mm/arch/i386/counter.hxx
+++ /dev/null
@@ -1,43 +0,0 @@
-// file : cult/mm/arch/i386/counter.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_ARCH_I386_COUNTER_HXX
-#define CULT_MM_ARCH_I386_COUNTER_HXX
-
-#include <cult/types/fundamental.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- class Counter: public NonCopyable
- {
- public:
- Counter ();
-
- // After failure assume the counter has its old value.
- //
- Void
- inc_ref ();
-
-
- // After failure assume the counter has its new value.
- //
- Boolean
- dec_ref ();
-
-
- Size
- count () const;
-
- private:
- Size value_;
- };
- }
-}
-
-#include <cult/mm/arch/i386/counter.ixx>
-
-#endif // CULT_MM_ARCH_I386_COUNTER_HXX
diff --git a/libcult/cult/mm/arch/i386/counter.ixx b/libcult/cult/mm/arch/i386/counter.ixx
deleted file mode 100644
index 8279394..0000000
--- a/libcult/cult/mm/arch/i386/counter.ixx
+++ /dev/null
@@ -1,46 +0,0 @@
-// file : cult/mm/arch/i386/counter.ixx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-namespace Cult
-{
- namespace MM
- {
- inline
- Counter::
- Counter ()
- : value_ (1)
- {
- }
-
- inline
- Void Counter::
- inc_ref ()
- {
- asm volatile ("lock; incl %0"
- :"=m" (value_)
- :"m" (value_));
- }
-
- inline
- Boolean Counter::
- dec_ref ()
- {
- register unsigned char r;
-
- asm volatile("lock; decl %0; setz %1"
- :"=m" (value_), "=rm" (r)
- :"m" (value_));
-
- return r != 0;
- }
-
- inline
- Size Counter::
- count () const
- {
- return value_;
- }
- }
-}
diff --git a/libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.hxx b/libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.hxx
deleted file mode 100644
index 5869b09..0000000
--- a/libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.hxx
+++ /dev/null
@@ -1,43 +0,0 @@
-// file : cult/mm/arch/i386/i486/i586/i686/x86_64/counter.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_ARCH_I386_I486_I586_I686_X86_64_COUNTER_HXX
-#define CULT_MM_ARCH_I386_I486_I586_I686_X86_64_COUNTER_HXX
-
-#include <cult/types/fundamental.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- class Counter: public NonCopyable
- {
- public:
- Counter ();
-
- // After failure assume the counter has its old value.
- //
- Void
- inc_ref ();
-
-
- // After failure assume the counter has its new value.
- //
- Boolean
- dec_ref ();
-
-
- Size
- count () const;
-
- private:
- Size value_;
- };
- }
-}
-
-#include <cult/mm/arch/i386/i486/i586/i686/x86_64/counter.ixx>
-
-#endif // CULT_MM_ARCH_I386_I486_I586_I686_X86_64_COUNTER_HXX
diff --git a/libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.ixx b/libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.ixx
deleted file mode 100644
index 9e9e7f4..0000000
--- a/libcult/cult/mm/arch/i386/i486/i586/i686/x86_64/counter.ixx
+++ /dev/null
@@ -1,46 +0,0 @@
-// file : cult/mm/arch/i386/i486/i586/i686/x86_64/counter.ixx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-namespace Cult
-{
- namespace MM
- {
- inline
- Counter::
- Counter ()
- : value_ (1)
- {
- }
-
- inline
- Void Counter::
- inc_ref ()
- {
- asm volatile ("lock; incq %0"
- :"=m" (value_)
- :"m" (value_));
- }
-
- inline
- Boolean Counter::
- dec_ref ()
- {
- register unsigned char r;
-
- asm volatile("lock; decq %0; setz %1"
- :"=m" (value_), "=rm" (r)
- :"m" (value_));
-
- return r != 0;
- }
-
- inline
- Size Counter::
- count () const
- {
- return value_;
- }
- }
-}
diff --git a/libcult/cult/mm/bits/evptr.hxx b/libcult/cult/mm/bits/evptr.hxx
deleted file mode 100644
index 02f0b48..0000000
--- a/libcult/cult/mm/bits/evptr.hxx
+++ /dev/null
@@ -1,379 +0,0 @@
-// file : cult/mm/bits/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_BITS_EVPTR_HXX
-#define CULT_MM_BITS_EVPTR_HXX
-
-#include <cult/types/fundamental.hxx>
-
-#include <cult/meta/answer.hxx>
-
-#include <cult/mm/counter.hxx>
-#include <cult/mm/exception.hxx>
-
-#include <cassert> // assert
-
-namespace Cult
-{
- namespace MM
- {
-
- //@@ Should be in mm/evptr.hxx
- //
- struct Clone: virtual Exception {};
-
- template <typename X>
- class Evptr;
-
- namespace Bits
- {
- template <typename x, Evptr<x> (x::*f) () const = &x::clone>
- struct Helper;
-
- //@@ Should be generalized and moved to Cult::meta
- //
- template <typename X>
- struct has_clone
- {
- template <typename y>
- static Meta::Yes
- test (Helper<y>*);
-
- template <typename>
- static Meta::No
- test (...);
-
- static Boolean const r = sizeof (test<X> (0)) == sizeof (Meta::Yes);
- };
-
- //@@ Need to incorporate tests for polymorpism and NonCopyable.
- //
-
- template <typename X, Boolean = has_clone<X>::r>
- struct Cloner;
-
- template <typename X>
- struct Cloner<X, true>
- {
- static X*
- clone (X const* cp)
- {
- return cp->clone ().release ();
- }
- };
-
- template <typename X>
- struct Cloner<X, false>
- {
- static X*
- clone (X const*)
- {
- throw MM::Clone ();
- }
- };
- }
-
- namespace Bits
- {
- template <typename X>
- class Transfer;
- }
-
- namespace Bits
- {
- template <typename X>
- class EvptrBase
- {
- protected:
- ~EvptrBase ()
- {
- free (p_ ? p_ : cp_, c_);
- }
-
- EvptrBase (X* p, X const* cp, Counter* c, Boolean inc = true)
- : p_ (p), cp_ (cp), c_ (c)
- {
- assert (!(p_ != 0 && cp_ != 0));
-
- if (cp_ != 0 && c_ && inc) c_->inc_ref ();
- }
-
- public:
- X*
- get () const
- {
- return get_ ();
- }
-
- X*
- release ()
- {
- X* p (get_ ());
-
- c_ = 0;
- p_ = 0;
- cp_ = 0;
-
- return p;
- }
-
- Size
- count () const
- {
- if (c_ == 0) throw NullPointer ();
- return c_->count ();
- }
-
- public:
- // Conversion to Boolean.
- //
- typedef X* (EvptrBase::*BooleanConvertible)() const;
-
- operator BooleanConvertible () const
- {
- return c_ ? &EvptrBase::get : 0;
- }
-
- protected:
- Void
- assign (X const* cp, Counter* c)
- {
- if (c_ && c_ == c) throw SelfAssignment ();
-
- free (p_ ? p_ : cp_, c_);
-
- if (c) c->inc_ref ();
-
- c_ = c;
- p_ = 0;
- cp_ = cp;
- }
-
- Void
- transfer (X* p, X const* cp, Counter* c)
- {
- free (p_ ? p_ : cp_, c_);
-
- c_ = c;
- p_ = p;
- cp_ = cp;
- }
-
- protected:
- X*
- get_ () const
- {
- if (c_ == 0) return 0;
-
- assert (p_ != 0 || cp_ != 0);
-
- if (p_ != 0)
- {
- if (c_->count () == 1) return p_;
- else
- {
- // Convert to shared case.
- //
- cp_ = p_;
- p_ = 0;
- }
- }
-
- // Shared case with cloning.
- //
-
- // Check if we are the sole owner.
- //
- if (c_->count () == 1)
- {
- // Convert to exclusive case.
- //
- p_ = const_cast<X*> (cp_);
- cp_ = 0;
- }
- else
- {
- assert (cp_ != 0);
-
- //p_ = cp_->clone ().release ();
-
- p_ = Cloner<X>::clone (cp_);
-
- free (cp_, c_);
-
- cp_ = 0;
- c_ = locate (p_, *counted);
- }
-
- return p_;
- }
-
- static Void
- free (X const* p, Counter* c)
- {
- if (c && c->dec_ref ())
- {
- assert (p != 0);
- delete p;
- }
- }
-
- private:
- template <typename>
- friend class Evptr;
-
- template <typename>
- friend class Transfer;
-
- mutable X* p_;
- mutable X const* cp_;
- mutable Counter* c_;
- };
-
-
- template <typename X>
- class EvptrBase<X const>
- {
- protected:
- ~EvptrBase ()
- {
- free (p_ ? p_ : cp_, c_);
- }
-
- EvptrBase (X const* p, X const* cp, Counter* c, Boolean inc = true)
- : p_ (p), cp_ (cp), c_ (c)
- {
- assert (!(p_ != 0 && cp_ != 0));
-
- if (cp_ != 0 && c_ && inc) c_->inc_ref ();
- }
-
- public:
- X const*
- get ()
- {
- return get_ ();
- }
-
- //@@ Should clone if shared?
- //
- X const*
- release ()
- {
- X const* p (get_ ());
-
- c_ = 0;
- p_ = 0;
- cp_ = 0;
-
- return p;
- }
-
- Size
- count () const
- {
- if (c_ == 0) throw NullPointer ();
- return c_->count ();
- }
-
- public:
- // Conversion to Boolean.
- //
- typedef X const* (EvptrBase::*BooleanConvertible)() const;
-
- operator BooleanConvertible () const
- {
- return c_ ? &EvptrBase::get : 0;
- }
-
- protected:
- Void
- assign (X const* cp, Counter* c)
- {
- if (c_ && c_ == c) throw SelfAssignment ();
-
- free (p_ ? p_ : cp_, c_);
-
- if (c) c->inc_ref ();
-
- c_ = c;
- p_ = 0;
- cp_ = cp;
- }
-
- Void
- transfer (X const* p, X const* cp, Counter* c)
- {
- free (p_ ? p_ : cp_, c_);
-
- c_ = c;
- p_ = p;
- cp_ = cp;
- }
-
- protected:
- X const*
- get_ () const
- {
- return p_ ? p_ : cp_;
- }
-
- static Void
- free (X const* p, Counter* c)
- {
- if (c && c->dec_ref ())
- {
- assert (p != 0);
- delete p;
- }
- }
-
- private:
- template <typename>
- friend class Evptr;
-
- template <typename>
- friend class Transfer;
-
- mutable X const* p_;
- mutable X const* cp_;
- mutable Counter* c_;
- };
- }
-
- namespace Bits
- {
- template <typename X>
- class Transfer : protected EvptrBase<X>
- {
- public:
- Transfer (Transfer<X> const& ct)
- : EvptrBase<X> (ct.p_, ct.cp_, ct.c_, false)
- {
- Transfer<X>& t (const_cast<Transfer<X>&> (ct));
-
- t.c_ = 0;
- t.p_ = 0;
- t.cp_ = 0;
- }
-
- private:
- Transfer (X* p, X const* cp, Counter* c)
- : EvptrBase<X> (p, cp, c, false)
- {
- }
-
- template <typename>
- friend class Evptr;
-
- private:
- Transfer<X>&
- operator= (Transfer<X> const&);
- };
- }
- }
-}
-
-#endif // CULT_MM_BITS_EVPTR_HXX
diff --git a/libcult/cult/mm/bits/shptr.hxx b/libcult/cult/mm/bits/shptr.hxx
deleted file mode 100644
index 7089c53..0000000
--- a/libcult/cult/mm/bits/shptr.hxx
+++ /dev/null
@@ -1,85 +0,0 @@
-// file : cult/mm/bits/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_BITS_SHPTR_HXX
-#define CULT_MM_BITS_SHPTR_HXX
-
-#include <cult/types/fundamental.hxx>
-
-#include <cult/mm/counter.hxx>
-#include <cult/mm/exception.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- namespace Bits
- {
- template <typename X>
- class Shptr
- {
- protected:
- ~Shptr ()
- {
- if (c_ && c_->dec_ref ()) delete p_;
- }
-
- Shptr (X* p, Counter* c, Boolean inc = true)
- : p_ (p), c_ (c)
- {
- if (c_ && inc) c_->inc_ref ();
- }
-
- protected:
- X*
- release_ () throw ()
- {
- X* tmp (p_);
-
- c_ = 0;
- p_ = 0;
-
- return tmp;
- }
-
- protected:
- template<typename y>
- Void
- assign (Shptr<y> const& bp, Boolean inc = true)
- {
- assign (bp.p_, bp.c_, inc);
- }
-
- Void
- assign (X* p, Counter* c, Boolean inc)
- {
- if (c_ && c_ == c) throw SelfAssignment ();
-
- if (c_)
- {
- Counter* t (c_);
- c_ = 0;
- p_ = 0;
- t->dec_ref ();
- }
-
- if (c && inc) c->inc_ref ();
-
- p_ = p;
- c_ = c;
- }
-
- protected:
- template <typename>
- friend class Shptr;
-
- X* p_;
- Counter* c_;
- };
- }
- }
-}
-
-#endif // CULT_MM_BITS_SHPTR_HXX
diff --git a/libcult/cult/mm/buffer.cxx b/libcult/cult/mm/buffer.cxx
deleted file mode 100644
index c3a28ff..0000000
--- a/libcult/cult/mm/buffer.cxx
+++ /dev/null
@@ -1,140 +0,0 @@
-// file : cult/mm/buffer.cxx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <cult/mm/buffer.hxx>
-
-#include <cstdlib> // malloc, realloc, free
-#include <cstring> // memcpy
-
-namespace Cult
-{
- namespace MM
- {
- Buffer::
- ~Buffer ()
- {
- std::free (b_);
- }
-
- Buffer::
- Buffer (Size capacity, Size size) throw (ZeroCapacity, Bounds, BadAlloc)
- : c_ (capacity), s_ (size), p_ (0)
- {
- if (c_ == 0) throw ZeroCapacity ();
- if (s_ > c_) throw Bounds ();
-
- b_ = std::malloc (c_);
-
- if (b_ == 0) throw BadAlloc ();
- }
-
- Buffer::
- Buffer (void const* p, size_t s)
- : c_ (s), s_ (s), p_ (0)
- {
- if (c_ == 0) throw ZeroCapacity ();
-
- b_ = std::malloc (c_);
-
- if (b_ == 0) throw BadAlloc ();
-
- std::memcpy (b_, p, s);
- }
-
-
- Buffer::
- Buffer (Buffer const& b)
- : c_ (b.c_), s_ (b.s_), p_ (b.p_)
- {
- b_ = std::malloc (c_);
-
- if (b_ == 0) throw BadAlloc ();
-
- std::memcpy (b_, b.b_, s_);
- }
-/*
- Buffer&
- operator= (Buffer const&)
- {
- return *this;
- }
-*/
-
- // capacity
- //
-
- Size Buffer::
- capacity () const throw ()
- {
- return c_;
- }
-
- Boolean Buffer::
- capacity (Size c) throw (ZeroCapacity, Bounds, BadAlloc)
- {
- if (c == 0) throw ZeroCapacity ();
- if (s_ > c) throw Bounds ();
-
- Void* b (std::realloc (b_, c));
-
- if (b == 0) throw BadAlloc ();
-
- c_ = c;
-
- if (b == b_) return false;
-
- b_ = b;
-
- return true;
- }
-
- // size
- //
-
- Size Buffer::
- size () const throw ()
- {
- return s_;
- }
-
- void Buffer::
- size (Size s) throw (Bounds)
- {
- if (s > c_ || p_ > s) throw Bounds ();
-
- s_ = s;
- }
-
- // position
- //
-
- Index Buffer::
- position () const throw ()
- {
- return p_;
- }
-
- Void Buffer::
- position (Index p) throw (Bounds)
- {
- if (p > s_) throw Bounds ();
-
- p_ = p;
- }
-
-
- Char const* Buffer::
- data () const
- {
- return reinterpret_cast<Char const*> (b_);
- }
-
- Char* Buffer::
- data ()
- {
- return reinterpret_cast<Char*> (b_);
- }
- }
-}
diff --git a/libcult/cult/mm/buffer.hxx b/libcult/cult/mm/buffer.hxx
deleted file mode 100644
index d50c824..0000000
--- a/libcult/cult/mm/buffer.hxx
+++ /dev/null
@@ -1,80 +0,0 @@
-// file : cult/mm/buffer.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_BUFFER_HXX
-#define CULT_MM_BUFFER_HXX
-
-#include <cult/types/fundamental.hxx>
-
-#include <cult/mm/exception.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- //@@ why can't capacity be zero?
- //
-
- class Buffer
- {
- public:
- struct Bounds: virtual Exception {};
- struct ZeroCapacity: virtual Exception {};
-
- public:
- virtual
- ~Buffer ();
-
- Buffer (Size capacity, Size size = 0)
- throw (ZeroCapacity, Bounds, BadAlloc);
-
- Buffer (Void const*, Size size);
-
- Buffer (Buffer const& other);
-
- private:
- Buffer&
- operator= (Buffer const&);
-
- public:
- Size
- capacity () const throw ();
-
- // Returns true if the underlying buffer has been moved.
- //
- Boolean
- capacity (Size capacity) throw (ZeroCapacity, Bounds, BadAlloc);
-
- public:
- Size
- size () const throw ();
-
- Void
- size (Size size) throw (Bounds);
-
- public:
- Index
- position () const throw ();
-
- Void
- position (Index) throw (Bounds);
-
- public:
- Char const*
- data () const;
-
- Char*
- data ();
-
- private:
- Void* b_;
- Size c_, s_, p_;
- };
- }
-
- using MM::Buffer;
-}
-
-#endif // CULT_MM_BUFFER_HXX
diff --git a/libcult/cult/mm/counter.cxx b/libcult/cult/mm/counter.cxx
deleted file mode 100644
index 7d43e3c..0000000
--- a/libcult/cult/mm/counter.cxx
+++ /dev/null
@@ -1,14 +0,0 @@
-// file : cult/mm/counter.cxx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <cult/mm/counter.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- StaticPtr<Key<Counter> > counted;
- }
-}
diff --git a/libcult/cult/mm/counter.hxx b/libcult/cult/mm/counter.hxx
deleted file mode 100644
index 12e1e70..0000000
--- a/libcult/cult/mm/counter.hxx
+++ /dev/null
@@ -1,79 +0,0 @@
-// file : cult/mm/counter.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_COUNTER_HXX
-#define CULT_MM_COUNTER_HXX
-
-#ifdef CULT_THREADS
-
-// Multi-threaded version is architecture-specific.
-//
-#include <cult/mm/arch/counter.hxx>
-
-#else
-
-// Single-threaded version.
-//
-
-#include <cult/types/fundamental.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- class Counter: public NonCopyable
- {
- public:
- Counter ();
-
- // After failure assume the counter has its old value.
- //
- Void
- inc_ref ();
-
-
- // After failure assume the counter has its new value.
- //
- Boolean
- dec_ref ();
-
-
- Size
- count () const;
-
- private:
- Size value_;
- };
- }
-}
-
-#include <cult/mm/counter.ixx>
-
-#endif // CULT_THREADS
-
-
-#include <cult/mm/new.hxx>
-#include <cult/mm/static-ptr.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- extern StaticPtr<Key<Counter> > counted;
-
-
- // Non-member inc_ref. Especially useful for messing with `this'.
- //
- template <typename X>
- X*
- inc_ref (X* p)
- {
- locate (p, *counted)->inc_ref ();
- return p;
- }
- }
-}
-
-#endif // CULT_MM_COUNTER_HXX
diff --git a/libcult/cult/mm/counter.ixx b/libcult/cult/mm/counter.ixx
deleted file mode 100644
index f807552..0000000
--- a/libcult/cult/mm/counter.ixx
+++ /dev/null
@@ -1,38 +0,0 @@
-// file : cult/mm/counter.ixx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-namespace Cult
-{
- namespace MM
- {
- inline
- Counter::
- Counter ()
- : value_ (1)
- {
- }
-
- inline
- Void Counter::
- inc_ref ()
- {
- ++value_;
- }
-
- inline
- Boolean Counter::
- dec_ref ()
- {
- return --value_ == 0;
- }
-
- inline
- Size Counter::
- count () const
- {
- return value_;
- }
- }
-}
diff --git a/libcult/cult/mm/evptr.hxx b/libcult/cult/mm/evptr.hxx
deleted file mode 100644
index ed0bd93..0000000
--- a/libcult/cult/mm/evptr.hxx
+++ /dev/null
@@ -1,221 +0,0 @@
-// 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
diff --git a/libcult/cult/mm/exception.hxx b/libcult/cult/mm/exception.hxx
deleted file mode 100644
index 38b3412..0000000
--- a/libcult/cult/mm/exception.hxx
+++ /dev/null
@@ -1,31 +0,0 @@
-// file : cult/mm/exceptions.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_EXCEPTIONS_HXX
-#define CULT_MM_EXCEPTIONS_HXX
-
-#include <cult/eh/exception.hxx>
-
-#include <new> // std::bad_alloc
-
-namespace Cult
-{
- namespace MM
- {
- typedef std::bad_alloc StdBadAlloc;
-
- struct Exception: virtual EH::Exception {};
-
- struct BadAlloc: virtual Exception, StdBadAlloc {};
-
- //@@ who uses this?
- //
- struct SelfAssignment: virtual Exception {};
-
- struct NullPointer : virtual Exception {};
- }
-}
-
-#endif // CULT_MM_EXCEPTIONS_HXX
diff --git a/libcult/cult/mm/new.cxx b/libcult/cult/mm/new.cxx
deleted file mode 100644
index 2443f1f..0000000
--- a/libcult/cult/mm/new.cxx
+++ /dev/null
@@ -1,192 +0,0 @@
-// file : cult/mm/new.cxx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <cult/mm/new.hxx>
-#include <cult/mm/counter.hxx>
-
-#include <cstdlib> // std::malloc, std::free
-
-#include <cult/trace/stream.hxx>
-
-namespace
-{
- Cult::Trace::Stream&
- tout ()
- {
- static Cult::Trace::Stream o ("Cult::MM", 7);
- return o;
- }
-}
-
-namespace Cult
-{
- namespace MM
- {
- using Bits::Offset;
-
-
- namespace
- {
- Void*
- allocate (Size size, KeyList const& l) throw (StdBadAlloc)
- {
- Size zone_size (0);
-
- for (KeyList::Iterator i (l.begin ()); i != l.end (); ++i)
- {
- zone_size += (*i)->size ();
- }
-
- Size map_size ((l.size () + 1) * sizeof (Offset));
-
- //tout () << "allocate: size: " << size
- // << " map size: " << map_size
- // << " zone size: " << zone_size;
-
- Char* block (reinterpret_cast<Char*> (
- std::malloc (size + zone_size + map_size)));
-
- Char* base (block + zone_size + map_size);
-
- Offset* map (reinterpret_cast<Offset*> (base) - 1); // map bottom
- Char* zone (block + zone_size); // zone bottom
-
- //tout () << 9 << "allocate:" << '\n'
- // << " block : " << (Void*) block << '\n'
- // << " base : " << (Void*) base << '\n'
- // << " map : " << (Void*) zone << '\n'
- // << " zone : " << (Void*) block;
-
-
- // Initialize zone map and construct services.
- //
- for (KeyList::Iterator i (l.begin ()); i != l.end (); ++i)
- {
- KeyBase const& k (**i);
-
- zone -= k.size (); // now at the beginning of the block
-
- try
- {
- k.construct (zone);
- }
- catch (...)
- {
- std::free (block);
- throw StdBadAlloc ();
- }
-
- map->key = &k;
- map->offset = base - zone;
-
- --map;
- }
-
- // Last element.
- //
- map->key = 0;
- map->offset = 0;
-
- return base;
- }
-
- Void
- free (Void* p) throw ()
- {
- Char* base (reinterpret_cast<Char*> (p));
-
- Offset* map (reinterpret_cast<Offset*> (base) - 1); // Map bottom.
-
- Char* block (reinterpret_cast<Char*> (map));
-
- while (map->key != 0)
- {
- Char* zone (base - map->offset);
-
- block = zone; // Last zone is the begining of the block.
-
- map->key->destroy (zone);
-
- --map;
- }
-
- //tout () << 9 << "free:" << '\n'
- // << " block : " << (Void*) block;
-
- std::free (block);
- }
- }
- }
-}
-
-namespace Cult
-{
- namespace MM
- {
- namespace Bits
- {
-#ifdef CULT_THREADS
- __thread
- Block* first_ __attribute__ ((tls_model ("initial-exec"))) = 0;
-#else
- Block* first_ = 0;
-#endif
- }
- }
-}
-
-using namespace Cult;
-
-Void*
-operator new (Size s) throw (MM::StdBadAlloc)
-{
- return MM::allocate (s, *MM::counted);
-}
-
-Void*
-operator new (Size size, MM::KeyList const& list, MM::Bits::Block const& b)
- throw (MM::StdBadAlloc)
-{
- Void* p (MM::allocate (size, list));
-
- const_cast<MM::Bits::Block&> (b).set (p, size);
-
- return p;
-}
-
-Void
-operator delete (Void* p) throw ()
-{
- if (p) MM::free (p);
-}
-
-Void
-operator delete (Void* p, Size) throw ()
-{
- if (p) MM::free (p);
-}
-
-namespace Cult
-{
- namespace MM
- {
-
- Void* ServiceAwareObject::
- operator new (Size size, Bits::Block const& block)
- {
- Void* p (allocate (size, *MM::counted));
-
- const_cast<MM::Bits::Block&> (block).set (p, size);
-
- return p;
- }
-
- Void ServiceAwareObject::
- operator delete (Void* p, Size)
- {
- if (p) MM::free (p);
- }
- }
-}
diff --git a/libcult/cult/mm/new.hxx b/libcult/cult/mm/new.hxx
deleted file mode 100644
index 2b815b4..0000000
--- a/libcult/cult/mm/new.hxx
+++ /dev/null
@@ -1,297 +0,0 @@
-// file : cult/mm/new.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_NEW_HXX
-#define CULT_MM_NEW_HXX
-
-#include <cult/config.hxx>
-
-#include <cult/types/fundamental.hxx>
-
-#include <cult/mm/exception.hxx>
-
-#include <cult/meta/polymorphic-p.hxx>
-
-namespace Cult
-{
- namespace MM
- {
- class KeyBase
- {
- public:
- // Returned size should be a multiple of a "perfect" size,
- // sizeof (size_t) * 2.
- //
- virtual Size
- size () const = 0;
-
- virtual Void
- construct (Void* p) const = 0;
-
- virtual Void
- destroy (Void* p) const = 0;
-
- virtual
- ~KeyBase ()
- {
- }
- };
-
-
- template <typename X>
- class Key: public KeyBase, public NonCopyable
- {
- public:
- Key ()
- {
- }
-
- virtual Size
- size () const
- {
- //@@ I can do this transparently in allocate().
- //
- Size align (sizeof (Size) * 2);
- Size size (sizeof (X));
-
- return align * (size / align + ((size % align) ? 1 : 0));
- }
-
- virtual Void
- construct (Void* p) const
- {
- new (p) X;
- }
-
- virtual Void
- destroy (Void* p) const
- {
- reinterpret_cast<X*> (p)->~X ();
- }
- };
-
-
- struct Absent : virtual Exception {};
-
-
- namespace Bits
- {
- Void*
- locate (Void const* p, KeyBase const& k) throw (Absent);
-
- template <typename X, Boolean poly = Meta::polymorphic_p<X>::r>
- struct Locator;
-
- template <typename X>
- struct Locator<X, false>
- {
- static Void*
- locate (X* p, KeyBase const& k) throw (Absent)
- {
- return Bits::locate (p, k);
- }
- };
-
- template <typename X>
- struct Locator<X, true>
- {
- static Void*
- locate (X* p, KeyBase const& k) throw (Absent)
- {
- return Bits::locate (dynamic_cast<Void const*> (p), k);
- }
- };
-
- // Note that this structure has a "perfect" size: sizeof (size_t) * 2.
- // If its size is added to the properly-aligned pointer the result will
- // still be a properly-aligned pointer.
- //
- struct Offset //@@ better name would be OffsetMap
- {
- KeyBase const* key;
- Size offset;
- };
- }
-
-
- template <typename X, typename Y>
- inline
- Y*
- locate (X* p, Key<Y> const& k) throw (Absent)
- {
- return p ? reinterpret_cast<Y*> (Bits::Locator<X>::locate (p, k)) : 0;
- }
-
- class KeyList
- {
- public:
- KeyList ()
- : size_ (0)
- {
- }
-
- KeyList (KeyBase const& k)
- : size_ (1)
- {
- keys_[0] = &k;
- }
-
- friend KeyList
- operator| (KeyList const& list, KeyBase const& key);
-
- public:
- typedef KeyBase const* const* Iterator;
-
- Iterator
- begin () const
- {
- return keys_;
- }
-
- Iterator
- end () const
- {
- return &(keys_[size_]);
- }
-
- Size
- size () const
- {
- return size_;
- }
-
- private:
- KeyBase const* keys_[8];
- Size size_;
- };
-
- inline KeyList
- operator| (KeyList const& list, KeyBase const& key)
- {
- //@@ Need to throw on overflow.
- //
- KeyList r (list);
- r.keys_[r.size_++] = &key;
- return r;
- }
-
- inline KeyList
- operator| (KeyBase const& a, KeyBase const& b)
- {
- return KeyList (a) | b;
- }
- }
-}
-
-namespace Cult
-{
- namespace MM
- {
- namespace Bits
- {
- class Block;
-
-#ifdef CULT_THREADS
- extern __thread
- Block* first_ __attribute__ ((tls_model ("initial-exec")));
-#else
- extern
- Block* first_;
-#endif
-
- class Block
- {
- public:
- Block ()
- {
- }
-
- ~Block ()
- {
- //@@ assert (first_ == this);
- first_ = next_;
- }
-
- Void
- set (Void* p, Size size)
- {
- p_ = reinterpret_cast<Char*> (p);
- size_ = size;
-
- next_ = first_;
- first_ = this;
- }
-
- public:
- static Void*
- locate (Void const* p)
- {
- return locate (p, first_);
- }
-
- private:
- static Void*
- locate (Void const* p, Block* b)
- {
- if (b)
- {
- if (p >= b->p_ && p < b->p_ + b->size_) return b->p_;
- else return locate (p, b->next_);
- }
-
- return 0;
- }
-
- private:
- Char* p_;
- Size size_;
-
- Block* next_;
- };
- }
- }
-}
-
-Cult::Void*
-operator new (Cult::Size) throw (Cult::MM::StdBadAlloc);
-
-Cult::Void*
-operator new (Cult::Size,
- Cult::MM::KeyList const&,
- Cult::MM::Bits::Block const& = Cult::MM::Bits::Block ())
- throw (Cult::MM::StdBadAlloc);
-
-//@@ Need a special operator new that just allocates memory (to use in
-// static_ptr for instance).
-//
-
-Cult::Void
-operator delete (Cult::Void*) throw ();
-
-Cult::Void
-operator delete (Cult::Void*, Cult::Size) throw ();
-
-
-namespace Cult
-{
- namespace MM
- {
- // Inherit from this class if you plan to access service objects
- // from a ctor.
- //
- struct ServiceAwareObject
- {
- static Void*
- operator new (Size s, Bits::Block const& b = Bits::Block ());
-
- static Void
- operator delete (Void* p, Size s);
- };
- }
-}
-
-#include <cult/mm/new.ixx>
-
-#endif // CULT_MM_NEW_HXX
diff --git a/libcult/cult/mm/new.ixx b/libcult/cult/mm/new.ixx
deleted file mode 100644
index c3287fb..0000000
--- a/libcult/cult/mm/new.ixx
+++ /dev/null
@@ -1,36 +0,0 @@
-// file : cult/mm/new.ixx
-// author : Boris Kolpackov <boris@kolpackov.net>
-// copyright : Copyright (c) 2005-2010 Boris Kolpackov
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-namespace Cult
-{
- namespace MM
- {
- namespace Bits
- {
- inline
- Void*
- locate (Void const* p, KeyBase const& k) throw (Absent)
- {
- if (Void* bp = Block::locate (p)) p = bp;
-
- Char* base (reinterpret_cast<Char*> (const_cast<Void*> (p)));
-
- Offset* map (reinterpret_cast<Offset*> (base) - 1); // Map bottom.
-
- while (map->key != 0)
- {
- if (map->key == &k)
- {
- return base - map->offset;
- }
-
- --map;
- }
-
- throw Absent ();
- }
- }
- }
-}
diff --git a/libcult/cult/mm/shptr.hxx b/libcult/cult/mm/shptr.hxx
deleted file mode 100644
index 6630b1c..0000000
--- a/libcult/cult/mm/shptr.hxx
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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
diff --git a/libcult/cult/mm/static-ptr.hxx b/libcult/cult/mm/static-ptr.hxx
deleted file mode 100644
index d3dffbd..0000000
--- a/libcult/cult/mm/static-ptr.hxx
+++ /dev/null
@@ -1,75 +0,0 @@
-// file : cult/mm/static-ptr.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_STATIC_PTR_HXX
-#define CULT_MM_STATIC_PTR_HXX
-
-#include <cult/types/fundamental.hxx>
-
-#include <cult/mm/new.hxx> // operator new
-
-namespace Cult
-{
- namespace MM
- {
- namespace Bits
- {
- struct Default {};
- }
-
- template <typename X, typename Id = Bits::Default>
- class StaticPtr: public NonCopyable
- {
- public:
- X&
- operator* () const
- {
- return instance ();
- }
-
- X*
- operator-> () const
- {
- return &instance ();
- }
-
- public:
- StaticPtr ()
- {
- if (i_ == 0) i_ = instance_ ();
- }
-
- ~StaticPtr ()
- {
- // Note that we don't delete the object in order to avoid
- // destruction order problem.
- //
- }
-
- private:
- static X&
- instance ()
- {
- if (i_ == 0) i_ = instance_ ();
-
- return *i_;
- }
-
- static X*
- instance_ ()
- {
- static X* i = new (KeyList ()) X;
- return i;
- }
-
- static X* i_;
- };
-
- template <typename X, typename Id>
- X* StaticPtr<X, Id>::i_ = 0;
- }
-}
-
-#endif // CULT_MM_STATIC_PTR_HXX