aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-08-16 11:45:23 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-08-16 11:45:23 +0200
commitc56f32eb5e0b88ef8297a691f5286ba4aa4aa8b4 (patch)
treeb6978e5a2e90839f1b0f3faead5448b926b1b010
parentb9376a8bd73d12c868dafa2d1f686058a77d35be (diff)
Add pointer guard for naked pointer
-rw-r--r--odb/database.txx2
-rw-r--r--odb/pointer-traits.hxx41
-rw-r--r--odb/result.hxx25
-rw-r--r--odb/traits.hxx12
4 files changed, 69 insertions, 11 deletions
diff --git a/odb/database.txx b/odb/database.txx
index a120afa..bec3234 100644
--- a/odb/database.txx
+++ b/odb/database.txx
@@ -32,7 +32,7 @@ namespace odb
typename traits::pointer_type r (find<T> (id));
- if (traits::pointer_ops::null_ptr (r))
+ if (traits::pointer_traits::null_ptr (r))
throw object_not_persistent ();
return r;
diff --git a/odb/pointer-traits.hxx b/odb/pointer-traits.hxx
index a715a9d..26f8b90 100644
--- a/odb/pointer-traits.hxx
+++ b/odb/pointer-traits.hxx
@@ -16,6 +16,24 @@ namespace odb
template <typename P>
class pointer_traits;
+ // No-op pointer guard for smart pointers.
+ //
+ template <typename P>
+ class nop_guard
+ {
+ public:
+ nop_guard () {}
+
+ explicit
+ nop_guard (P) {}
+
+ void
+ release () {}
+
+ void
+ reset (P) {}
+ };
+
// Default implementation that should work for any sensible smart
// pointer with one template argument (object type). The only
// assumptions that we make are the availability of operator-> and
@@ -28,6 +46,7 @@ namespace odb
public:
typedef T type;
typedef P<T> pointer;
+ typedef nop_guard<pointer> guard;
// Return underlying pointer, including NULL.
//
@@ -77,12 +96,33 @@ namespace odb
// Specialization for naked pointer.
//
+ template <typename P>
+ class nptr_guard
+ {
+ public:
+ ~nptr_guard () {delete p_;}
+ nptr_guard (): p_ (0) {}
+
+ explicit
+ nptr_guard (P p): p_ (p) {}
+
+ void
+ release () {p_ = 0;}
+
+ void
+ reset (P p) {delete p_; p_ = p;}
+
+ private:
+ P p_;
+ };
+
template <typename T>
class pointer_traits<T*>
{
public:
typedef T type;
typedef T* pointer;
+ typedef nptr_guard<pointer> guard;
static type*
get_ptr (pointer p)
@@ -126,6 +166,7 @@ namespace odb
public:
typedef T type;
typedef odb::shared_ptr<T> pointer;
+ typedef nop_guard<pointer> guard;
static type*
get_ptr (const pointer& p)
diff --git a/odb/result.hxx b/odb/result.hxx
index 87374e5..0323b66 100644
--- a/odb/result.hxx
+++ b/odb/result.hxx
@@ -32,12 +32,19 @@ namespace odb
friend class result<T>;
friend class result_iterator<T>;
- typename object_traits<T>::pointer_type
- current (bool /*release*/)
+ typedef object_traits<T> traits;
+ typedef typename traits::pointer_type pointer_type;
+ typedef typename traits::pointer_traits pointer_traits;
+
+ pointer_type
+ current (bool release)
{
- if (object_traits<T>::pointer_ops::null_ptr (current_) && !end_)
+ if (pointer_traits::null_ptr (current_) && !end_)
current ();
+ if (release)
+ guard_.release ();
+
return current_;
}
@@ -58,8 +65,18 @@ namespace odb
next () = 0;
protected:
+ void
+ current (pointer_type p)
+ {
+ current_ = p;
+ guard_.reset (current_);
+ }
+
bool end_;
- typename object_traits<T>::pointer_type current_;
+
+ private:
+ pointer_type current_;
+ typename pointer_traits::guard guard_;
};
template <typename T>
diff --git a/odb/traits.hxx b/odb/traits.hxx
index d38ee41..e5c9eed 100644
--- a/odb/traits.hxx
+++ b/odb/traits.hxx
@@ -67,16 +67,16 @@ namespace odb
create ()
{
void* v (pointer_traits<P>::allocate (sizeof (object_type)));
- guard g (v);
+ mem_guard g (v);
P p (new (v) object_type);
g.release ();
return p;
}
private:
- struct guard
+ struct mem_guard
{
- guard (void* p): p_ (p) {}
- ~guard () {if (p_) pointer_traits<P>::free (p_);}
+ mem_guard (void* p): p_ (p) {}
+ ~mem_guard () {if (p_) pointer_traits<P>::free (p_);}
void release () {p_ = 0;}
void* p_;
};
@@ -86,8 +86,8 @@ namespace odb
struct object_traits: access::object_traits<T>
{
typedef
- pointer_traits<typename access::object_traits<T>::pointer_type>
- pointer_ops;
+ odb::pointer_traits<typename access::object_traits<T>::pointer_type>
+ pointer_traits;
};
}