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.ixx | 471 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 471 insertions(+) create mode 100644 odb/lazy-ptr.ixx (limited to 'odb/lazy-ptr.ixx') diff --git a/odb/lazy-ptr.ixx b/odb/lazy-ptr.ixx new file mode 100644 index 0000000..3c27d20 --- /dev/null +++ b/odb/lazy-ptr.ixx @@ -0,0 +1,471 @@ +// file : odb/lazy-ptr.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 + // + + template + inline lazy_ptr:: + lazy_ptr (): p_ (0) {} + + template + template + inline lazy_ptr:: + lazy_ptr (Y* p): p_ (p) {} + + template + inline lazy_ptr:: + lazy_ptr (const lazy_ptr& r): p_ (r.p_), i_ (r.i_) {} + + template + template + inline lazy_ptr:: + lazy_ptr (const lazy_ptr& r): p_ (r.p_), i_ (r.i_) {} + + template + inline lazy_ptr& lazy_ptr:: + operator= (const lazy_ptr& r) + { + p_ = r.p_; + i_ = r.i_; + return *this; + } + + template + template + inline lazy_ptr& lazy_ptr:: + operator= (Y* r) + { + p_ = r; + i_.reset (); + return *this; + } + + template + template + inline lazy_ptr& lazy_ptr:: + operator= (const lazy_ptr& r) + { + p_ = r.p_; + i_ = r.i_; + return *this; + } + + template + inline void lazy_ptr:: + swap (lazy_ptr& b) + { + T* p (p_); + p_ = b.p_; + b.p_ = p; + i_.swap (b.i_); + } + + template + inline void lazy_ptr:: + reset () + { + p_ = 0; + i_.reset (); + } + + template + template + inline void lazy_ptr:: + reset (Y* p) + { + p_ = p; + i_.reset (); + } + + template + inline T& lazy_ptr:: + operator* () const + { + return *p_; + } + + template + inline T* lazy_ptr:: + operator-> () const + { + return p_; + } + + template + inline T* lazy_ptr:: + get () const + { + return p_; + } + + template + inline bool lazy_ptr:: + loaded () const + { + return p_ || !i_; + } + + template + inline T* lazy_ptr:: + load () const + { + if (!loaded ()) + p_ = i_.template load (true); // Reset id. + + return p_; + } + + template + inline void lazy_ptr:: + unload () const + { + typedef typename object_traits::object_type object_type; + + if (p_) + { + if (i_.database () != 0) + i_.reset_id (object_traits::id (*p_)); + + p_ = 0; + } + } + + template + template + inline lazy_ptr:: + lazy_ptr (database_type& db, const ID& id): p_ (0), i_ (db, id) {} + + template + template + inline lazy_ptr:: + lazy_ptr (database_type& db, Y* r) + : p_ (r) + { + if (p_) + i_.reset (db); + } + + template + template + inline void lazy_ptr:: + reset (database_type& db, const ID& id) + { + p_ = 0; + i_.reset (db, id); + } + + template + template + inline void lazy_ptr:: + reset (database_type& db, Y* r) + { + p_ = r; + + if (p_) + i_.reset (db); + else + i_.reset (); + } + + template + template + inline typename object_traits::id_type lazy_ptr:: + object_id () const + { + typedef typename object_traits::object_type object_type; + + return p_ ? object_traits::id (*p_) : i_.object_id (); + } + + template + inline typename lazy_ptr::database_type& lazy_ptr:: + database () const + { + return *i_.database (); + } + + template + inline bool + operator== (const lazy_ptr& a, const lazy_ptr& b) + { + return a.equal (b); + } + + template + inline bool + operator!= (const lazy_ptr& a, const lazy_ptr& b) + { + return !a.equal (b); + } + + template + inline void + swap (lazy_ptr& a, lazy_ptr& b) + { + a.swap (b); + } + + // + // lazy_auto_ptr_ref + // + + template + inline lazy_auto_ptr_ref:: + lazy_auto_ptr_ref (T* p, const lazy_ptr_impl_ref& i): p_ (p), i_ (i) {} + + // + // lazy_auto_ptr + // + + template + inline lazy_auto_ptr:: + lazy_auto_ptr (T* p): p_ (p) {} + + template + inline lazy_auto_ptr:: + lazy_auto_ptr (lazy_auto_ptr& r) + : p_ (r.p_), i_ (static_cast (r.i_)) + { + } + + template + template + inline lazy_auto_ptr:: + lazy_auto_ptr (lazy_auto_ptr& r) + : p_ (r.p_), i_ (static_cast (r.i_)) + { + } + + template + inline lazy_auto_ptr& lazy_auto_ptr:: + operator= (lazy_auto_ptr& r) + { + p_ = r.p_; + i_ = static_cast (r.i_); + return *this; + } + + template + template + inline lazy_auto_ptr& lazy_auto_ptr:: + operator= (lazy_auto_ptr& r) + { + p_ = r.p_; + i_ = static_cast (r.i_); + return *this; + } + + template + inline T& lazy_auto_ptr:: + operator* () const + { + return *p_; + } + + template + inline T* lazy_auto_ptr:: + operator-> () const + { + return p_.operator-> (); + } + + template + inline T* lazy_auto_ptr:: + get () const + { + return p_.get (); + } + + template + inline T* lazy_auto_ptr:: + release () + { + i_.reset (); + return p_.release (); + } + + template + inline void lazy_auto_ptr:: + reset (T* p) + { + i_.reset (); + p_.reset (p); + } + + template + inline lazy_auto_ptr:: + lazy_auto_ptr (const lazy_auto_ptr_ref& r): p_ (r.p_), i_ (r.i_) {} + + template + inline lazy_auto_ptr& lazy_auto_ptr:: + operator= (const lazy_auto_ptr_ref& r) + { + if (p_.get () != r.p_) + p_.reset (r.p_); + + i_ = r.i_; + return *this; + } + + template + template + inline lazy_auto_ptr:: + operator lazy_auto_ptr_ref () + { + return lazy_auto_ptr_ref (p_.release (), i_); + } + + template + template + inline lazy_auto_ptr:: + operator lazy_auto_ptr () + { + return lazy_auto_ptr (*this); + } + + template + template + inline lazy_auto_ptr:: + lazy_auto_ptr (std::auto_ptr& r): p_ (r) {} + + template + inline lazy_auto_ptr:: + lazy_auto_ptr (std::auto_ptr_ref r): p_ (r) {} + + template + template + inline lazy_auto_ptr& lazy_auto_ptr:: + operator= (std::auto_ptr& r) + { + p_ = r; + i_.reset (); + return *this; + } + + template + inline lazy_auto_ptr& lazy_auto_ptr:: + operator= (std::auto_ptr_ref r) + { + p_ = r; + i_.reset (); + return *this; + } + + template + inline bool lazy_auto_ptr:: + loaded () const + { + return p_.get () != 0 || !i_; + } + + template + inline std::auto_ptr& lazy_auto_ptr:: + load () const + { + if (!loaded ()) + { + std::auto_ptr tmp (i_.template load (true)); // Reset id. + p_ = tmp; + } + + return p_; + } + + template + inline void lazy_auto_ptr:: + unload () const + { + typedef typename object_traits::object_type object_type; + + if (p_.get () != 0) + { + if (i_.database () != 0) + i_.reset_id (object_traits::id (*p_)); + + p_.reset (); + } + } + + template + template + inline lazy_auto_ptr:: + lazy_auto_ptr (database_type& db, const ID& id): i_ (db, id) {} + + template + inline lazy_auto_ptr:: + lazy_auto_ptr (database_type& db, T* p) + : p_ (p) + { + if (p) + i_.reset (db); + } + + template + template + inline lazy_auto_ptr:: + lazy_auto_ptr (database_type& db, std::auto_ptr& p) + : p_ (p) + { + if (p) + i_.reset (db); + } + + template + template + inline void lazy_auto_ptr:: + reset (database_type& db, const ID& id) + { + p_.reset (); + i_.reset (db, id); + } + + template + inline void lazy_auto_ptr:: + reset (database_type& db, T* p) + { + p_.reset (p); + + if (p) + i_.reset (db); + else + i_.reset (); + } + + template + template + inline void lazy_auto_ptr:: + reset (database_type& db, std::auto_ptr& p) + { + p_ = p; + + if (p_.get () != 0) + i_.reset (db); + else + i_.reset (); + } + + template + template + inline typename object_traits::id_type lazy_auto_ptr:: + object_id () const + { + typedef typename object_traits::object_type object_type; + + return p_.get () != 0 + ? object_traits::id (*p_) + : i_.object_id (); + } + + template + inline typename lazy_auto_ptr::database_type& lazy_auto_ptr:: + database () const + { + return *i_.database (); + } +} -- cgit v1.1