diff options
Diffstat (limited to 'libodb/odb/lazy-ptr-impl.ixx')
-rw-r--r-- | libodb/odb/lazy-ptr-impl.ixx | 397 |
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>, + ©<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>, + ©<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>, ©<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; + } +} |