From 1896d36996ab48ed7271e855d7e32b4e61f64896 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 23 Apr 2012 16:48:00 +0200 Subject: Polymorphic inheritance support --- odb/object-result.hxx | 358 +++++--------------------------------------------- 1 file changed, 30 insertions(+), 328 deletions(-) (limited to 'odb/object-result.hxx') diff --git a/odb/object-result.hxx b/odb/object-result.hxx index 759c9f5..f966018 100644 --- a/odb/object-result.hxx +++ b/odb/object-result.hxx @@ -7,363 +7,66 @@ #include -#include // std::ptrdiff_t, std::size_t +#include // std::ptrdiff_t #include // iterator categories -#include // std::move #include +#include #include #include -#include // ODB_CXX11 -#include - namespace odb { + // + // object_result_impl + // template class object_result_impl; template - class object_result_impl_no_id; + class polymorphic_object_result_impl; - template - class object_result_iterator; + template + class no_id_object_result_impl; + + // + // object_result_impl_selector + // + template ::id_type, + bool polymorphic = object_traits::polymorphic> + struct object_result_impl_selector; - template ::id_type> - struct object_result_impl_selector + template + struct object_result_impl_selector { typedef object_result_impl type; }; - template - struct object_result_impl_selector + template + struct object_result_impl_selector { - typedef object_result_impl_no_id type; + typedef polymorphic_object_result_impl type; }; - // Implementation for objects with object id. - // template - class object_result_impl: public details::shared_base + struct object_result_impl_selector { - public: - virtual - ~object_result_impl (); - - protected: - typedef odb::database database_type; - - // In result_impl, T is always non-const and the same as object_type. - // - typedef T object_type; - typedef odb::object_traits object_traits; - typedef typename object_traits::id_type id_type; - - typedef typename object_traits::pointer_type pointer_type; - typedef odb::pointer_traits pointer_traits; - - friend class result; - friend class result; - friend class result_iterator; - friend class result_iterator; - friend class object_result_iterator; - friend class object_result_iterator; - - protected: - object_result_impl (database_type& db) - : begin_ (true), end_ (false), db_ (db), current_ () - { - } - - database_type& - database () const - { - return db_; - } - - // To make this work with all kinds of pointers (raw, 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 (); - } - - void - begin () - { - if (begin_) - { - next (); - begin_ = false; - } - } - - bool - end () const - { - return end_; - } - - protected: - // The fetch argument is a hint to the implementation. If it is - // false then it means load_id() was already called (and presumably - // fetched the data into the object image) and the object image - // is still valid (so the implementation doesn't need to fetch - // the data again). - // - virtual void - load (object_type&, bool fetch = true) = 0; - - virtual id_type - load_id () = 0; - - virtual void - next () = 0; - - virtual void - cache () = 0; - - virtual std::size_t - size () = 0; - - protected: -#ifdef ODB_CXX11 - void - current (pointer_type& p) - { - current_ = std::move (p); - guard_.reset (current_); - } - - void - current (pointer_type&& p) - { - current (p); - } -#else - void - current (pointer_type p) - { - current_ = p; - guard_.reset (current_); - } -#endif - - bool begin_; - bool end_; - - private: - database_type& db_; - pointer_type current_; - typename pointer_traits::guard guard_; - }; - - // Implementation for objects without object id. - // - template - class object_result_impl_no_id: public details::shared_base - { - public: - virtual - ~object_result_impl_no_id (); - - protected: - typedef odb::database database_type; - - // In result_impl, T is always non-const and the same as object_type. - // - typedef T object_type; - typedef odb::object_traits object_traits; - - typedef typename object_traits::pointer_type pointer_type; - typedef odb::pointer_traits pointer_traits; - - friend class result; - friend class result; - friend class result_iterator; - friend class result_iterator; - friend class object_result_iterator; - friend class object_result_iterator; - - protected: - object_result_impl_no_id (database_type& db) - : begin_ (true), end_ (false), db_ (db), current_ () - { - } - - database_type& - database () const - { - return db_; - } - - // To make this work with all kinds of pointers (raw, 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 (); - } - - void - begin () - { - if (begin_) - { - next (); - begin_ = false; - } - } - - bool - end () const - { - return end_; - } - - protected: - virtual void - load (object_type&) = 0; - - virtual void - next () = 0; - - virtual void - cache () = 0; - - virtual std::size_t - size () = 0; - - protected: -#ifdef ODB_CXX11 - void - current (pointer_type& p) - { - current_ = std::move (p); - guard_.reset (current_); - } - - void - current (pointer_type&& p) - { - current (p); - } -#else - void - current (pointer_type p) - { - current_ = p; - guard_.reset (current_); - } -#endif - - bool begin_; - bool end_; - - private: - database_type& db_; - pointer_type current_; - typename pointer_traits::guard guard_; + typedef no_id_object_result_impl type; }; // // result_iterator // - template - class object_result_iterator - { - public: - // T can be const T while object_type is always non-const. - // - typedef typename object_traits::object_type object_type; - typedef typename object_traits::id_type id_type; - - typedef object_result_impl result_impl_type; - - public: - object_result_iterator (result_impl_type* res) - : res_ (res) - { - } - - public: - typename object_traits::pointer_type - load () - { - typename object_traits::pointer_type r (res_->current ()); - res_->release (); - return r; - } - - void - load (object_type&); - - id_type - id () - { - return res_->load_id (); - } - - protected: - result_impl_type* res_; - }; - - template - class object_result_iterator - { - public: - // T can be const T while object_type is always non-const. - // - typedef typename object_traits::object_type object_type; - - typedef object_result_impl_no_id result_impl_type; - - public: - object_result_iterator (result_impl_type* res) - : res_ (res) - { - } - - public: - typename object_traits::pointer_type - load () - { - typename object_traits::pointer_type r (res_->current ()); - res_->release (); - return r; - } - - void - load (object_type& obj) - { - // Objects without ids are not stored in session cache. - // - if (!res_->end ()) - res_->load (obj); - } - - protected: - result_impl_type* res_; - }; + template + class object_result_iterator; template class result_iterator: public object_result_iterator< T, - typename object_traits::id_type> + typename object_traits::id_type, + object_traits::polymorphic> { public: typedef T value_type; @@ -375,8 +78,9 @@ namespace odb // T can be const T while object_type is always non-const. // typedef - object_result_iterator::id_type> - base_type; + object_result_iterator::id_type, + object_traits::polymorphic> base_type; public: explicit @@ -456,8 +160,6 @@ namespace odb }; } -#include - #include #endif // ODB_OBJECT_RESULT_HXX -- cgit v1.1