From c56f32eb5e0b88ef8297a691f5286ba4aa4aa8b4 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 16 Aug 2010 11:45:23 +0200 Subject: Add pointer guard for naked pointer --- odb/database.txx | 2 +- odb/pointer-traits.hxx | 41 +++++++++++++++++++++++++++++++++++++++++ odb/result.hxx | 25 +++++++++++++++++++++---- odb/traits.hxx | 12 ++++++------ 4 files changed, 69 insertions(+), 11 deletions(-) (limited to 'odb') 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 (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 class pointer_traits; + // No-op pointer guard for smart pointers. + // + template + 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 pointer; + typedef nop_guard guard; // Return underlying pointer, including NULL. // @@ -77,12 +96,33 @@ namespace odb // Specialization for naked pointer. // + template + 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 class pointer_traits { public: typedef T type; typedef T* pointer; + typedef nptr_guard guard; static type* get_ptr (pointer p) @@ -126,6 +166,7 @@ namespace odb public: typedef T type; typedef odb::shared_ptr pointer; + typedef nop_guard 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; friend class result_iterator; - typename object_traits::pointer_type - current (bool /*release*/) + typedef object_traits traits; + typedef typename traits::pointer_type pointer_type; + typedef typename traits::pointer_traits pointer_traits; + + pointer_type + current (bool release) { - if (object_traits::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::pointer_type current_; + + private: + pointer_type current_; + typename pointer_traits::guard guard_; }; template 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

::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

::free (p_);} + mem_guard (void* p): p_ (p) {} + ~mem_guard () {if (p_) pointer_traits

::free (p_);} void release () {p_ = 0;} void* p_; }; @@ -86,8 +86,8 @@ namespace odb struct object_traits: access::object_traits { typedef - pointer_traits::pointer_type> - pointer_ops; + odb::pointer_traits::pointer_type> + pointer_traits; }; } -- cgit v1.1