From a157760b26ccbd16250e263ee16d12a483124227 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 16 Nov 2010 08:49:35 +0200 Subject: Rework pointer traits, add naked, auto_ptr, and TR1 specializations --- odb/pointer-traits.hxx | 122 +++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 60 deletions(-) (limited to 'odb/pointer-traits.hxx') diff --git a/odb/pointer-traits.hxx b/odb/pointer-traits.hxx index 4c94709..34ec7cd 100644 --- a/odb/pointer-traits.hxx +++ b/odb/pointer-traits.hxx @@ -9,6 +9,7 @@ #include #include // operators new/delete +#include // std::auto_ptr #include // std::size_t namespace odb @@ -16,16 +17,42 @@ namespace odb template class pointer_traits; + // + // Standard pointer guards. + // + + // Naked pointer guard. + // + template + class naked_ptr_guard + { + public: + ~naked_ptr_guard () {delete p_;} + naked_ptr_guard (): p_ (0) {} + + explicit + naked_ptr_guard (P p): p_ (p) {} + + void + release () {p_ = 0;} + + void + reset (P p) {delete p_; p_ = p;} + + private: + P p_; + }; + // No-op pointer guard for smart pointers. // template - class nop_guard + class smart_ptr_guard { public: - nop_guard () {} + smart_ptr_guard () {} explicit - nop_guard (const P&) {} + smart_ptr_guard (const P&) {} void release () {} @@ -34,32 +61,28 @@ namespace odb reset (const 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 - // operator*, and that the former does not throw if the pointer is - // NULL. + // Specialization for naked pointers. // - template class P> - class pointer_traits< P > + template + class pointer_traits { public: - typedef T type; - typedef P pointer; - typedef nop_guard guard; + typedef T element_type; + typedef T* pointer_type; + typedef naked_ptr_guard guard_type; - // Return underlying pointer, including NULL. + // Return naked pointer to the pointed-to element, including NULL. // - static type* - get_ptr (const pointer& p) + static element_type* + get_ptr (pointer_type p) { - return p.operator-> (); + return p; } - // Return reference to the pointed-to object. + // Return reference to the pointed-to element. // - static type& - get_ref (const pointer& p) + static element_type& + get_ref (pointer_type p) { return *p; } @@ -67,13 +90,14 @@ namespace odb // Return true if the pointer is NULL. // static bool - null_ptr (const pointer& p) + null_ptr (pointer_type p) { - return get_ptr (p) == 0; + return p == 0; } public: - // Allocate memory for a shared object. + // Allocate memory for an element that will be managed by this + // pointer. // static void* allocate (std::size_t n) @@ -81,9 +105,9 @@ namespace odb return operator new (n); } - // Free memory allocated for a shared object. This functions is - // only called if the constructor of the object being created - // fails. Otherwise, pointer is used to delete the object + // Free memory allocated for an element. This functions is only + // called if the constructor of the element being created fails. + // Otherwise, the pointer (or guard) is used to delete the object // and free the memory. This behavior is identical to the one // used by operator delete overloading. // @@ -94,54 +118,32 @@ namespace odb } }; - // Specialization for naked pointer. + // Specialization for std::auto_ptr. // - 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 + class pointer_traits< std::auto_ptr > { public: - typedef T type; - typedef T* pointer; - typedef nptr_guard guard; + typedef T element_type; + typedef std::auto_ptr pointer_type; + typedef smart_ptr_guard guard_type; - static type* - get_ptr (pointer p) + static element_type* + get_ptr (const pointer_type& p) { - return p; + return p.get (); } - static type& - get_ref (pointer p) + static element_type& + get_ref (const pointer_type& p) { return *p; } - // Return true if the pointer is NULL. - // static bool - null_ptr (pointer p) + null_ptr (const pointer_type& p) { - return p == 0; + return p.get () == 0; } public: -- cgit v1.1