aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-11-15 17:46:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-11-15 17:46:28 +0200
commit30b664c0561cc9f6d2bd24f7bce9b6c57fb52320 (patch)
tree743ce4a41249c8586e81a001cf147bedfbdf9a85
parent93392ca601a0cab8517a4ca8d163df4b41dd3e49 (diff)
Add support for custom object pointers
New option: --default-pointer. New object pragma specifier: pointer.
-rw-r--r--odb/forward.hxx7
-rw-r--r--odb/pointer-traits.hxx6
-rw-r--r--odb/result.hxx23
-rw-r--r--odb/result.txx14
-rw-r--r--odb/traits.hxx35
5 files changed, 43 insertions, 42 deletions
diff --git a/odb/forward.hxx b/odb/forward.hxx
index bd6cbcb..dbd3628 100644
--- a/odb/forward.hxx
+++ b/odb/forward.hxx
@@ -19,13 +19,10 @@ namespace odb
template <typename T>
class object_traits;
- template <typename T>
- class object_memory;
-
- template <typename T>
+ template <typename T, typename P>
class object_factory;
- template <typename P>
+ template <typename T, typename P>
class pointer_factory;
template <typename T>
diff --git a/odb/pointer-traits.hxx b/odb/pointer-traits.hxx
index 18162e4..4c94709 100644
--- a/odb/pointer-traits.hxx
+++ b/odb/pointer-traits.hxx
@@ -25,13 +25,13 @@ namespace odb
nop_guard () {}
explicit
- nop_guard (P) {}
+ nop_guard (const P&) {}
void
release () {}
void
- reset (P) {}
+ reset (const P&) {}
};
// Default implementation that should work for any sensible smart
@@ -69,7 +69,7 @@ namespace odb
static bool
null_ptr (const pointer& p)
{
- return get_ptr () == 0;
+ return get_ptr (p) == 0;
}
public:
diff --git a/odb/result.hxx b/odb/result.hxx
index ff9f057..cf924c3 100644
--- a/odb/result.hxx
+++ b/odb/result.hxx
@@ -40,8 +40,19 @@ namespace odb
typedef typename traits::pointer_type pointer_type;
typedef typename traits::pointer_traits pointer_traits;
- pointer_type
- current (bool release);
+ // To make this work with all kinds of pointers (naked, 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 ();
+ }
bool
end () const
@@ -100,7 +111,7 @@ namespace odb
reference
operator* () const
{
- return pointer_traits::get_ref (res_->current (false));
+ return pointer_traits::get_ref (res_->current ());
}
// Our value_type is already a pointer so return it instead of
@@ -110,7 +121,7 @@ namespace odb
pointer
operator-> () const
{
- return pointer_traits::get_ptr (res_->current (false));
+ return pointer_traits::get_ptr (res_->current ());
}
result_iterator&
@@ -133,7 +144,9 @@ namespace odb
typename object_traits<T>::pointer_type
load ()
{
- return res_->current (true);
+ typename object_traits<T>::pointer_type r (res_->current ());
+ res_->release ();
+ return r;
}
void
diff --git a/odb/result.txx b/odb/result.txx
index e58af1f..3068890 100644
--- a/odb/result.txx
+++ b/odb/result.txx
@@ -12,8 +12,8 @@ namespace odb
}
template <typename T>
- typename result_impl<T>::pointer_type result_impl<T>::
- current (bool release)
+ typename result_impl<T>::pointer_type& result_impl<T>::
+ current ()
{
if (pointer_traits::null_ptr (current_) && !end_)
{
@@ -21,14 +21,6 @@ namespace odb
current (pointer_traits::get_ref (current_));
}
- pointer_type r (current_);
-
- if (release)
- {
- current_ = pointer_type ();
- guard_.release ();
- }
-
- return r;
+ return current_;
}
}
diff --git a/odb/traits.hxx b/odb/traits.hxx
index 318d88b..bc25dcb 100644
--- a/odb/traits.hxx
+++ b/odb/traits.hxx
@@ -16,8 +16,7 @@ namespace odb
// template <typename T>
// class access::object_traits;
//
- // Specializations should inherit from object_memory, object_factory
- // and define the following members:
+ // Specializations should define the following members:
//
// id_type - object id (primary key) type
// id_type id (const T&) - get object id
@@ -30,39 +29,35 @@ namespace odb
//
//
- template <typename T>
- class access::object_memory
- {
- public:
- typedef T* pointer_type;
- };
-
- template <typename T>
+ template <typename T, typename P>
class access::object_factory
{
public:
- static typename object_memory<T>::pointer_type
+ typedef T object_type;
+ typedef P pointer_type;
+
+ static P
create ()
{
// By default use pointer-specific construction.
//
- return
- pointer_factory<typename object_memory<T>::pointer_type>::create ();
+ return pointer_factory<T, P>::create ();
}
};
- template <typename P>
+ template <typename T, typename P>
class access::pointer_factory
{
public:
- typedef typename pointer_traits<P>::type object_type;
+ typedef T object_type;
+ typedef P pointer_type;
static P
create ()
{
- void* v (pointer_traits<P>::allocate (sizeof (object_type)));
+ void* v (pointer_traits<P>::allocate (sizeof (T)));
mem_guard g (v);
- P p (new (v) object_type);
+ P p (new (v) T);
g.release ();
return p;
}
@@ -77,8 +72,12 @@ namespace odb
};
template <typename T>
- struct object_traits: access::object_traits<T>
+ struct object_traits: access::object_traits<T>,
+ access::object_factory<T, typename access::object_traits<T>::pointer_type>
{
+ typedef typename access::object_traits<T>::object_type object_type;
+ typedef typename access::object_traits<T>::pointer_type pointer_type;
+
typedef
odb::pointer_traits<typename access::object_traits<T>::pointer_type>
pointer_traits;