diff options
-rw-r--r-- | odb/pointer-traits.hxx | 122 | ||||
-rw-r--r-- | odb/result.hxx | 2 | ||||
-rw-r--r-- | odb/tr1-pointer-traits.hxx | 74 |
3 files changed, 137 insertions, 61 deletions
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 <odb/pre.hxx> #include <new> // operators new/delete +#include <memory> // std::auto_ptr #include <cstddef> // std::size_t namespace odb @@ -16,16 +17,42 @@ namespace odb template <typename P> class pointer_traits; + // + // Standard pointer guards. + // + + // Naked pointer guard. + // + template <typename P> + 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 <typename P> - 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 <typename T, template <typename> class P> - class pointer_traits< P<T> > + template <typename T> + class pointer_traits<T*> { public: - typedef T type; - typedef P<T> pointer; - typedef nop_guard<pointer> guard; + typedef T element_type; + typedef T* pointer_type; + typedef naked_ptr_guard<pointer_type> 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 <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*> + class pointer_traits< std::auto_ptr<T> > { public: - typedef T type; - typedef T* pointer; - typedef nptr_guard<pointer> guard; + typedef T element_type; + typedef std::auto_ptr<element_type> pointer_type; + typedef smart_ptr_guard<pointer_type> 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: diff --git a/odb/result.hxx b/odb/result.hxx index cf924c3..42acb0e 100644 --- a/odb/result.hxx +++ b/odb/result.hxx @@ -85,7 +85,7 @@ namespace odb private: pointer_type current_; - typename pointer_traits::guard guard_; + typename pointer_traits::guard_type guard_; }; template <typename T> diff --git a/odb/tr1-pointer-traits.hxx b/odb/tr1-pointer-traits.hxx new file mode 100644 index 0000000..edb5ce8 --- /dev/null +++ b/odb/tr1-pointer-traits.hxx @@ -0,0 +1,74 @@ +// file : odb/tr1-pointer-traits.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_TR1_POINTER_TRAITS_HXX +#define ODB_TR1_POINTER_TRAITS_HXX + +#include <odb/pre.hxx> + +// This header assumes that the necessary TR1 header has already +// been included. +// +#include <odb/pointer-traits.hxx> + +namespace odb +{ + // Specialization for std::tr1::shared_ptr. + // + template <typename T> + class pointer_traits< std::tr1::shared_ptr<T> > + { + public: + typedef T element_type; + typedef std::tr1::shared_ptr<element_type> pointer_type; + typedef smart_ptr_guard<pointer_type> guard_type; + + static element_type* + get_ptr (const pointer_type& p) + { + return p.get (); + } + + static element_type& + get_ref (const pointer_type& p) + { + return *p; + } + + static bool + null_ptr (const pointer_type& p) + { + return p.get () == 0; + } + + public: + static void* + allocate (std::size_t n) + { + return operator new (n); + } + + static void + free (void* p) + { + operator delete (p); + } + }; + + // Specialization for std::tr1::weak_ptr. + // + template <typename T> + class pointer_traits< std::tr1::weak_ptr<T> > + { + public: + typedef T element_type; + typedef std::tr1::weak_ptr<element_type> pointer_type; + typedef std::tr1::shared_ptr<element_type> strong_pointer_type; + }; +} + +#include <odb/post.hxx> + +#endif // ODB_TR1_POINTER_TRAITS_HXX |