summaryrefslogtreecommitdiff
path: root/libodb/odb/lazy-ptr-impl.ixx
diff options
context:
space:
mode:
Diffstat (limited to 'libodb/odb/lazy-ptr-impl.ixx')
-rw-r--r--libodb/odb/lazy-ptr-impl.ixx397
1 files changed, 397 insertions, 0 deletions
diff --git a/libodb/odb/lazy-ptr-impl.ixx b/libodb/odb/lazy-ptr-impl.ixx
new file mode 100644
index 0000000..9ab0471
--- /dev/null
+++ b/libodb/odb/lazy-ptr-impl.ixx
@@ -0,0 +1,397 @@
+// file : odb/lazy-ptr-impl.ixx
+// license : GNU GPL v2; see accompanying LICENSE file
+
+namespace odb
+{
+ //
+ // lazy_ptr_base
+ //
+
+ inline lazy_ptr_base::
+ lazy_ptr_base ()
+ : id_ (0), db_ (0), loader_ (0), free_ (0), copy_ (0)
+ {
+ }
+
+ inline lazy_ptr_base::
+ lazy_ptr_base (const lazy_ptr_base& r)
+ : id_ (0), db_ (r.db_), loader_ (r.loader_),
+ free_ (r.free_), copy_ (r.copy_)
+ {
+ if (r.id_)
+ id_ = copy_ (r.id_);
+ }
+
+ inline lazy_ptr_base::
+ lazy_ptr_base (const lazy_ptr_impl_ref& r)
+ : id_ (r.id_), db_ (r.db_), loader_ (r.loader_),
+ free_ (r.free_), copy_ (r.copy_)
+ {
+ }
+
+#ifdef ODB_CXX11
+ inline lazy_ptr_base::
+ lazy_ptr_base (lazy_ptr_base&& r) noexcept
+ : id_ (r.id_), db_ (r.db_), loader_ (r.loader_),
+ free_ (r.free_), copy_ (r.copy_)
+ {
+ r.id_ = 0;
+ }
+#endif
+
+ inline void lazy_ptr_base::
+ reset_id ()
+ {
+ if (id_)
+ free_ (id_);
+
+ id_ = 0;
+ }
+
+ inline void lazy_ptr_base::
+ reset_ (database_type* db,
+ void* loader,
+ const void* id,
+ free_func free,
+ copy_func copy)
+ {
+ void* idc (id ? copy (id) : 0);
+
+ if (id_)
+ free_ (id_);
+
+ free_ = free;
+ copy_ = copy;
+
+ id_ = idc;
+ db_ = db;
+ loader_ = loader;
+ }
+
+ inline void lazy_ptr_base::
+ reset ()
+ {
+ reset_id ();
+ db_ = 0;
+ loader_ = 0;
+ }
+
+#ifdef ODB_CXX11
+ inline lazy_ptr_base& lazy_ptr_base::
+ operator= (lazy_ptr_base&& r) noexcept
+ {
+ if (id_ != r.id_)
+ {
+ reset_id ();
+ id_ = r.id_;
+ free_ = r.free_;
+ copy_ = r.copy_;
+
+ r.id_ = 0;
+ }
+
+ db_ = r.db_;
+ loader_ = r.loader_;
+ return *this;
+ }
+#endif
+
+ inline lazy_ptr_base& lazy_ptr_base::
+ operator= (const lazy_ptr_base& r)
+ {
+ if (id_ != r.id_)
+ reset_ (r.db_, r.loader_, r.id_, r.free_, r.copy_);
+ else
+ {
+ db_ = r.db_;
+ loader_ = r.loader_;
+ }
+
+ return *this;
+ }
+
+ inline lazy_ptr_base& lazy_ptr_base::
+ operator= (const lazy_ptr_impl_ref& r)
+ {
+ if (id_ != r.id_)
+ {
+ reset_id ();
+ id_ = r.id_;
+ free_ = r.free_;
+ copy_ = r.copy_;
+ }
+
+ db_ = r.db_;
+ loader_ = r.loader_;
+ return *this;
+ }
+
+ inline lazy_ptr_base::
+ ~lazy_ptr_base ()
+ {
+ if (id_)
+ free_ (id_);
+ }
+
+ inline void lazy_ptr_base::
+ swap (lazy_ptr_base& r)
+ {
+ void* id (id_);
+ database_type* db (db_);
+ void* l (loader_);
+ free_func f (free_);
+ copy_func c (copy_);
+
+ id_ = r.id_;
+ db_ = r.db_;
+ loader_ = r.loader_;
+ free_ = r.free_;
+ copy_ = r.copy_;
+
+ r.id_ = id;
+ r.db_ = db;
+ r.loader_ = l;
+ r.free_ = f;
+ r.copy_ = c;
+ }
+
+ inline lazy_ptr_base::database_type* lazy_ptr_base::
+ database () const
+ {
+ return db_;
+ }
+
+ inline lazy_ptr_base::
+ operator lazy_ptr_impl_ref ()
+ {
+ lazy_ptr_impl_ref r;
+ r.id_ = id_;
+ r.db_ = db_;
+ r.loader_ = loader_;
+ r.free_ = free_;
+ r.copy_ = copy_;
+ id_ = 0;
+ db_ = 0;
+ loader_ = 0;
+ return r;
+ }
+
+ //
+ // lazy_ptr_impl
+ //
+
+ template <typename T>
+ inline lazy_ptr_impl<T>::
+ lazy_ptr_impl ()
+ {
+ }
+
+ template <typename T>
+ template <typename DB, typename ID>
+ inline lazy_ptr_impl<T>::
+ lazy_ptr_impl (DB& db, const ID& id)
+ {
+ typedef typename object_traits<T>::id_type id_type;
+ typedef typename object_traits<T>::pointer_type pointer_type;
+ typedef pointer_type (*loader_type) (database_type&, const id_type&);
+
+ // Make sure that ID and T's object id types are the same
+ // (or implicit-convertible). If you get a compile error
+ // pointing here, then you most likely used a wrong object
+ // id argument in the constructor call.
+ //
+ const id_type& r (id);
+
+ // Compiler error pointing here? Perhaps db is not an
+ // odb::<database>::database instance?
+ //
+ database_type& bdb (db);
+
+ // For some reason GCC needs this statically-typed pointer in
+ // order to instantiate the functions.
+ //
+ loader_type ldr (&loader<T, DB>);
+
+ reset_ (&bdb,
+ reinterpret_cast<void*> (ldr),
+ &r,
+ &free<id_type>,
+ &copy<id_type>);
+ }
+
+ template <typename T>
+ inline lazy_ptr_impl<T>::
+ lazy_ptr_impl (const lazy_ptr_impl& r)
+ : lazy_ptr_base (r)
+ {
+ }
+
+ template <typename T>
+ template <typename Y>
+ inline lazy_ptr_impl<T>::
+ lazy_ptr_impl (const lazy_ptr_impl<Y>& r)
+ : lazy_ptr_base (r)
+ {
+ }
+
+ template <typename T>
+ inline lazy_ptr_impl<T>::
+ lazy_ptr_impl (const lazy_ptr_impl_ref& r)
+ : lazy_ptr_base (r)
+ {
+ }
+
+ template <typename T>
+ inline lazy_ptr_impl<T>& lazy_ptr_impl<T>::
+ operator= (const lazy_ptr_impl& r)
+ {
+ lazy_ptr_base& b (*this);
+ b = r;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename Y>
+ inline lazy_ptr_impl<T>& lazy_ptr_impl<T>::
+ operator= (const lazy_ptr_impl<Y>& r)
+ {
+ lazy_ptr_base& b (*this);
+ b = r;
+ return *this;
+ }
+
+ template <typename T>
+ inline lazy_ptr_impl<T>& lazy_ptr_impl<T>::
+ operator= (const lazy_ptr_impl_ref& r)
+ {
+ lazy_ptr_base& b (*this);
+ b = r;
+ return *this;
+ }
+
+#ifdef ODB_CXX11
+ template <typename T>
+ inline lazy_ptr_impl<T>::
+ lazy_ptr_impl (lazy_ptr_impl&& r) noexcept
+ : lazy_ptr_base (std::move (r))
+ {
+ }
+
+ template <typename T>
+ template <typename Y>
+ inline lazy_ptr_impl<T>::
+ lazy_ptr_impl (lazy_ptr_impl<Y>&& r)
+ : lazy_ptr_base (std::move (r))
+ {
+ }
+
+ template <typename T>
+ inline lazy_ptr_impl<T>& lazy_ptr_impl<T>::
+ operator= (lazy_ptr_impl&& r) noexcept
+ {
+ lazy_ptr_base& b (*this);
+ b = std::move (r);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename Y>
+ inline lazy_ptr_impl<T>& lazy_ptr_impl<T>::
+ operator= (lazy_ptr_impl<Y>&& r)
+ {
+ lazy_ptr_base& b (*this);
+ b = std::move (r);
+ return *this;
+ }
+#endif
+
+ template <typename T>
+ template <typename DB, typename ID>
+ inline void lazy_ptr_impl<T>::
+ reset (DB& db, const ID& id)
+ {
+ typedef typename object_traits<T>::id_type id_type;
+ typedef typename object_traits<T>::pointer_type pointer_type;
+ typedef pointer_type (*loader_type) (database_type&, const id_type&);
+
+ // Make sure that ID and T's object id types are the same
+ // (or implicit-convertible). If you get a compile error
+ // pointing here, then you most likely used a wrong object
+ // id argument in the constructor call.
+ //
+ const id_type& r (id);
+
+ // Compiler error pointing here? Perhaps db is not an
+ // odb::<database>::database instance?
+ //
+ database_type& bdb (db);
+
+ // For some reason GCC needs this statically-typed pointer in
+ // order to instantiate the functions.
+ //
+ loader_type ldr (&loader<T, DB>);
+
+ reset_ (&bdb,
+ reinterpret_cast<void*> (ldr),
+ &r,
+ &free<id_type>,
+ &copy<id_type>);
+ }
+
+ template <typename T>
+ template <typename DB>
+ inline void lazy_ptr_impl<T>::
+ reset_db (DB& db)
+ {
+ typedef typename object_traits<T>::id_type id_type;
+ typedef typename object_traits<T>::pointer_type pointer_type;
+ typedef pointer_type (*loader_type) (database_type&, const id_type&);
+
+ reset_id ();
+
+ // Compiler error pointing here? Perhaps db is not an
+ // odb::<database>::database instance?
+ //
+ db_ = &db;
+
+ // For some reason GCC needs this statically-typed pointer in
+ // order to instantiate the functions.
+ //
+ loader_type ldr (&loader<T, DB>);
+ loader_ = reinterpret_cast<void*> (ldr);
+ }
+
+ template <typename T>
+ template <typename ID>
+ inline void lazy_ptr_impl<T>::
+ reset_id (const ID& id)
+ {
+ typedef typename object_traits<T>::id_type id_type;
+
+ // Make sure that ID and T's object id types are the same
+ // (or implicit-convertible). If you get a compile error
+ // pointing here, then you most likely used a wrong object
+ // id argument in the constructor call.
+ //
+ const id_type& r (id);
+
+ reset_ (db_, loader_, &r, &free<id_type>, &copy<id_type>);
+ }
+
+ template <typename T>
+ template <typename O>
+ inline typename object_traits<O>::id_type lazy_ptr_impl<T>::
+ object_id () const
+ {
+ typedef typename object_traits<T>::id_type id_type;
+ const id_type& id (*static_cast<const id_type*> (id_));
+
+ // Make sure that O' and T's object id types are the same
+ // (or implicit-convertible). If you get a compile error
+ // pointing here, then you most likely used a wrong type
+ // as a template argument in the object_id() call.
+ //
+ const typename object_traits<O>::id_type& r (id);
+ return r;
+ }
+}