// file : odb/lazy-ptr.hxx // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_LAZY_PTR_HXX #define ODB_LAZY_PTR_HXX #include #include // std::auto_ptr, std::shared_ptr/weak_ptr #include // std::move #include // odb::database #include #include #include // ODB_CXX11 namespace odb { // Raw pointer lazy version. // template class lazy_ptr { // Pointer interface. // public: typedef T element_type; lazy_ptr (); template lazy_ptr (Y*); lazy_ptr (const lazy_ptr&); template lazy_ptr (const lazy_ptr&); lazy_ptr& operator= (const lazy_ptr&); template lazy_ptr& operator= (Y*); template lazy_ptr& operator= (const lazy_ptr&); void swap (lazy_ptr&); void reset (); template void reset (Y*); T& operator* () const; T* operator-> () const; T* get () const; typedef T* lazy_ptr::*unspecified_bool_type; operator unspecified_bool_type () const { return (p_ || i_) ? &lazy_ptr::p_ : 0; } // Lazy loading interface. // public: typedef odb::database database_type; // NULL loaded() // // true true NULL pointer to transient object // false true valid pointer to persistent object // true false unloaded pointer to persistent object // false false valid pointer to transient object // bool loaded () const; T* load () const; // Unload the pointer. For transient objects this function is // equivalent to reset(). // void unload () const; template lazy_ptr (database_type&, const ID&); template lazy_ptr (database_type&, Y*); template void reset (database_type&, const ID&); template void reset (database_type&, Y*); #ifdef ODB_CXX11 template #else template #endif typename object_traits::id_type object_id () const; database_type& database () const; // Helpers. // public: template bool equal (const lazy_ptr&) const; private: template friend class lazy_ptr; mutable T* p_; mutable lazy_ptr_impl i_; }; // operator< and operator<< are not provided. // template bool operator== (const lazy_ptr&, const lazy_ptr&); template bool operator!= (const lazy_ptr&, const lazy_ptr&); template void swap (lazy_ptr&, lazy_ptr&); // std::auto_ptr lazy version. // template struct lazy_auto_ptr_ref { explicit lazy_auto_ptr_ref (T*, const lazy_ptr_impl_ref&); T* p_; lazy_ptr_impl_ref i_; }; template class lazy_auto_ptr { // Standard auto_ptr interface. // public: typedef T element_type; explicit lazy_auto_ptr (T* = 0); lazy_auto_ptr (lazy_auto_ptr&); template lazy_auto_ptr (lazy_auto_ptr&); lazy_auto_ptr& operator= (lazy_auto_ptr&); template lazy_auto_ptr& operator= (lazy_auto_ptr&); T& operator* () const; T* operator-> () const; T* get () const; T* release (); void reset (T* = 0); lazy_auto_ptr (const lazy_auto_ptr_ref&); lazy_auto_ptr& operator= (const lazy_auto_ptr_ref&); template operator lazy_auto_ptr_ref (); template operator lazy_auto_ptr (); // Extension: conversion to bool. // public: typedef std::auto_ptr lazy_auto_ptr::*unspecified_bool_type; operator unspecified_bool_type () const { return (p_.get () != 0 || i_) ? &lazy_auto_ptr::p_ : 0; } // Initialization/assignment from auto_ptr. // public: template lazy_auto_ptr (std::auto_ptr&); lazy_auto_ptr (std::auto_ptr_ref); template lazy_auto_ptr& operator= (std::auto_ptr&); lazy_auto_ptr& operator= (std::auto_ptr_ref); // Lazy loading interface. // public: typedef odb::database database_type; // NULL loaded() // // true true NULL pointer to transient object // false true valid pointer to persistent object // true false unloaded pointer to persistent object // false false valid pointer to transient object // bool loaded () const; std::auto_ptr& load () const; // Unload the pointer. For transient objects this function is // equivalent to reset(). // void unload () const; template lazy_auto_ptr (database_type&, const ID&); lazy_auto_ptr (database_type&, T*); template lazy_auto_ptr (database_type&, std::auto_ptr&); template void reset (database_type&, const ID&); void reset (database_type&, T*); template void reset (database_type&, std::auto_ptr&); #ifdef ODB_CXX11 template #else template #endif typename object_traits::id_type object_id () const; database_type& database () const; private: template friend class lazy_auto_ptr; // Note that it is possible to have a situation where p_ is NULL, // i_.id is NULL and i_.db is not NULL. This will happen if the // auto_ptr reference returned by load() is transferred to another // pointer or reset. // mutable std::auto_ptr p_; mutable lazy_ptr_impl i_; }; #ifdef ODB_CXX11 // C++11 std::shared_ptr lazy version. // template class lazy_weak_ptr; template class lazy_shared_ptr { // The standard shared_ptr interface. // public: typedef T element_type; /*constexpr*/ lazy_shared_ptr () /*noexcept*/; /*constexpr*/ lazy_shared_ptr (std::nullptr_t) /*noexcept*/; template explicit lazy_shared_ptr (Y*); template lazy_shared_ptr (Y*, D); template lazy_shared_ptr (Y*, D, A); template lazy_shared_ptr (std::nullptr_t, D); template lazy_shared_ptr (std::nullptr_t, D, A); template lazy_shared_ptr (const lazy_shared_ptr&, T*) /*noexcept*/; lazy_shared_ptr (const lazy_shared_ptr&) /*noexcept*/; template lazy_shared_ptr (const lazy_shared_ptr&) /*noexcept*/; lazy_shared_ptr (lazy_shared_ptr&&) /*noexcept*/; template lazy_shared_ptr (lazy_shared_ptr&&) /*noexcept*/; template explicit lazy_shared_ptr (const lazy_weak_ptr&); template explicit lazy_shared_ptr (std::auto_ptr&&); template lazy_shared_ptr (std::unique_ptr&&); ~lazy_shared_ptr (); lazy_shared_ptr& operator= (const lazy_shared_ptr&) /*noexcept*/; template lazy_shared_ptr& operator= (const lazy_shared_ptr&) /*noexcept*/; lazy_shared_ptr& operator= (lazy_shared_ptr&&) /*noexcept*/; template lazy_shared_ptr& operator= (lazy_shared_ptr&&) /*noexcept*/; template lazy_shared_ptr& operator= (std::auto_ptr&&); template lazy_shared_ptr& operator= (std::unique_ptr&&); void swap (lazy_shared_ptr&) /*noexcept*/; void reset () /*noexcept*/; template void reset (Y*); template void reset (Y*, D); template void reset (Y*, D, A); T* get () const /*noexcept*/; T& operator* () const /*noexcept*/; T* operator-> () const /*noexcept*/; long use_count () const /*noexcept*/; bool unique () const /*noexcept*/; explicit operator bool () const /*noexcept*/; // owner_before () is not provded. // Initialization/assignment from shared_ptr and weak_ptr. // public: template lazy_shared_ptr (const std::shared_ptr&); template lazy_shared_ptr (std::shared_ptr&&); template explicit lazy_shared_ptr (const std::weak_ptr&); template lazy_shared_ptr& operator= (const std::shared_ptr&); template lazy_shared_ptr& operator= (std::shared_ptr&&); // Lazy loading interface. // public: typedef odb::database database_type; // NULL loaded() // // true true NULL pointer to transient object // false true valid pointer to persistent object // true false unloaded pointer to persistent object // false false valid pointer to transient object // bool loaded () const; std::shared_ptr load () const; // Unload the pointer. For transient objects this function is // equivalent to reset(). // void unload () const; template lazy_shared_ptr (database_type&, const ID&); template lazy_shared_ptr (database_type&, Y*); template lazy_shared_ptr (database_type&, Y*, D); template lazy_shared_ptr (database_type&, Y*, D, A); template lazy_shared_ptr (database_type&, std::auto_ptr&&); template lazy_shared_ptr (database_type&, const std::shared_ptr&); template lazy_shared_ptr (database_type&, std::shared_ptr&&); template lazy_shared_ptr (database_type&, const std::weak_ptr&); template void reset (database_type&, const ID&); template void reset (database_type&, Y*); template void reset (database_type&, Y*, D); template void reset (database_type&, Y*, D, A); template void reset (database_type&, std::auto_ptr&&); template void reset (database_type&, const std::shared_ptr&); template void reset (database_type&, std::shared_ptr&&); template typename object_traits::id_type object_id () const; database_type& database () const; // Helpers. // public: template bool equal (const lazy_shared_ptr&) const; private: template friend class lazy_shared_ptr; template friend class lazy_weak_ptr; mutable std::shared_ptr p_; mutable lazy_ptr_impl i_; }; template void swap (lazy_shared_ptr&, lazy_shared_ptr&) /*noexcept*/; template D* get_deleter (const lazy_shared_ptr&) /*noexcept*/; // operator< and operator<< are not provided. // template bool operator== (const lazy_shared_ptr&, const lazy_shared_ptr&) /*noexcept*/; template bool operator== (const lazy_shared_ptr&, std::nullptr_t) /*noexcept*/; template bool operator== (std::nullptr_t, const lazy_shared_ptr&) /*noexcept*/; template bool operator!= (const lazy_shared_ptr&, const lazy_shared_ptr&) /*noexcept*/; template bool operator!= (const lazy_shared_ptr&, std::nullptr_t) /*noexcept*/; template bool operator!= (std::nullptr_t, const lazy_shared_ptr&) /*noexcept*/; // C++11 std::weak_ptr lazy version. // template class lazy_weak_ptr { // The standard weak_ptr interface. // public: typedef T element_type; /*constexpr*/ lazy_weak_ptr () /*noexcept*/; template lazy_weak_ptr (const lazy_shared_ptr&) /*noexcept*/; lazy_weak_ptr (const lazy_weak_ptr&) /*noexcept*/; template lazy_weak_ptr (const lazy_weak_ptr&) /*noexcept*/; ~lazy_weak_ptr (); lazy_weak_ptr& operator= (const lazy_weak_ptr&) /*noexcept*/; template lazy_weak_ptr& operator= (const lazy_weak_ptr&) /*noexcept*/; template lazy_weak_ptr& operator= (const lazy_shared_ptr&) /*noexcept*/; void swap (lazy_weak_ptr&) /*noexcept*/; void reset () /*noexcept*/; long use_count () const /*noexcept*/; bool expired () const /*noexcept*/; lazy_shared_ptr lock () const /*noexcept*/; // owner_before () is not provded. // Initialization/assignment from shared_ptr and weak_ptr. // public: template lazy_weak_ptr (const std::weak_ptr&); template lazy_weak_ptr (const std::shared_ptr&); template lazy_weak_ptr& operator= (const std::weak_ptr&); template lazy_weak_ptr& operator= (const std::shared_ptr&); // Lazy loading interface. // public: typedef odb::database database_type; // expired() loaded() // // true true expired pointer to transient object // false true valid pointer to persistent object // true false expired pointer to persistent object // false false valid pointer to transient object // bool loaded () const; // Performs both lock and load. // std::shared_ptr load () const; // Unload the pointer. For transient objects this function is // equivalent to reset(). // void unload () const; template lazy_weak_ptr (database_type&, const ID&); template lazy_weak_ptr (database_type&, const std::shared_ptr&); template lazy_weak_ptr (database_type&, const std::weak_ptr&); template void reset (database_type&, const ID&); template void reset (database_type&, const std::shared_ptr&); template void reset (database_type&, const std::weak_ptr&); // The object_id() function can only be called when the object is // persistent, or: expired() XOR loaded() (can use != for XOR). // template typename object_traits::id_type object_id () const; database_type& database () const; private: template friend class lazy_shared_ptr; template friend class lazy_weak_ptr; mutable std::weak_ptr p_; mutable lazy_ptr_impl i_; }; // operator< is not provided. // template void swap (lazy_weak_ptr&, lazy_weak_ptr&); #endif // ODB_CXX11 namespace core { using odb::lazy_ptr; using odb::lazy_auto_ptr; #ifdef ODB_CXX11 using odb::lazy_shared_ptr; using odb::lazy_weak_ptr; #endif } } #include #include #include #include #endif // ODB_LAZY_PTR_HXX