aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-09-22 11:02:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-09-22 11:02:08 +0200
commitb9d18e76f95a9a231cc4a8a9aea5bf1bad942c9a (patch)
treeb6aba372e9217b6427e29a9f0f4373688f9200e8
parent57419407e931555cb4841b9a3cc0a01f5f60cdcc (diff)
Make common result implementation instead of separate for views and objects1.6.0.a2
-rw-r--r--odb/object-result.hxx155
-rw-r--r--odb/result.hxx170
-rw-r--r--odb/view-result.hxx155
3 files changed, 173 insertions, 307 deletions
diff --git a/odb/object-result.hxx b/odb/object-result.hxx
index b4ef810..4c25962 100644
--- a/odb/object-result.hxx
+++ b/odb/object-result.hxx
@@ -27,8 +27,8 @@ namespace odb
~result_impl ();
protected:
- friend class result<T, class_object>;
- friend class result<const T, class_object>;
+ friend class result<T>;
+ friend class result<const T>;
friend class result_iterator<T, class_object>;
friend class result_iterator<const T, class_object>;
@@ -206,167 +206,18 @@ namespace odb
result_impl_type* res_;
};
- // Input iterator requirements.
- //
- template <typename T>
- inline bool
- operator== (result_iterator<T, class_object> i,
- result_iterator<T, class_object> j)
- {
- return i.equal (j);
- }
-
- template <typename T>
- inline bool
- operator!= (result_iterator<T, class_object> i,
- result_iterator<T, class_object> j)
- {
- return !i.equal (j);
- }
-
//
//
template <typename T>
- class result<T, class_object>
+ class result_base<T, class_object>
{
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, class_object> iterator;
-
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
// T can be const T while object_type is always non-const.
//
typedef typename object_traits<T>::object_type object_type;
typedef result_impl<object_type, class_object> result_impl_type;
-
- public:
- result ()
- {
- }
-
- explicit
- result (details::shared_ptr<result_impl_type> 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;
- }
-
- // Conversion from result<T> to result<const T>.
- //
- template <typename UT>
- result (const result<UT, class_object>& r)
- //
- // If you get a compiler error pointing to the line below saying
- // that the impl_ member is inaccessible, then you are most likely
- // trying to perform an illegal result conversion, for example,
- // from result<const obj> to result<obj>.
- //
- : impl_ (r.impl_)
- {
- }
-
- template <typename UT>
- result&
- operator= (const result<UT, class_object>& r)
- {
- // If you get a compiler error pointing to the line below saying
- // that the impl_ member is inaccessible, then you are most likely
- // trying to perform an illegal result conversion, for example,
- // from result<const obj> to result<obj>.
- //
- if (impl_ != r.impl_)
- impl_ = r.impl_;
-
- return *this;
- }
-
- void
- swap (result& r)
- {
- // @@ add swap() to shared_ptr.
- //
- details::shared_ptr<result_impl_type> 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:
- friend class result<const T>;
-
- details::shared_ptr<result_impl_type> impl_;
};
}
diff --git a/odb/result.hxx b/odb/result.hxx
index a997615..1d4a199 100644
--- a/odb/result.hxx
+++ b/odb/result.hxx
@@ -8,19 +8,183 @@
#include <odb/pre.hxx>
+#include <cstddef> // std::ptrdiff_t, std::size_t
+
#include <odb/forward.hxx> // result
#include <odb/traits.hxx>
namespace odb
{
- template <typename T, class_kind kind = class_traits<T>::kind>
- class result;
+ template <typename T, class_kind kind>
+ class result_base;
+
+ template <typename T, class_kind kind>
+ class result_impl;
template <typename T, class_kind kind = class_traits<T>::kind>
class result_iterator;
+ // Input iterator requirements.
+ //
template <typename T, class_kind kind>
- class result_impl;
+ inline bool
+ operator== (result_iterator<T, kind> i, result_iterator<T, kind> j)
+ {
+ return i.equal (j);
+ }
+
+ template <typename T, class_kind kind>
+ inline bool
+ operator!= (result_iterator<T, kind> i, result_iterator<T, kind> j)
+ {
+ return !i.equal (j);
+ }
+
+ template <typename T>
+ class result: result_base<T, class_traits<T>::kind>
+ {
+ public:
+ static const class_kind kind = class_traits<T>::kind;
+
+ typedef result_base<T, kind> base;
+
+ typedef typename base::value_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, kind> iterator;
+
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ // T can be const T while result_impl's argument is always non-const.
+ //
+ typedef typename base::result_impl_type result_impl_type;
+
+ public:
+ result ()
+ {
+ }
+
+ explicit
+ result (details::shared_ptr<result_impl_type> impl)
+ : impl_ (impl)
+ {
+ }
+
+ // Copying or assignment of a result instance 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;
+ }
+
+ // Conversion from result<T> to result<const T>.
+ //
+ template <typename UT>
+ result (const result<UT>& r)
+ //
+ // If you get a compiler error pointing to the line below saying
+ // that the impl_ member is inaccessible, then you are most likely
+ // trying to perform an illegal result conversion, for example,
+ // from result<const obj> to result<obj>.
+ //
+ : impl_ (r.impl_)
+ {
+ }
+
+ template <typename UT>
+ result&
+ operator= (const result<UT>& r)
+ {
+ // If you get a compiler error pointing to the line below saying
+ // that the impl_ member is inaccessible, then you are most likely
+ // trying to perform an illegal result conversion, for example,
+ // from result<const obj> to result<obj>.
+ //
+ if (impl_ != r.impl_)
+ impl_ = r.impl_;
+
+ return *this;
+ }
+
+ void
+ swap (result& r)
+ {
+ // @@ add swap() to shared_ptr.
+ //
+ details::shared_ptr<result_impl_type> 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 row 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:
+ friend class result<const T>;
+
+ details::shared_ptr<result_impl_type> impl_;
+ };
namespace core
{
diff --git a/odb/view-result.hxx b/odb/view-result.hxx
index 25fd0f5..a3cebf8 100644
--- a/odb/view-result.hxx
+++ b/odb/view-result.hxx
@@ -27,8 +27,8 @@ namespace odb
~result_impl ();
protected:
- friend class result<T, class_view>;
- friend class result<const T, class_view>;
+ friend class result<T>;
+ friend class result<const T>;
friend class result_iterator<T, class_view>;
friend class result_iterator<const T, class_view>;
@@ -201,167 +201,18 @@ namespace odb
result_impl_type* res_;
};
- // Input iterator requirements.
- //
- template <typename T>
- inline bool
- operator== (result_iterator<T, class_view> i,
- result_iterator<T, class_view> j)
- {
- return i.equal (j);
- }
-
- template <typename T>
- inline bool
- operator!= (result_iterator<T, class_view> i,
- result_iterator<T, class_view> j)
- {
- return !i.equal (j);
- }
-
//
//
template <typename T>
- class result<T, class_view>
+ class result_base<T, class_view>
{
public:
typedef typename view_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, class_view> iterator;
-
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
// T can be const T while view_type is always non-const.
//
typedef typename view_traits<T>::view_type view_type;
typedef result_impl<view_type, class_view> result_impl_type;
-
- public:
- result ()
- {
- }
-
- explicit
- result (details::shared_ptr<result_impl_type> 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;
- }
-
- // Conversion from result<T> to result<const T>.
- //
- template <typename UT>
- result (const result<UT, class_view>& r)
- //
- // If you get a compiler error pointing to the line below saying
- // that the impl_ member is inaccessible, then you are most likely
- // trying to perform an illegal result conversion, for example,
- // from result<const obj> to result<obj>.
- //
- : impl_ (r.impl_)
- {
- }
-
- template <typename UT>
- result&
- operator= (const result<UT, class_view>& r)
- {
- // If you get a compiler error pointing to the line below saying
- // that the impl_ member is inaccessible, then you are most likely
- // trying to perform an illegal result conversion, for example,
- // from result<const obj> to result<obj>.
- //
- if (impl_ != r.impl_)
- impl_ = r.impl_;
-
- return *this;
- }
-
- void
- swap (result& r)
- {
- // @@ add swap() to shared_ptr.
- //
- details::shared_ptr<result_impl_type> 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 view 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:
- friend class result<const T>;
-
- details::shared_ptr<result_impl_type> impl_;
};
}