From 9c275a93cec797a021571ba8545906e0b4ffbfbc Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 5 Sep 2011 10:20:47 +0200 Subject: Support for views; native part --- odb/result.hxx | 327 +++------------------------------------------------------ 1 file changed, 14 insertions(+), 313 deletions(-) (limited to 'odb/result.hxx') diff --git a/odb/result.hxx b/odb/result.hxx index 17406e7..a997615 100644 --- a/odb/result.hxx +++ b/odb/result.hxx @@ -8,333 +8,34 @@ #include -#include // std::ptrdiff_t, std::size_t -#include // iterator categories - -#include -#include - -#include +#include // result +#include namespace odb { - template + template ::kind> class result; - template + template ::kind> class result_iterator; - template - class result_impl: public details::shared_base - { - public: - virtual - ~result_impl (); - - protected: - friend class result; - friend class result_iterator; - - typedef odb::database database_type; - - typedef typename odb::object_traits::pointer_type pointer_type; - typedef odb::pointer_traits pointer_traits; - - typedef typename odb::object_traits::object_type object_type; - typedef typename odb::object_traits::id_type id_type; - typedef odb::object_traits object_traits; - - 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: - virtual void - load (object_type&) = 0; - - virtual id_type - load_id () = 0; - - virtual void - next () = 0; - - virtual void - cache () = 0; - - virtual std::size_t - size () = 0; - - protected: - void - current (pointer_type p) - { - current_ = p; - guard_.reset (current_); - } - - bool begin_; - bool end_; - - private: - database_type& db_; - pointer_type current_; - typename pointer_traits::guard guard_; - }; - - template - class result_iterator - { - public: - typedef T value_type; - typedef value_type& reference; - typedef value_type* pointer; - typedef std::ptrdiff_t difference_type; - typedef std::input_iterator_tag iterator_category; - - // T might be const T, but object_type is always T. - // - typedef typename object_traits::object_type object_type; - typedef typename object_traits::id_type id_type; - - public: - explicit - result_iterator (result_impl* res = 0) - : res_ (res) - { - } - - // Input iterator requirements. - // - public: - reference - operator* () const - { - return pointer_traits::get_ref (res_->current ()); - } - - // Our value_type is already a pointer so return it instead of - // a pointer to it (operator-> will just have to go one deeper - // in the latter case). - // - pointer - operator-> () const - { - return pointer_traits::get_ptr (res_->current ()); - } - - result_iterator& - operator++ () - { - res_->next (); - return *this; - } - - result_iterator - operator++ (int) - { - // All non-end iterators for a result object move together. - // - res_->next (); - return *this; - } - - public: - typename object_traits::pointer_type - load () - { - typename object_traits::pointer_type r (res_->current ()); - res_->release (); - return r; - } - - void - load (object_type&); - - public: - bool - equal (result_iterator j) const - { - return (res_ ? res_->end () : true) == (j.res_ ? j.res_->end () : true); - } - - private: - typedef - odb::pointer_traits::pointer_type> - pointer_traits; - - result_impl* res_; - }; - - // Input iterator requirements. - // - template - inline bool - operator== (result_iterator i, result_iterator j) - { - return i.equal (j); - } - - template - inline bool - operator!= (result_iterator i, result_iterator j) - { - return !i.equal (j); - } - - // - // - template - class result - { - public: - typedef typename object_traits::pointer_type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - - typedef result_iterator iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - public: - result () - { - } - - explicit - result (details::shared_ptr > impl) - : impl_ (impl) - { - } - - // Copying or assignment of a result object leads to one instance - // being an alias for another. Think of copying a result as copying - // a file handle -- the file you access through either of them is - // still the same. - // - public: - result (const result& r) - : impl_ (r.impl_) - { - } - - result& - operator= (const result& r) - { - if (impl_ != r.impl_) - impl_ = r.impl_; - - return *this; - } - - void - swap (result& r) - { - // @@ add swap() to shared_ptr. - // - details::shared_ptr > p (impl_); - impl_ = r.impl_; - r.impl_ = p; - } - - public: - iterator - begin () - { - if (impl_) - impl_->begin (); - - return iterator (impl_.get ()); - } - - iterator - end () - { - return iterator (); - } - - // Cache the result instead of fetching the data from the database - // one object at a time. This is necessary if you plan on performing - // database operations while iterating over the result. - // - public: - void - cache () - { - if (impl_) - impl_->cache (); - } - - public: - bool - empty () const - { - if (impl_ == 0) - return true; - - impl_->begin (); - return impl_->end (); - } - - // Size is only known in cached results. - // - size_type - size () const - { - return impl_ ? impl_->size () : 0; - } - - private: - details::shared_ptr > impl_; - }; + template + class result_impl; namespace core { using odb::result; + using odb::result_iterator; } } -#include - #include #endif // ODB_RESULT_HXX + +// Include result specializations so that the user code only needs +// to include this header. +// + +#include +#include -- cgit v1.1