From ec355c48c49074bebeb597f6e5dcedfeb9d52fae Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 9 Dec 2010 10:36:15 +0200 Subject: Add lazy pointer support Built-in support is provided for raw, auto, and tr1 shared/weak pointers. New test: common/lazy-ptr. --- odb/lazy-ptr-impl.ixx | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 odb/lazy-ptr-impl.ixx (limited to 'odb/lazy-ptr-impl.ixx') diff --git a/odb/lazy-ptr-impl.ixx b/odb/lazy-ptr-impl.ixx new file mode 100644 index 0000000..8acd11c --- /dev/null +++ b/odb/lazy-ptr-impl.ixx @@ -0,0 +1,268 @@ +// file : odb/lazy-ptr-impl.ixx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + // + // lazy_ptr_base + // + + inline lazy_ptr_base:: + lazy_ptr_base () + : id_ (0), db_ (0) + { + } + + inline lazy_ptr_base:: + lazy_ptr_base (const lazy_ptr_base& r) + : id_ (0), db_ (r.db_), 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_), free_ (r.free_), copy_ (r.copy_) + { + } + + inline lazy_ptr_base& lazy_ptr_base:: + operator= (const lazy_ptr_base& r) + { + if (id_ != r.id_) + reset_ (r.db_, r.id_, r.free_, r.copy_); + else + db_ = r.db_; + + 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_; + return *this; + } + + inline lazy_ptr_base:: + ~lazy_ptr_base () + { + if (id_) + free_ (id_); + } + + inline void lazy_ptr_base:: + reset () + { + reset_id (); + db_ = 0; + } + + inline void lazy_ptr_base:: + reset (database_type& db) + { + reset_id (); + db_ = &db; + } + + inline void lazy_ptr_base:: + reset_id () + { + if (id_) + free_ (id_); + + id_ = 0; + } + + inline void lazy_ptr_base:: + reset_ (database_type* db, 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; + } + + inline void lazy_ptr_base:: + swap (lazy_ptr_base& r) + { + void* id (id_); + database_type* db (db_); + free_func f (free_); + copy_func c (copy_); + + id_ = r.id_; + db_ = r.db_; + free_ = r.free_; + copy_ = r.copy_; + + r.id_ = id; + r.db_ = db; + 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.free_ = free_; + r.copy_ = copy_; + id_ = 0; + db_ = 0; + return r; + } + + // + // lazy_ptr_impl + // + + template + inline lazy_ptr_impl:: + lazy_ptr_impl () + { + } + + template + template + inline lazy_ptr_impl:: + lazy_ptr_impl (database_type& db, const ID& id) + { + typedef typename object_traits::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, &r, &free, ©); + } + + template + inline lazy_ptr_impl:: + lazy_ptr_impl (const lazy_ptr_impl& r) + : lazy_ptr_base (r) + { + } + + template + template + inline lazy_ptr_impl:: + lazy_ptr_impl (const lazy_ptr_impl& r) + : lazy_ptr_base (r) + { + } + + template + inline lazy_ptr_impl:: + lazy_ptr_impl (const lazy_ptr_impl_ref& r) + : lazy_ptr_base (r) + { + } + + template + inline lazy_ptr_impl& lazy_ptr_impl:: + operator= (const lazy_ptr_impl& r) + { + lazy_ptr_base& b (*this); + b = r; + return *this; + } + + template + template + inline lazy_ptr_impl& lazy_ptr_impl:: + operator= (const lazy_ptr_impl& r) + { + lazy_ptr_base& b (*this); + b = r; + return *this; + } + + template + inline lazy_ptr_impl& lazy_ptr_impl:: + operator= (const lazy_ptr_impl_ref& r) + { + lazy_ptr_base& b (*this); + b = r; + return *this; + } + + template + template + inline void lazy_ptr_impl:: + reset (database_type& db, const ID& id) + { + typedef typename object_traits::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, &r, &free, ©); + } + + template + template + inline void lazy_ptr_impl:: + reset_id (const ID& id) + { + typedef typename object_traits::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_, &r, &free, ©); + } + + template + template + inline typename object_traits::id_type lazy_ptr_impl:: + object_id () const + { + typedef typename object_traits::id_type id_type; + const id_type& id (*static_cast (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::id_type& r (id); + return r; + } +} -- cgit v1.1