diff options
Diffstat (limited to 'odb/object-result.hxx')
-rw-r--r-- | odb/object-result.hxx | 358 |
1 files changed, 30 insertions, 328 deletions
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 <odb/pre.hxx> -#include <cstddef> // std::ptrdiff_t, std::size_t +#include <cstddef> // std::ptrdiff_t #include <iterator> // iterator categories -#include <utility> // std::move #include <odb/forward.hxx> +#include <odb/traits.hxx> #include <odb/result.hxx> #include <odb/pointer-traits.hxx> -#include <odb/details/config.hxx> // ODB_CXX11 -#include <odb/details/shared-ptr.hxx> - namespace odb { + // + // object_result_impl + // template <typename T> class object_result_impl; template <typename T> - class object_result_impl_no_id; + class polymorphic_object_result_impl; - template <typename T, typename ID> - class object_result_iterator; + template <typename T> + class no_id_object_result_impl; + + // + // object_result_impl_selector + // + template <typename T, + typename ID = typename object_traits<T>::id_type, + bool polymorphic = object_traits<T>::polymorphic> + struct object_result_impl_selector; - template <typename T, typename ID = typename object_traits<T>::id_type> - struct object_result_impl_selector + template <typename T, typename ID> + struct object_result_impl_selector<T, ID, false> { typedef object_result_impl<T> type; }; - template <typename T> - struct object_result_impl_selector<T, void> + template <typename T, typename ID> + struct object_result_impl_selector<T, ID, true> { - typedef object_result_impl_no_id<T> type; + typedef polymorphic_object_result_impl<T> type; }; - // Implementation for objects with object id. - // template <typename T> - class object_result_impl: public details::shared_base + struct object_result_impl_selector<T, void, false> { - 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_type> object_traits; - typedef typename object_traits::id_type id_type; - - typedef typename object_traits::pointer_type pointer_type; - typedef odb::pointer_traits<pointer_type> pointer_traits; - - friend class result<T>; - friend class result<const T>; - friend class result_iterator<T, class_object>; - friend class result_iterator<const T, class_object>; - friend class object_result_iterator<T, id_type>; - friend class object_result_iterator<const T, id_type>; - - 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 <typename T> - 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_type> object_traits; - - typedef typename object_traits::pointer_type pointer_type; - typedef odb::pointer_traits<pointer_type> pointer_traits; - - friend class result<T>; - friend class result<const T>; - friend class result_iterator<T, class_object>; - friend class result_iterator<const T, class_object>; - friend class object_result_iterator<T, void>; - friend class object_result_iterator<const T, void>; - - 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<T> type; }; // // result_iterator // - template <typename T, typename ID> - class object_result_iterator - { - public: - // T can be const T while object_type is always non-const. - // - typedef typename object_traits<T>::object_type object_type; - typedef typename object_traits<T>::id_type id_type; - - typedef object_result_impl<object_type> result_impl_type; - - public: - object_result_iterator (result_impl_type* res) - : res_ (res) - { - } - - public: - typename object_traits<T>::pointer_type - load () - { - typename object_traits<T>::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 <typename T> - class object_result_iterator<T, void> - { - public: - // T can be const T while object_type is always non-const. - // - typedef typename object_traits<T>::object_type object_type; - - typedef object_result_impl_no_id<object_type> result_impl_type; - - public: - object_result_iterator (result_impl_type* res) - : res_ (res) - { - } - - public: - typename object_traits<T>::pointer_type - load () - { - typename object_traits<T>::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 <typename T, typename ID, bool polymorphic> + class object_result_iterator; template <typename T> class result_iterator<T, class_object>: public object_result_iterator< T, - typename object_traits<T>::id_type> + typename object_traits<T>::id_type, + object_traits<T>::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<T, typename object_traits<T>::id_type> - base_type; + object_result_iterator<T, + typename object_traits<T>::id_type, + object_traits<T>::polymorphic> base_type; public: explicit @@ -456,8 +160,6 @@ namespace odb }; } -#include <odb/object-result.txx> - #include <odb/post.hxx> #endif // ODB_OBJECT_RESULT_HXX |