diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2010-11-15 17:46:28 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2010-11-15 17:46:28 +0200 |
commit | 30b664c0561cc9f6d2bd24f7bce9b6c57fb52320 (patch) | |
tree | 743ce4a41249c8586e81a001cf147bedfbdf9a85 | |
parent | 93392ca601a0cab8517a4ca8d163df4b41dd3e49 (diff) |
Add support for custom object pointers
New option: --default-pointer. New object pragma specifier: pointer.
-rw-r--r-- | odb/forward.hxx | 7 | ||||
-rw-r--r-- | odb/pointer-traits.hxx | 6 | ||||
-rw-r--r-- | odb/result.hxx | 23 | ||||
-rw-r--r-- | odb/result.txx | 14 | ||||
-rw-r--r-- | odb/traits.hxx | 35 |
5 files changed, 43 insertions, 42 deletions
diff --git a/odb/forward.hxx b/odb/forward.hxx index bd6cbcb..dbd3628 100644 --- a/odb/forward.hxx +++ b/odb/forward.hxx @@ -19,13 +19,10 @@ namespace odb template <typename T> class object_traits; - template <typename T> - class object_memory; - - template <typename T> + template <typename T, typename P> class object_factory; - template <typename P> + template <typename T, typename P> class pointer_factory; template <typename T> diff --git a/odb/pointer-traits.hxx b/odb/pointer-traits.hxx index 18162e4..4c94709 100644 --- a/odb/pointer-traits.hxx +++ b/odb/pointer-traits.hxx @@ -25,13 +25,13 @@ namespace odb nop_guard () {} explicit - nop_guard (P) {} + nop_guard (const P&) {} void release () {} void - reset (P) {} + reset (const P&) {} }; // Default implementation that should work for any sensible smart @@ -69,7 +69,7 @@ namespace odb static bool null_ptr (const pointer& p) { - return get_ptr () == 0; + return get_ptr (p) == 0; } public: diff --git a/odb/result.hxx b/odb/result.hxx index ff9f057..cf924c3 100644 --- a/odb/result.hxx +++ b/odb/result.hxx @@ -40,8 +40,19 @@ namespace odb typedef typename traits::pointer_type pointer_type; typedef typename traits::pointer_traits pointer_traits; - pointer_type - current (bool release); + // To make this work with all kinds of pointers (naked, std::auto_ptr, + // shared), we need to make sure we don't make any copies of the + // pointer on the return path. + // + pointer_type& + current (); + + void + release () + { + current_ = pointer_type (); + guard_.release (); + } bool end () const @@ -100,7 +111,7 @@ namespace odb reference operator* () const { - return pointer_traits::get_ref (res_->current (false)); + return pointer_traits::get_ref (res_->current ()); } // Our value_type is already a pointer so return it instead of @@ -110,7 +121,7 @@ namespace odb pointer operator-> () const { - return pointer_traits::get_ptr (res_->current (false)); + return pointer_traits::get_ptr (res_->current ()); } result_iterator& @@ -133,7 +144,9 @@ namespace odb typename object_traits<T>::pointer_type load () { - return res_->current (true); + typename object_traits<T>::pointer_type r (res_->current ()); + res_->release (); + return r; } void diff --git a/odb/result.txx b/odb/result.txx index e58af1f..3068890 100644 --- a/odb/result.txx +++ b/odb/result.txx @@ -12,8 +12,8 @@ namespace odb } template <typename T> - typename result_impl<T>::pointer_type result_impl<T>:: - current (bool release) + typename result_impl<T>::pointer_type& result_impl<T>:: + current () { if (pointer_traits::null_ptr (current_) && !end_) { @@ -21,14 +21,6 @@ namespace odb current (pointer_traits::get_ref (current_)); } - pointer_type r (current_); - - if (release) - { - current_ = pointer_type (); - guard_.release (); - } - - return r; + return current_; } } diff --git a/odb/traits.hxx b/odb/traits.hxx index 318d88b..bc25dcb 100644 --- a/odb/traits.hxx +++ b/odb/traits.hxx @@ -16,8 +16,7 @@ namespace odb // template <typename T> // class access::object_traits; // - // Specializations should inherit from object_memory, object_factory - // and define the following members: + // Specializations should define the following members: // // id_type - object id (primary key) type // id_type id (const T&) - get object id @@ -30,39 +29,35 @@ namespace odb // // - template <typename T> - class access::object_memory - { - public: - typedef T* pointer_type; - }; - - template <typename T> + template <typename T, typename P> class access::object_factory { public: - static typename object_memory<T>::pointer_type + typedef T object_type; + typedef P pointer_type; + + static P create () { // By default use pointer-specific construction. // - return - pointer_factory<typename object_memory<T>::pointer_type>::create (); + return pointer_factory<T, P>::create (); } }; - template <typename P> + template <typename T, typename P> class access::pointer_factory { public: - typedef typename pointer_traits<P>::type object_type; + typedef T object_type; + typedef P pointer_type; static P create () { - void* v (pointer_traits<P>::allocate (sizeof (object_type))); + void* v (pointer_traits<P>::allocate (sizeof (T))); mem_guard g (v); - P p (new (v) object_type); + P p (new (v) T); g.release (); return p; } @@ -77,8 +72,12 @@ namespace odb }; template <typename T> - struct object_traits: access::object_traits<T> + struct object_traits: access::object_traits<T>, + access::object_factory<T, typename access::object_traits<T>::pointer_type> { + typedef typename access::object_traits<T>::object_type object_type; + typedef typename access::object_traits<T>::pointer_type pointer_type; + typedef odb::pointer_traits<typename access::object_traits<T>::pointer_type> pointer_traits; |