aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-08-18 20:02:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-08-18 20:02:11 +0200
commit2636e266dc7a048e52b40b668c460c2793e897c4 (patch)
tree9717f573d9733b8cfa09a15ee44ed7768c427d7b
parentdce5d0658e67ced4d5fa64f98f598b86917927a7 (diff)
Move shared_ptr to the details namespace
-rw-r--r--odb/details/meta/answer.hxx28
-rw-r--r--odb/details/meta/class-p.hxx31
-rw-r--r--odb/details/meta/polymorphic-p.hxx54
-rw-r--r--odb/details/meta/remove-c.hxx30
-rw-r--r--odb/details/meta/remove-cv.hxx27
-rw-r--r--odb/details/meta/remove-p.hxx30
-rw-r--r--odb/details/meta/remove-v.hxx30
-rw-r--r--odb/details/shared-ptr.hxx162
-rw-r--r--odb/details/shared-ptr/base.cxx (renamed from odb/shared-ptr/base.cxx)53
-rw-r--r--odb/details/shared-ptr/base.hxx108
-rw-r--r--odb/details/shared-ptr/base.ixx85
-rw-r--r--odb/details/shared-ptr/base.txx206
-rw-r--r--odb/forward.hxx3
-rw-r--r--odb/makefile3
-rw-r--r--odb/meta/answer.hxx25
-rw-r--r--odb/meta/class-p.hxx28
-rw-r--r--odb/meta/polymorphic-p.hxx51
-rw-r--r--odb/meta/remove-c.hxx27
-rw-r--r--odb/meta/remove-cv.hxx24
-rw-r--r--odb/meta/remove-p.hxx27
-rw-r--r--odb/meta/remove-v.hxx27
-rw-r--r--odb/pointer-traits.hxx43
-rw-r--r--odb/result.hxx9
-rw-r--r--odb/shared-ptr.hxx159
-rw-r--r--odb/shared-ptr/base.hxx102
-rw-r--r--odb/shared-ptr/base.ixx82
-rw-r--r--odb/shared-ptr/base.txx200
-rw-r--r--odb/traits.hxx1
28 files changed, 822 insertions, 833 deletions
diff --git a/odb/details/meta/answer.hxx b/odb/details/meta/answer.hxx
new file mode 100644
index 0000000..31387a9
--- /dev/null
+++ b/odb/details/meta/answer.hxx
@@ -0,0 +1,28 @@
+// file : odb/details/meta/answer.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_META_ANSWER_HXX
+#define ODB_DETAILS_META_ANSWER_HXX
+
+namespace odb
+{
+ namespace details
+ {
+ namespace meta
+ {
+ struct yes
+ {
+ char filling;
+ };
+
+ struct no
+ {
+ char filling[2];
+ };
+ }
+ }
+}
+
+#endif // ODB_DETAILS_META_ANSWER_HXX
diff --git a/odb/details/meta/class-p.hxx b/odb/details/meta/class-p.hxx
new file mode 100644
index 0000000..c680d8e
--- /dev/null
+++ b/odb/details/meta/class-p.hxx
@@ -0,0 +1,31 @@
+// file : odb/details/meta/class-p.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_META_CLASS_HXX
+#define ODB_DETAILS_META_CLASS_HXX
+
+#include <odb/details/meta/answer.hxx>
+
+namespace odb
+{
+ namespace details
+ {
+ namespace meta
+ {
+ // g++ cannot have these inside class_p.
+ //
+ template <typename Y> no class_p_test (...);
+ template <typename Y> yes class_p_test (void (Y::*) ());
+
+ template <typename X>
+ struct class_p
+ {
+ static bool const r = sizeof (class_p_test<X> (0)) == sizeof (yes);
+ };
+ }
+ }
+}
+
+#endif // ODB_DETAILS_META_CLASS_HXX
diff --git a/odb/details/meta/polymorphic-p.hxx b/odb/details/meta/polymorphic-p.hxx
new file mode 100644
index 0000000..6e95144
--- /dev/null
+++ b/odb/details/meta/polymorphic-p.hxx
@@ -0,0 +1,54 @@
+// file : odb/details/meta/polymorphic-p.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_META_POLYMORPHIC_HXX
+#define ODB_DETAILS_META_POLYMORPHIC_HXX
+
+#include <odb/details/meta/class-p.hxx>
+#include <odb/details/meta/remove-cv.hxx>
+
+namespace odb
+{
+ namespace details
+ {
+ namespace meta
+ {
+ template <typename CVX>
+ struct polymorphic_p
+ {
+ typedef typename remove_cv<CVX>::r X;
+
+ template <typename Y, bool C>
+ struct impl
+ {
+ static const bool r = false;
+ };
+
+ template <typename Y>
+ struct impl<Y, true>
+ {
+ struct t1: Y
+ {
+ t1 ();
+ };
+
+ struct t2: Y
+ {
+ t2 ();
+
+ virtual
+ ~t2 () throw ();
+ };
+
+ static const bool r = sizeof (t1) == sizeof (t2);
+ };
+
+ static const bool r = impl<X, class_p<X>::r>::r;
+ };
+ }
+ }
+}
+
+#endif // ODB_DETAILS_META_POLYMORPHIC_HXX
diff --git a/odb/details/meta/remove-c.hxx b/odb/details/meta/remove-c.hxx
new file mode 100644
index 0000000..9d8e0b5
--- /dev/null
+++ b/odb/details/meta/remove-c.hxx
@@ -0,0 +1,30 @@
+// file : odb/details/meta/remove-c.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_META_REMOVE_C_HXX
+#define ODB_DETAILS_META_REMOVE_C_HXX
+
+namespace odb
+{
+ namespace details
+ {
+ namespace meta
+ {
+ template <typename X>
+ struct remove_c
+ {
+ typedef X r;
+ };
+
+ template <typename X>
+ struct remove_c<X const>
+ {
+ typedef X r;
+ };
+ }
+ }
+}
+
+#endif // ODB_DETAILS_META_REMOVE_C_HXX
diff --git a/odb/details/meta/remove-cv.hxx b/odb/details/meta/remove-cv.hxx
new file mode 100644
index 0000000..958fc08
--- /dev/null
+++ b/odb/details/meta/remove-cv.hxx
@@ -0,0 +1,27 @@
+// file : odb/details/meta/remove-cv.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_META_REMOVE_CV_HXX
+#define ODB_DETAILS_META_REMOVE_CV_HXX
+
+#include <odb/details/meta/remove-c.hxx>
+#include <odb/details/meta/remove-v.hxx>
+
+namespace odb
+{
+ namespace details
+ {
+ namespace meta
+ {
+ template <typename X>
+ struct remove_cv
+ {
+ typedef typename remove_v<typename remove_c<X>::r>::r r;
+ };
+ }
+ }
+}
+
+#endif // ODB_DETAILS_META_REMOVE_CV_HXX
diff --git a/odb/details/meta/remove-p.hxx b/odb/details/meta/remove-p.hxx
new file mode 100644
index 0000000..c8f6d92
--- /dev/null
+++ b/odb/details/meta/remove-p.hxx
@@ -0,0 +1,30 @@
+// file : odb/details/meta/remove-p.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_META_REMOVE_P_HXX
+#define ODB_DETAILS_META_REMOVE_P_HXX
+
+namespace odb
+{
+ namespace details
+ {
+ namespace meta
+ {
+ template <typename X>
+ struct remove_p
+ {
+ typedef X r;
+ };
+
+ template <typename X>
+ struct remove_p<X*>
+ {
+ typedef X r;
+ };
+ }
+ }
+}
+
+#endif // ODB_DETAILS_META_REMOVE_P_HXX
diff --git a/odb/details/meta/remove-v.hxx b/odb/details/meta/remove-v.hxx
new file mode 100644
index 0000000..c91b7e4
--- /dev/null
+++ b/odb/details/meta/remove-v.hxx
@@ -0,0 +1,30 @@
+// file : odb/details/meta/remove-v.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_META_REMOVE_V_HXX
+#define ODB_DETAILS_META_REMOVE_V_HXX
+
+namespace odb
+{
+ namespace details
+ {
+ namespace meta
+ {
+ template <typename X>
+ struct remove_v
+ {
+ typedef X r;
+ };
+
+ template <typename X>
+ struct remove_v<X volatile>
+ {
+ typedef X r;
+ };
+ }
+ }
+}
+
+#endif // ODB_DETAILS_META_REMOVE_V_HXX
diff --git a/odb/details/shared-ptr.hxx b/odb/details/shared-ptr.hxx
new file mode 100644
index 0000000..67b67df
--- /dev/null
+++ b/odb/details/shared-ptr.hxx
@@ -0,0 +1,162 @@
+// file : odb/details/shared-ptr.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_SHARED_PTR_HXX
+#define ODB_DETAILS_SHARED_PTR_HXX
+
+#include <odb/details/shared-ptr/base.hxx>
+
+namespace odb
+{
+ namespace details
+ {
+ template <typename X>
+ class shared_ptr: bits::counter_ops<typename bits::counter_type<X>::r, X>
+ {
+ typedef bits::counter_ops<typename bits::counter_type<X>::r, X> base;
+
+ public:
+ ~shared_ptr ()
+ {
+ if (x_ != 0)
+ base::dec (x_);
+ }
+
+ explicit
+ shared_ptr (X* x = 0)
+ : base (x), x_ (x)
+ {
+ }
+
+ shared_ptr (const shared_ptr& x)
+ : base (x), x_ (x.x_)
+ {
+ if (x_ != 0)
+ base::inc (x_);
+ }
+
+ template <typename Y>
+ shared_ptr (const shared_ptr<Y>& x)
+ : base (x), x_ (x.x_)
+ {
+ if (x_ != 0)
+ base::inc (x_);
+ }
+
+ shared_ptr&
+ operator= (const shared_ptr& x)
+ {
+ if (x_ != x.x_)
+ {
+ if (x_ != 0)
+ base::dec (x_);
+
+ static_cast<base&> (*this) = x;
+ x_ = x.x_;
+
+ if (x_ != 0)
+ base::inc (x_);
+ }
+
+ return *this;
+ }
+
+ template <typename Y>
+ shared_ptr&
+ operator= (const shared_ptr<Y>& x)
+ {
+ if (x_ != x.x_)
+ {
+ if (x_ != 0)
+ base::dec (x_);
+
+ static_cast<base&> (*this) = x;
+ x_ = x.x_;
+
+ if (x_ != 0)
+ base::inc (x_);
+ }
+
+ return *this;
+ }
+
+ public:
+ X*
+ operator-> () const
+ {
+ return x_;
+ }
+
+ X&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ // Conversion to bool.
+ //
+ typedef void (shared_ptr::*boolean_convertible)();
+ void true_value () {};
+
+ operator boolean_convertible () const
+ {
+ return x_ ? &shared_ptr<X>::true_value : 0;
+ }
+
+ public:
+ X*
+ get () const
+ {
+ return x_;
+ }
+
+ X*
+ release ()
+ {
+ X* r (x_);
+ x_ = 0;
+ return r;
+ }
+
+ void
+ reset (X* x)
+ {
+ if (x_ != 0)
+ base::dec (x_);
+
+ base::reset (x);
+ x_ = x;
+ }
+
+ std::size_t
+ count () const
+ {
+ return x_ != 0 ? base::count (x_) : 0;
+ }
+
+ private:
+ template <typename>
+ friend class shared_ptr;
+
+ X* x_;
+ };
+
+ template <typename X, typename Y>
+ inline bool
+ operator== (const shared_ptr<X>& x, const shared_ptr<Y>& y)
+ {
+ return x.get () == y.get ();
+ }
+
+ template <typename X, typename Y>
+ inline bool
+ operator!= (const shared_ptr<X>& x, const shared_ptr<Y>& y)
+ {
+ return x.get () != y.get ();
+ }
+ }
+}
+
+#endif // ODB_DETAILS_SHARED_PTR_HXX
diff --git a/odb/shared-ptr/base.cxx b/odb/details/shared-ptr/base.cxx
index 197d20b..2c220cb 100644
--- a/odb/shared-ptr/base.cxx
+++ b/odb/details/shared-ptr/base.cxx
@@ -1,48 +1,45 @@
-// file : odb/shared-ptr/base.cxx
+// file : odb/details/shared-ptr/base.cxx
// author : Boris Kolpackov <boris@codesynthesis.com>
// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
-#include <odb/shared-ptr/base.hxx>
+#include <odb/details/shared-ptr/base.hxx>
using std::size_t;
-//
-//
-odb::share shared = odb::share (1);
-odb::share exclusive = odb::share (2);
-
-//
-//
namespace odb
{
- const char* not_shared::
- what () const throw ()
- {
- return "object is not shared";
- }
-
- bool shared_base::
- _dec_ref_callback ()
+ namespace details
{
- bool r (--counter_ == 0);
+ share shared = share (1);
+ share exclusive = share (2);
- if (r)
+ const char* not_shared::
+ what () const throw ()
{
- callback_->zero_counter (callback_->arg);
- r = (counter_ == 0);
+ return "object is not shared";
}
- return r;
+ bool shared_base::
+ _dec_ref_callback ()
+ {
+ bool r (--counter_ == 0);
+
+ if (r)
+ {
+ callback_->zero_counter (callback_->arg);
+ r = (counter_ == 0);
+ }
+
+ return r;
+ }
}
}
-//
-//
void*
-operator new (size_t n, odb::share s) throw (std::bad_alloc)
+operator new (size_t n, odb::details::share s) throw (std::bad_alloc)
{
- if (s == shared)
+ if (s == odb::details::shared)
{
// Here we need to make sure we don't break the alignment of the
// returned block. For that we need to know the maximum alignment
@@ -60,13 +57,13 @@ operator new (size_t n, odb::share s) throw (std::bad_alloc)
}
void
-operator delete (void* p, odb::share s) throw ()
+operator delete (void* p, odb::details::share s) throw ()
{
// This version of operator delete is only called when the c-tor
// fails. In this case there is no object and we can just free the
// memory.
//
- if (s == shared)
+ if (s == odb::details::shared)
{
size_t* sp = static_cast<size_t*> (p);
sp -= 2;
diff --git a/odb/details/shared-ptr/base.hxx b/odb/details/shared-ptr/base.hxx
new file mode 100644
index 0000000..4fbbc0b
--- /dev/null
+++ b/odb/details/shared-ptr/base.hxx
@@ -0,0 +1,108 @@
+// file : odb/details/shared-ptr/base.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_DETAILS_SHARED_PTR_BASE_HXX
+#define ODB_DETAILS_SHARED_PTR_BASE_HXX
+
+#include <new>
+#include <cstddef> // std::size_t
+
+#include <odb/exception.hxx>
+
+namespace odb
+{
+ namespace details
+ {
+ struct share
+ {
+ explicit
+ share (char id);
+
+ bool
+ operator== (share) const;
+
+ private:
+ char id_;
+ };
+
+ extern share shared;
+ extern share exclusive;
+ }
+}
+
+void*
+operator new (std::size_t, odb::details::share) throw (std::bad_alloc);
+
+void
+operator delete (void*, odb::details::share) throw ();
+
+namespace odb
+{
+ namespace details
+ {
+ struct not_shared: exception
+ {
+ virtual const char*
+ what () const throw ();
+ };
+
+ struct shared_base
+ {
+ shared_base ();
+ shared_base (const shared_base&);
+ shared_base&
+ operator= (const shared_base&);
+
+ void
+ _inc_ref ();
+
+ bool
+ _dec_ref ();
+
+ std::size_t
+ _ref_count () const;
+
+ void*
+ operator new (std::size_t, share) throw (std::bad_alloc);
+
+ void
+ operator delete (void*, share) throw ();
+
+ void
+ operator delete (void*) throw ();
+
+ struct refcount_callback
+ {
+ void* arg;
+ void (*zero_counter) (void*);
+ };
+
+ private:
+ bool
+ _dec_ref_callback ();
+
+ protected:
+ std::size_t counter_;
+ refcount_callback* callback_;
+ };
+
+ template <typename X>
+ inline X*
+ inc_ref (X*);
+
+ template <typename X>
+ inline void
+ dec_ref (X*);
+
+ template <typename X>
+ inline std::size_t
+ ref_count (const X*);
+ }
+}
+
+#include <odb/details/shared-ptr/base.ixx>
+#include <odb/details/shared-ptr/base.txx>
+
+#endif // ODB_DETAILS_SHARED_PTR_BASE_HXX
diff --git a/odb/details/shared-ptr/base.ixx b/odb/details/shared-ptr/base.ixx
new file mode 100644
index 0000000..cd8e2ce
--- /dev/null
+++ b/odb/details/shared-ptr/base.ixx
@@ -0,0 +1,85 @@
+// file : odb/details/shared-ptr/base.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+namespace odb
+{
+ namespace details
+ {
+ // share
+ //
+
+ inline share::
+ share (char id)
+ : id_ (id)
+ {
+ }
+
+ inline bool share::
+ operator== (share x) const
+ {
+ return id_ == x.id_;
+ }
+
+ // shared_base
+ //
+
+ inline shared_base::
+ shared_base ()
+ : counter_ (1), callback_ (0)
+ {
+ }
+
+ inline shared_base::
+ shared_base (const shared_base&)
+ : counter_ (1), callback_ (0)
+ {
+ }
+
+ inline shared_base& shared_base::
+ operator= (const shared_base&)
+ {
+ return *this;
+ }
+
+ inline void shared_base::
+ _inc_ref ()
+ {
+ counter_++;
+ }
+
+ inline bool shared_base::
+ _dec_ref ()
+ {
+ if (callback_ == 0)
+ return --counter_ == 0;
+ else
+ return _dec_ref_callback ();
+ }
+
+ inline std::size_t shared_base::
+ _ref_count () const
+ {
+ return counter_;
+ }
+
+ inline void* shared_base::
+ operator new (std::size_t n, share) throw (std::bad_alloc)
+ {
+ return ::operator new (n);
+ }
+
+ inline void shared_base::
+ operator delete (void* p, share) throw ()
+ {
+ ::operator delete (p);
+ }
+
+ inline void shared_base::
+ operator delete (void* p) throw ()
+ {
+ ::operator delete (p);
+ }
+ }
+}
diff --git a/odb/details/shared-ptr/base.txx b/odb/details/shared-ptr/base.txx
new file mode 100644
index 0000000..fc30fdf
--- /dev/null
+++ b/odb/details/shared-ptr/base.txx
@@ -0,0 +1,206 @@
+// file : odb/details/shared-ptr/base.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#include <odb/details/meta/answer.hxx>
+#include <odb/details/meta/polymorphic-p.hxx>
+
+namespace odb
+{
+ namespace details
+ {
+ namespace bits
+ {
+ // Support for locating the counter in the memory block.
+ //
+ template <typename X, bool poly = meta::polymorphic_p<X>::r>
+ struct locator;
+
+ template <typename X>
+ struct locator<X, false>
+ {
+ static std::size_t*
+ counter (X* x)
+ {
+ std::size_t* p (reinterpret_cast<std::size_t*> (x));
+
+ if (*(--p) != 0xDEADBEEF)
+ throw not_shared ();
+
+ return --p;
+ }
+ };
+
+ template <typename X>
+ struct locator<X, true>
+ {
+ static std::size_t*
+ counter (X* x)
+ {
+ std::size_t* p (
+ static_cast<std::size_t*> (
+ dynamic_cast<void*> (x)));
+
+ if (*(--p) != 0xDEADBEEF)
+ throw not_shared ();
+
+ return --p;
+ }
+ };
+
+ template <typename X>
+ std::size_t*
+ counter (const X* p)
+ {
+ return bits::locator<X>::counter (const_cast<X*> (p));
+ }
+
+ // Counter type and operations.
+ //
+ meta::no test (...);
+ meta::yes test (shared_base*);
+
+ template <typename X,
+ std::size_t A = sizeof (bits::test (reinterpret_cast<X*> (0)))>
+ struct counter_type;
+
+ template <typename X>
+ struct counter_type<X, sizeof (meta::no)>
+ {
+ typedef X r;
+ };
+
+ template <typename X>
+ struct counter_type<X, sizeof (meta::yes)>
+ {
+ typedef shared_base r;
+ };
+
+ template <typename X, typename Y>
+ struct counter_ops;
+
+ template <typename X>
+ struct counter_ops<X, X>
+ {
+ counter_ops (const X* p) : counter_ (p ? bits::counter (p) : 0) {}
+ counter_ops (const counter_ops& x) : counter_ (x.counter_) {}
+
+ template <typename Z>
+ counter_ops (const counter_ops<Z, Z>& x) : counter_ (x.counter_) {}
+
+ counter_ops&
+ operator= (const counter_ops& x)
+ {
+ counter_ = x.counter_;
+ return *this;
+ }
+
+ template <typename Z>
+ counter_ops&
+ operator= (const counter_ops<Z, Z>& x)
+ {
+ counter_ = x.counter_;
+ return *this;
+ }
+
+ void
+ reset (const X* p)
+ {
+ counter_ = p ? bits::counter (p) : 0;
+ }
+
+ void
+ inc (X*)
+ {
+ (*counter_)++;
+ }
+
+ void
+ dec (X* p)
+ {
+ if (--(*counter_) == 0)
+ {
+ p->~X ();
+
+ // Counter is the top of the memory block.
+ //
+ operator delete (counter_);
+ }
+ }
+
+ std::size_t
+ count (const X*) const
+ {
+ return *counter_;
+ }
+
+ std::size_t* counter_;
+ };
+
+ template <typename Y>
+ struct counter_ops<shared_base, Y>
+ {
+ counter_ops (const Y*) {}
+ counter_ops (const counter_ops&) {}
+
+ template <typename Z>
+ counter_ops (const counter_ops<shared_base, Z>&) {}
+
+ counter_ops&
+ operator= (const counter_ops&)
+ {
+ return *this;
+ }
+
+ template <typename Z>
+ counter_ops&
+ operator= (const counter_ops<shared_base, Z>&)
+ {
+ return *this;
+ }
+
+ void
+ reset (const Y*) {}
+
+ void
+ inc (shared_base* p) {p->_inc_ref ();}
+
+ void
+ dec (Y* p)
+ {
+ if (static_cast<shared_base*> (p)->_dec_ref ())
+ delete p;
+ }
+
+ std::size_t
+ count (const shared_base* p) const {return p->_ref_count ();}
+ };
+ }
+
+ template <typename X>
+ inline X*
+ inc_ref (X* p)
+ {
+ bits::counter_ops<typename bits::counter_type<X>::r, X> c (p);
+ c.inc (p);
+ return p;
+ }
+
+ template <typename X>
+ inline void
+ dec_ref (X* p)
+ {
+ bits::counter_ops<typename bits::counter_type<X>::r, X> c (p);
+ c.dec (p);
+ }
+
+ template <typename X>
+ inline std::size_t
+ ref_count (const X* p)
+ {
+ bits::counter_ops<typename bits::counter_type<X>::r, X> c (p);
+ return c.count (p);
+ }
+ }
+}
diff --git a/odb/forward.hxx b/odb/forward.hxx
index 8e91407..695cef6 100644
--- a/odb/forward.hxx
+++ b/odb/forward.hxx
@@ -11,9 +11,6 @@ namespace odb
class database;
class transaction;
- template <typename T>
- class shared_ptr;
-
class access
{
public:
diff --git a/odb/makefile b/odb/makefile
index 2038b01..9b6c094 100644
--- a/odb/makefile
+++ b/odb/makefile
@@ -6,13 +6,12 @@
include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
cxx_tun := \
-shared-ptr/base.cxx \
exception.cxx \
exceptions.cxx \
database.cxx \
transaction.cxx
-cxx_tun += details/buffer.cxx
+cxx_tun += details/buffer.cxx details/shared-ptr/base.cxx
# POSIX-based implementation details.
#
diff --git a/odb/meta/answer.hxx b/odb/meta/answer.hxx
deleted file mode 100644
index 80a25e0..0000000
--- a/odb/meta/answer.hxx
+++ /dev/null
@@ -1,25 +0,0 @@
-// file : odb/meta/answer.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_META_ANSWER_HXX
-#define ODB_META_ANSWER_HXX
-
-namespace odb
-{
- namespace meta
- {
- struct yes
- {
- char filling;
- };
-
- struct no
- {
- char filling[2];
- };
- }
-}
-
-#endif // ODB_META_ANSWER_HXX
diff --git a/odb/meta/class-p.hxx b/odb/meta/class-p.hxx
deleted file mode 100644
index e3d15c9..0000000
--- a/odb/meta/class-p.hxx
+++ /dev/null
@@ -1,28 +0,0 @@
-// file : odb/meta/class-p.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_META_CLASS_HXX
-#define ODB_META_CLASS_HXX
-
-#include <odb/meta/answer.hxx>
-
-namespace odb
-{
- namespace meta
- {
- // g++ cannot have these inside class_p.
- //
- template <typename Y> no class_p_test (...);
- template <typename Y> yes class_p_test (void (Y::*) ());
-
- template <typename X>
- struct class_p
- {
- static bool const r = sizeof (class_p_test<X> (0)) == sizeof (yes);
- };
- }
-}
-
-#endif // ODB_META_CLASS_HXX
diff --git a/odb/meta/polymorphic-p.hxx b/odb/meta/polymorphic-p.hxx
deleted file mode 100644
index 571ef52..0000000
--- a/odb/meta/polymorphic-p.hxx
+++ /dev/null
@@ -1,51 +0,0 @@
-// file : odb/meta/polymorphic-p.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_META_POLYMORPHIC_HXX
-#define ODB_META_POLYMORPHIC_HXX
-
-#include <odb/meta/class-p.hxx>
-#include <odb/meta/remove-cv.hxx>
-
-namespace odb
-{
- namespace meta
- {
- template <typename CVX>
- struct polymorphic_p
- {
- typedef typename remove_cv<CVX>::r X;
-
- template <typename Y, bool C>
- struct impl
- {
- static const bool r = false;
- };
-
- template <typename Y>
- struct impl<Y, true>
- {
- struct t1: Y
- {
- t1 ();
- };
-
- struct t2: Y
- {
- t2 ();
-
- virtual
- ~t2 () throw ();
- };
-
- static const bool r = sizeof (t1) == sizeof (t2);
- };
-
- static const bool r = impl<X, class_p<X>::r>::r;
- };
- }
-}
-
-#endif // ODB_META_POLYMORPHIC_HXX
diff --git a/odb/meta/remove-c.hxx b/odb/meta/remove-c.hxx
deleted file mode 100644
index db724b3..0000000
--- a/odb/meta/remove-c.hxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// file : odb/meta/remove-c.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_META_REMOVE_C_HXX
-#define ODB_META_REMOVE_C_HXX
-
-namespace odb
-{
- namespace meta
- {
- template <typename X>
- struct remove_c
- {
- typedef X r;
- };
-
- template <typename X>
- struct remove_c<X const>
- {
- typedef X r;
- };
- }
-}
-
-#endif // ODB_META_REMOVE_C_HXX
diff --git a/odb/meta/remove-cv.hxx b/odb/meta/remove-cv.hxx
deleted file mode 100644
index 0805a9d..0000000
--- a/odb/meta/remove-cv.hxx
+++ /dev/null
@@ -1,24 +0,0 @@
-// file : odb/meta/remove-cv.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_META_REMOVE_CV_HXX
-#define ODB_META_REMOVE_CV_HXX
-
-#include <odb/meta/remove-c.hxx>
-#include <odb/meta/remove-v.hxx>
-
-namespace odb
-{
- namespace meta
- {
- template <typename X>
- struct remove_cv
- {
- typedef typename remove_v<typename remove_c<X>::r>::r r;
- };
- }
-}
-
-#endif // ODB_META_REMOVE_CV_HXX
diff --git a/odb/meta/remove-p.hxx b/odb/meta/remove-p.hxx
deleted file mode 100644
index 053c860..0000000
--- a/odb/meta/remove-p.hxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// file : odb/meta/remove-p.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_META_REMOVE_P_HXX
-#define ODB_META_REMOVE_P_HXX
-
-namespace odb
-{
- namespace meta
- {
- template <typename X>
- struct remove_p
- {
- typedef X r;
- };
-
- template <typename X>
- struct remove_p<X*>
- {
- typedef X r;
- };
- }
-}
-
-#endif // ODB_META_REMOVE_P_HXX
diff --git a/odb/meta/remove-v.hxx b/odb/meta/remove-v.hxx
deleted file mode 100644
index 9e37a6c..0000000
--- a/odb/meta/remove-v.hxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// file : odb/meta/remove-v.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_META_REMOVE_V_HXX
-#define ODB_META_REMOVE_V_HXX
-
-namespace odb
-{
- namespace meta
- {
- template <typename X>
- struct remove_v
- {
- typedef X r;
- };
-
- template <typename X>
- struct remove_v<X volatile>
- {
- typedef X r;
- };
- }
-}
-
-#endif // ODB_META_REMOVE_V_HXX
diff --git a/odb/pointer-traits.hxx b/odb/pointer-traits.hxx
index 26f8b90..23ec1f8 100644
--- a/odb/pointer-traits.hxx
+++ b/odb/pointer-traits.hxx
@@ -9,8 +9,6 @@
#include <new> // operators new/delete
#include <cstddef> // std::size_t
-#include <odb/shared-ptr.hxx>
-
namespace odb
{
template <typename P>
@@ -157,47 +155,6 @@ namespace odb
operator delete (p);
}
};
-
- // Specialization for odb::shared_ptr.
- //
- template <typename T>
- class pointer_traits< shared_ptr<T> >
- {
- public:
- typedef T type;
- typedef odb::shared_ptr<T> pointer;
- typedef nop_guard<pointer> guard;
-
- static type*
- get_ptr (const pointer& p)
- {
- return p.get ();
- }
-
- static type&
- get_ref (const pointer& p)
- {
- return *p;
- }
-
- static bool
- null_ptr (const pointer& p)
- {
- return !p;
- }
-
- static void*
- allocate (std::size_t n)
- {
- return operator new (n, shared);
- }
-
- static void
- free (void* p)
- {
- operator delete (p, shared);
- }
- };
}
#endif // ODB_POINTER_TRAITS_HXX
diff --git a/odb/result.hxx b/odb/result.hxx
index 0323b66..58dd9cb 100644
--- a/odb/result.hxx
+++ b/odb/result.hxx
@@ -10,7 +10,8 @@
#include <iterator> // iterator categories
#include <odb/forward.hxx>
-#include <odb/shared-ptr.hxx>
+
+#include <odb/details/shared-ptr.hxx>
namespace odb
{
@@ -21,7 +22,7 @@ namespace odb
class result_iterator;
template <typename T>
- class result_impl: public shared_base
+ class result_impl: public details::shared_base
{
public:
virtual
@@ -188,7 +189,7 @@ namespace odb
}
explicit
- result (shared_ptr<result_impl<T> > impl)
+ result (details::shared_ptr<result_impl<T> > impl)
: impl_ (impl)
{
}
@@ -227,7 +228,7 @@ namespace odb
}
private:
- shared_ptr<result_impl<T> > impl_;
+ details::shared_ptr<result_impl<T> > impl_;
};
}
diff --git a/odb/shared-ptr.hxx b/odb/shared-ptr.hxx
deleted file mode 100644
index f6096f7..0000000
--- a/odb/shared-ptr.hxx
+++ /dev/null
@@ -1,159 +0,0 @@
-// file : odb/shared-ptr.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_SHARED_PTR_HXX
-#define ODB_SHARED_PTR_HXX
-
-#include <odb/shared-ptr/base.hxx>
-
-namespace odb
-{
- template <typename X>
- class shared_ptr: bits::counter_ops<typename bits::counter_type<X>::r, X>
- {
- typedef bits::counter_ops<typename bits::counter_type<X>::r, X> base;
-
- public:
- ~shared_ptr ()
- {
- if (x_ != 0)
- base::dec (x_);
- }
-
- explicit
- shared_ptr (X* x = 0)
- : base (x), x_ (x)
- {
- }
-
- shared_ptr (const shared_ptr& x)
- : base (x), x_ (x.x_)
- {
- if (x_ != 0)
- base::inc (x_);
- }
-
- template <typename Y>
- shared_ptr (const shared_ptr<Y>& x)
- : base (x), x_ (x.x_)
- {
- if (x_ != 0)
- base::inc (x_);
- }
-
- shared_ptr&
- operator= (const shared_ptr& x)
- {
- if (x_ != x.x_)
- {
- if (x_ != 0)
- base::dec (x_);
-
- static_cast<base&> (*this) = x;
- x_ = x.x_;
-
- if (x_ != 0)
- base::inc (x_);
- }
-
- return *this;
- }
-
- template <typename Y>
- shared_ptr&
- operator= (const shared_ptr<Y>& x)
- {
- if (x_ != x.x_)
- {
- if (x_ != 0)
- base::dec (x_);
-
- static_cast<base&> (*this) = x;
- x_ = x.x_;
-
- if (x_ != 0)
- base::inc (x_);
- }
-
- return *this;
- }
-
- public:
- X*
- operator-> () const
- {
- return x_;
- }
-
- X&
- operator* () const
- {
- return *x_;
- }
-
- // Conversion to bool.
- //
- typedef void (shared_ptr::*boolean_convertible)();
- void true_value () {};
-
- operator boolean_convertible () const
- {
- return x_ ? &shared_ptr<X>::true_value : 0;
- }
-
- public:
- X*
- get () const
- {
- return x_;
- }
-
- X*
- release ()
- {
- X* r (x_);
- x_ = 0;
- return r;
- }
-
- void
- reset (X* x)
- {
- if (x_ != 0)
- base::dec (x_);
-
- base::reset (x);
- x_ = x;
- }
-
- std::size_t
- count () const
- {
- return x_ != 0 ? base::count (x_) : 0;
- }
-
- private:
- template <typename>
- friend class shared_ptr;
-
- X* x_;
- };
-
- template <typename X, typename Y>
- inline bool
- operator== (const shared_ptr<X>& x, const shared_ptr<Y>& y)
- {
- return x.get () == y.get ();
- }
-
- template <typename X, typename Y>
- inline bool
- operator!= (const shared_ptr<X>& x, const shared_ptr<Y>& y)
- {
- return x.get () != y.get ();
- }
-}
-
-#endif // ODB_SHARED_PTR_HXX
diff --git a/odb/shared-ptr/base.hxx b/odb/shared-ptr/base.hxx
deleted file mode 100644
index 4766aa7..0000000
--- a/odb/shared-ptr/base.hxx
+++ /dev/null
@@ -1,102 +0,0 @@
-// file : odb/shared-ptr/base.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#ifndef ODB_SHARED_PTR_BASE_HXX
-#define ODB_SHARED_PTR_BASE_HXX
-
-#include <new>
-#include <cstddef> // std::size_t
-
-#include <odb/exception.hxx>
-
-namespace odb
-{
- struct share
- {
- explicit
- share (char id);
-
- bool
- operator== (share) const;
-
- private:
- char id_;
- };
-}
-
-extern odb::share shared;
-extern odb::share exclusive;
-
-void*
-operator new (std::size_t, odb::share) throw (std::bad_alloc);
-
-void
-operator delete (void*, odb::share) throw ();
-
-namespace odb
-{
- struct not_shared: exception
- {
- virtual const char*
- what () const throw ();
- };
-
- struct shared_base
- {
- shared_base ();
- shared_base (const shared_base&);
- shared_base&
- operator= (const shared_base&);
-
- void
- _inc_ref ();
-
- bool
- _dec_ref ();
-
- std::size_t
- _ref_count () const;
-
- void*
- operator new (std::size_t, share) throw (std::bad_alloc);
-
- void
- operator delete (void*, share) throw ();
-
- void
- operator delete (void*) throw ();
-
- struct refcount_callback
- {
- void* arg;
- void (*zero_counter) (void*);
- };
-
- private:
- bool
- _dec_ref_callback ();
-
- protected:
- std::size_t counter_;
- refcount_callback* callback_;
- };
-
- template <typename X>
- inline X*
- inc_ref (X*);
-
- template <typename X>
- inline void
- dec_ref (X*);
-
- template <typename X>
- inline std::size_t
- ref_count (const X*);
-}
-
-#include <odb/shared-ptr/base.ixx>
-#include <odb/shared-ptr/base.txx>
-
-#endif // ODB_SHARED_PTR_BASE_HXX
diff --git a/odb/shared-ptr/base.ixx b/odb/shared-ptr/base.ixx
deleted file mode 100644
index 61270a3..0000000
--- a/odb/shared-ptr/base.ixx
+++ /dev/null
@@ -1,82 +0,0 @@
-// file : odb/shared-ptr/base.ixx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-namespace odb
-{
- // share
- //
-
- inline share::
- share (char id)
- : id_ (id)
- {
- }
-
- inline bool share::
- operator== (share x) const
- {
- return id_ == x.id_;
- }
-
- // shared_base
- //
-
- inline shared_base::
- shared_base ()
- : counter_ (1), callback_ (0)
- {
- }
-
- inline shared_base::
- shared_base (const shared_base&)
- : counter_ (1), callback_ (0)
- {
- }
-
- inline shared_base& shared_base::
- operator= (const shared_base&)
- {
- return *this;
- }
-
- inline void shared_base::
- _inc_ref ()
- {
- counter_++;
- }
-
- inline bool shared_base::
- _dec_ref ()
- {
- if (callback_ == 0)
- return --counter_ == 0;
- else
- return _dec_ref_callback ();
- }
-
- inline std::size_t shared_base::
- _ref_count () const
- {
- return counter_;
- }
-
- inline void* shared_base::
- operator new (std::size_t n, share) throw (std::bad_alloc)
- {
- return ::operator new (n);
- }
-
- inline void shared_base::
- operator delete (void* p, share) throw ()
- {
- ::operator delete (p);
- }
-
- inline void shared_base::
- operator delete (void* p) throw ()
- {
- ::operator delete (p);
- }
-}
diff --git a/odb/shared-ptr/base.txx b/odb/shared-ptr/base.txx
deleted file mode 100644
index 5cf85f3..0000000
--- a/odb/shared-ptr/base.txx
+++ /dev/null
@@ -1,200 +0,0 @@
-// file : odb/shared-ptr/base.txx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
-// license : GNU GPL v2; see accompanying LICENSE file
-
-#include <odb/meta/answer.hxx>
-#include <odb/meta/polymorphic-p.hxx>
-
-namespace odb
-{
- namespace bits
- {
- // Support for locating the counter in the memory block.
- //
- template <typename X, bool poly = meta::polymorphic_p<X>::r>
- struct locator;
-
- template <typename X>
- struct locator<X, false>
- {
- static std::size_t*
- counter (X* x)
- {
- std::size_t* p (reinterpret_cast<std::size_t*> (x));
-
- if (*(--p) != 0xDEADBEEF)
- throw not_shared ();
-
- return --p;
- }
- };
-
- template <typename X>
- struct locator<X, true>
- {
- static std::size_t*
- counter (X* x)
- {
- std::size_t* p (
- static_cast<std::size_t*> (
- dynamic_cast<void*> (x)));
-
- if (*(--p) != 0xDEADBEEF)
- throw not_shared ();
-
- return --p;
- }
- };
-
- template <typename X>
- std::size_t*
- counter (const X* p)
- {
- return bits::locator<X>::counter (const_cast<X*> (p));
- }
-
- // Counter type and operations.
- //
- meta::no test (...);
- meta::yes test (shared_base*);
-
- template <typename X,
- std::size_t A = sizeof (bits::test (reinterpret_cast<X*> (0)))>
- struct counter_type;
-
- template <typename X>
- struct counter_type<X, sizeof (meta::no)>
- {
- typedef X r;
- };
-
- template <typename X>
- struct counter_type<X, sizeof (meta::yes)>
- {
- typedef shared_base r;
- };
-
- template <typename X, typename Y>
- struct counter_ops;
-
- template <typename X>
- struct counter_ops<X, X>
- {
- counter_ops (const X* p) : counter_ (p ? bits::counter (p) : 0) {}
- counter_ops (const counter_ops& x) : counter_ (x.counter_) {}
-
- template <typename Z>
- counter_ops (const counter_ops<Z, Z>& x) : counter_ (x.counter_) {}
-
- counter_ops&
- operator= (const counter_ops& x)
- {
- counter_ = x.counter_;
- return *this;
- }
-
- template <typename Z>
- counter_ops&
- operator= (const counter_ops<Z, Z>& x)
- {
- counter_ = x.counter_;
- return *this;
- }
-
- void
- reset (const X* p)
- {
- counter_ = p ? bits::counter (p) : 0;
- }
-
- void
- inc (X*)
- {
- (*counter_)++;
- }
-
- void
- dec (X* p)
- {
- if (--(*counter_) == 0)
- {
- p->~X ();
- operator delete (counter_); // Counter is the top of the memory block.
- }
- }
-
- std::size_t
- count (const X*) const
- {
- return *counter_;
- }
-
- std::size_t* counter_;
- };
-
- template <typename Y>
- struct counter_ops<shared_base, Y>
- {
- counter_ops (const Y*) {}
- counter_ops (const counter_ops&) {}
-
- template <typename Z>
- counter_ops (const counter_ops<shared_base, Z>&) {}
-
- counter_ops&
- operator= (const counter_ops&)
- {
- return *this;
- }
-
- template <typename Z>
- counter_ops&
- operator= (const counter_ops<shared_base, Z>&)
- {
- return *this;
- }
-
- void
- reset (const Y*) {}
-
- void
- inc (shared_base* p) {p->_inc_ref ();}
-
- void
- dec (Y* p)
- {
- if (static_cast<shared_base*> (p)->_dec_ref ())
- delete p;
- }
-
- std::size_t
- count (const shared_base* p) const {return p->_ref_count ();}
- };
- }
-
- template <typename X>
- inline X*
- inc_ref (X* p)
- {
- bits::counter_ops<typename bits::counter_type<X>::r, X> c (p);
- c.inc (p);
- return p;
- }
-
- template <typename X>
- inline void
- dec_ref (X* p)
- {
- bits::counter_ops<typename bits::counter_type<X>::r, X> c (p);
- c.dec (p);
- }
-
- template <typename X>
- inline std::size_t
- ref_count (const X* p)
- {
- bits::counter_ops<typename bits::counter_type<X>::r, X> c (p);
- return c.count (p);
- }
-}
diff --git a/odb/traits.hxx b/odb/traits.hxx
index d393b3d..1701ef0 100644
--- a/odb/traits.hxx
+++ b/odb/traits.hxx
@@ -7,7 +7,6 @@
#define ODB_TRAITS_HXX
#include <odb/forward.hxx>
-#include <odb/shared-ptr.hxx>
#include <odb/pointer-traits.hxx>
namespace odb