aboutsummaryrefslogtreecommitdiff
path: root/odb/result.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/result.hxx')
-rw-r--r--odb/result.hxx327
1 files changed, 14 insertions, 313 deletions
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 <odb/pre.hxx>
-#include <cstddef> // std::ptrdiff_t, std::size_t
-#include <iterator> // iterator categories
-
-#include <odb/forward.hxx>
-#include <odb/pointer-traits.hxx>
-
-#include <odb/details/shared-ptr.hxx>
+#include <odb/forward.hxx> // result
+#include <odb/traits.hxx>
namespace odb
{
- template <typename T>
+ template <typename T, class_kind kind = class_traits<T>::kind>
class result;
- template <typename T>
+ template <typename T, class_kind kind = class_traits<T>::kind>
class result_iterator;
- template <typename T>
- class result_impl: public details::shared_base
- {
- public:
- virtual
- ~result_impl ();
-
- protected:
- friend class result<T>;
- friend class result_iterator<T>;
-
- typedef odb::database database_type;
-
- typedef typename odb::object_traits<T>::pointer_type pointer_type;
- typedef odb::pointer_traits<pointer_type> pointer_traits;
-
- typedef typename odb::object_traits<T>::object_type object_type;
- typedef typename odb::object_traits<T>::id_type id_type;
- typedef odb::object_traits<object_type> 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 <typename T>
- 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<T>::object_type object_type;
- typedef typename object_traits<T>::id_type id_type;
-
- public:
- explicit
- result_iterator (result_impl<T>* 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<T>::pointer_type
- load ()
- {
- typename object_traits<T>::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<typename object_traits<T>::pointer_type>
- pointer_traits;
-
- result_impl<T>* res_;
- };
-
- // Input iterator requirements.
- //
- template <typename T>
- inline bool
- operator== (result_iterator<T> i, result_iterator<T> j)
- {
- return i.equal (j);
- }
-
- template <typename T>
- inline bool
- operator!= (result_iterator<T> i, result_iterator<T> j)
- {
- return !i.equal (j);
- }
-
- //
- //
- template <typename T>
- class result
- {
- public:
- typedef typename object_traits<T>::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<T> iterator;
-
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- public:
- result ()
- {
- }
-
- explicit
- result (details::shared_ptr<result_impl<T> > 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<result_impl<T> > 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<result_impl<T> > impl_;
- };
+ template <typename T, class_kind kind>
+ class result_impl;
namespace core
{
using odb::result;
+ using odb::result_iterator;
}
}
-#include <odb/result.txx>
-
#include <odb/post.hxx>
#endif // ODB_RESULT_HXX
+
+// Include result specializations so that the user code only needs
+// to include this header.
+//
+
+#include <odb/object-result.hxx>
+#include <odb/view-result.hxx>