| cache-traits.hxx | | cache-traits.hxx | |
| | | | |
| skipping to change at line 14 | | skipping to change at line 14 | |
| | | | |
| #ifndef ODB_CACHE_TRAITS_HXX | | #ifndef ODB_CACHE_TRAITS_HXX | |
| #define ODB_CACHE_TRAITS_HXX | | #define ODB_CACHE_TRAITS_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <odb/traits.hxx> | | #include <odb/traits.hxx> | |
| #include <odb/forward.hxx> | | #include <odb/forward.hxx> | |
| #include <odb/session.hxx> | | #include <odb/session.hxx> | |
| #include <odb/pointer-traits.hxx> | | #include <odb/pointer-traits.hxx> | |
|
| | | #include <odb/no-op-cache-traits.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
|
| // Caching traits for objects passed by pointer. | | // pointer_cache_traits | |
| // | | // | |
|
| template <typename P, typename ID, pointer_kind kind> | | // Caching traits for objects passed by pointer. P should be the canonica | |
| struct pointer_cache_traits_impl; | | l | |
| | | // pointer (non-const). | |
| template <typename P> | | // | |
| struct pointer_cache_traits: pointer_cache_traits_impl< | | template <typename P, pointer_kind pk> | |
| P, | | | |
| typename object_traits<typename pointer_traits<P>::element_type>::id_ty | | | |
| pe, | | | |
| pointer_traits<P>::kind> | | | |
| { | | | |
| }; | | | |
| | | | |
| template <typename P, typename ID, pointer_kind kind> | | | |
| struct pointer_cache_traits_impl | | struct pointer_cache_traits_impl | |
| { | | { | |
| typedef P pointer_type; | | typedef P pointer_type; | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
|
| typedef typename pointer_traits::element_type element_type; | | typedef typename pointer_traits::element_type object_type; | |
| | | typedef typename object_traits<object_type>::id_type id_type; | |
| // element_type can be const while object_type is always non-const. | | | |
| // | | | |
| typedef typename object_traits<element_type>::object_type object_type; | | | |
| typedef typename object_traits<element_type>::id_type id_type; | | | |
| typedef session::object_position<object_type> position_type; | | typedef session::object_position<object_type> position_type; | |
| | | | |
| struct insert_guard | | struct insert_guard | |
| { | | { | |
|
| | | insert_guard () {} | |
| insert_guard (const position_type& pos): pos_ (pos) {} | | insert_guard (const position_type& pos): pos_ (pos) {} | |
| ~insert_guard () {erase (pos_);} | | ~insert_guard () {erase (pos_);} | |
| | | | |
| position_type | | position_type | |
| position () const {return pos_;} | | position () const {return pos_;} | |
| | | | |
| void | | void | |
| release () {pos_.map_ = 0;} | | release () {pos_.map_ = 0;} | |
| | | | |
|
| | | // Note: doesn't call erase() on the old position (assumes not set). | |
| | | // | |
| | | void | |
| | | reset (const position_type& pos) {pos_ = pos;} | |
| | | | |
| private: | | private: | |
| position_type pos_; | | position_type pos_; | |
| }; | | }; | |
| | | | |
| // We need the insert() overload with explicit id to handle self- | | // We need the insert() overload with explicit id to handle self- | |
| // references. In such cases the object is not yet loaded and the | | // references. In such cases the object is not yet loaded and the | |
| // id member does not contain the correct id. | | // id member does not contain the correct id. | |
| // | | // | |
| // Qualify the database type to resolve a phony ambiguity in VC 10. | | // Qualify the database type to resolve a phony ambiguity in VC 10. | |
| // | | // | |
| static position_type | | static position_type | |
| insert (odb::database& db, const id_type& id, const pointer_type& p) | | insert (odb::database& db, const id_type& id, const pointer_type& p) | |
| { | | { | |
| if (session::has_current ()) | | if (session::has_current ()) | |
|
| { | | return session::current ().insert<object_type> (db, id, p); | |
| // Cast away constness if any. | | | |
| // | | | |
| return session::current ().insert<object_type> ( | | | |
| db, id, pointer_traits::cast (p)); | | | |
| } | | | |
| else | | else | |
| return position_type (); | | return position_type (); | |
| } | | } | |
| | | | |
| static position_type | | static position_type | |
| insert (odb::database& db, const pointer_type& p) | | insert (odb::database& db, const pointer_type& p) | |
| { | | { | |
| const id_type& id ( | | const id_type& id ( | |
| object_traits<object_type>::id ( | | object_traits<object_type>::id ( | |
| pointer_traits::get_ref (p))); | | pointer_traits::get_ref (p))); | |
| | | | |
| skipping to change at line 112 | | skipping to change at line 102 | |
| } | | } | |
| | | | |
| static void | | static void | |
| erase (const position_type& p) | | erase (const position_type& p) | |
| { | | { | |
| if (p.map_ != 0) | | if (p.map_ != 0) | |
| session::current ().erase<object_type> (p); | | session::current ().erase<object_type> (p); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| template <typename P, pointer_kind kind> | | | |
| struct pointer_cache_traits_impl<P, void, kind> | | | |
| { | | | |
| typedef P pointer_type; | | | |
| struct position_type {}; | | | |
| | | | |
| static position_type | | | |
| insert (odb::database&, const pointer_type&) | | | |
| { | | | |
| return position_type (); | | | |
| } | | | |
| }; | | | |
| | | | |
| // Unique pointers don't work with the object cache. | | // Unique pointers don't work with the object cache. | |
| // | | // | |
|
| template <typename P, typename ID> | | | |
| struct pointer_cache_traits_impl<P, ID, pk_unique> | | | |
| { | | | |
| typedef P pointer_type; | | | |
| typedef typename pointer_traits<pointer_type>::element_type element_typ | | | |
| e; | | | |
| typedef typename object_traits<element_type>::id_type id_type; | | | |
| struct position_type {}; | | | |
| | | | |
| struct insert_guard | | | |
| { | | | |
| insert_guard (const position_type&) {} | | | |
| | | | |
| position_type | | | |
| position () const {return position_type ();} | | | |
| | | | |
| void | | | |
| release () {} | | | |
| }; | | | |
| | | | |
| static position_type | | | |
| insert (odb::database&, const id_type&, const pointer_type&) | | | |
| { | | | |
| return position_type (); | | | |
| } | | | |
| | | | |
| static position_type | | | |
| insert (odb::database&, const pointer_type&) | | | |
| { | | | |
| return position_type (); | | | |
| } | | | |
| | | | |
| static pointer_type | | | |
| find (odb::database&, const id_type&) { return pointer_type (); } | | | |
| | | | |
| static void | | | |
| erase (odb::database&, const id_type&) {} | | | |
| | | | |
| static void | | | |
| erase (const position_type&) {} | | | |
| }; | | | |
| | | | |
| template <typename P> | | template <typename P> | |
|
| struct pointer_cache_traits_impl<P, void, pk_unique> | | struct pointer_cache_traits_impl<P, pk_unique>: | |
| { | | no_op_pointer_cache_traits<P> {}; | |
| typedef P pointer_type; | | | |
| struct position_type {}; | | | |
| | | | |
|
| static position_type | | template <typename P> | |
| insert (odb::database&, const pointer_type&) | | struct pointer_cache_traits: | |
| { | | pointer_cache_traits_impl<P, pointer_traits<P>::kind> {}; | |
| return position_type (); | | | |
| } | | | |
| }; | | | |
| | | | |
|
| // Caching traits for objects passed by reference. Only if the object | | // reference_cache_traits | |
| // pointer kind is raw do we add the object to the session. | | // | |
| | | // Caching traits for objects passed by reference. T should be the | |
| | | // canonical object type (non-const). Only if the object pointer | |
| | | // kind is raw do we add the object to the session. | |
| // | | // | |
|
| template <typename T, typename ID, pointer_kind kind> | | template <typename T, pointer_kind pk> | |
| struct reference_cache_traits_impl; | | struct reference_cache_traits_impl: no_op_reference_cache_traits<T> {}; | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| struct reference_cache_traits: reference_cache_traits_impl< | | struct reference_cache_traits_impl<T, pk_raw> | |
| T, | | | |
| typename object_traits<T>::id_type, | | | |
| pointer_traits<typename object_traits<T>::pointer_type>::kind> | | | |
| { | | | |
| }; | | | |
| | | | |
| template <typename T, typename ID, pointer_kind kind> | | | |
| struct reference_cache_traits_impl | | | |
| { | | { | |
|
| typedef T element_type; | | typedef T object_type; | |
| typedef typename object_traits<element_type>::pointer_type pointer_type | | typedef typename object_traits<object_type>::pointer_type pointer_type; | |
| ; | | typedef typename object_traits<object_type>::id_type id_type; | |
| typedef typename object_traits<element_type>::id_type id_type; | | | |
| | | | |
| typedef | | | |
| typename pointer_cache_traits<pointer_type>::position_type | | | |
| position_type; | | | |
| | | | |
| struct insert_guard | | | |
| { | | | |
| insert_guard (const position_type&) {} | | | |
| | | | |
|
| position_type | | typedef pointer_cache_traits<pointer_type> pointer_traits; | |
| position () const {return position_type ();} | | typedef typename pointer_traits::position_type position_type; | |
| | | typedef typename pointer_traits::insert_guard insert_guard; | |
| void | | | |
| release () {} | | | |
| }; | | | |
| | | | |
| static position_type | | static position_type | |
|
| insert (odb::database&, const id_type&, element_type&) | | insert (odb::database& db, const id_type& id, object_type& obj) | |
| { | | | |
| return position_type (); | | | |
| } | | | |
| | | | |
| static position_type | | | |
| insert (odb::database&, element_type&) | | | |
| { | | | |
| return position_type (); | | | |
| } | | | |
| }; | | | |
| | | | |
| template <typename T, pointer_kind kind> | | | |
| struct reference_cache_traits_impl<T, void, kind> | | | |
| { | | | |
| typedef T element_type; | | | |
| struct position_type {}; | | | |
| | | | |
| static position_type | | | |
| insert (odb::database&, element_type&) | | | |
| { | | | |
| return position_type (); | | | |
| } | | | |
| }; | | | |
| | | | |
| template <typename T, typename ID> | | | |
| struct reference_cache_traits_impl<T, ID, pk_raw> | | | |
| { | | | |
| typedef T element_type; | | | |
| typedef typename object_traits<element_type>::pointer_type pointer_type | | | |
| ; | | | |
| typedef typename object_traits<element_type>::id_type id_type; | | | |
| | | | |
| typedef | | | |
| typename pointer_cache_traits<pointer_type>::position_type | | | |
| position_type; | | | |
| | | | |
| typedef | | | |
| typename pointer_cache_traits<pointer_type>::insert_guard | | | |
| insert_guard; | | | |
| | | | |
| static position_type | | | |
| insert (odb::database& db, const id_type& id, element_type& obj) | | | |
| { | | { | |
| pointer_type p (&obj); | | pointer_type p (&obj); | |
|
| return pointer_cache_traits<pointer_type>::insert (db, id, p); | | return pointer_traits::insert (db, id, p); | |
| } | | } | |
| | | | |
| static position_type | | static position_type | |
|
| insert (odb::database& db, element_type& obj) | | insert (odb::database& db, object_type& obj) | |
| { | | { | |
| pointer_type p (&obj); | | pointer_type p (&obj); | |
|
| return pointer_cache_traits<pointer_type>::insert (db, p); | | return pointer_traits::insert (db, p); | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| struct reference_cache_traits_impl<T, void, pk_raw> | | struct reference_cache_traits: | |
| { | | reference_cache_traits_impl< | |
| typedef T element_type; | | T, pointer_traits<typename object_traits<T>::pointer_type>::kind> {}; | |
| struct position_type {}; | | | |
| | | | |
| static position_type | | | |
| insert (odb::database&, element_type&) | | | |
| { | | | |
| return position_type (); | | | |
| } | | | |
| }; | | | |
| } | | } | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_CACHE_TRAITS_HXX | | #endif // ODB_CACHE_TRAITS_HXX | |
| | | | |
End of changes. 21 change blocks. |
| 179 lines changed or deleted | | 42 lines changed or added | |
|
| database.ixx | | database.ixx | |
| // file : odb/database.ixx | | // file : odb/database.ixx | |
| // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
|
| #include <cstring> // std::string | | #include <cstring> // std::strlen() | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| inline database:: | | inline database:: | |
| database () | | database () | |
| : tracer_ (0) | | : tracer_ (0) | |
| { | | { | |
| } | | } | |
| | | | |
| inline connection_ptr database:: | | inline connection_ptr database:: | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 69 | |
| | | | |
| // The passed pointer should be the same or implicit-convertible | | // The passed pointer should be the same or implicit-convertible | |
| // to the object pointer. This way we make sure the object pointer | | // to the object pointer. This way we make sure the object pointer | |
| // does not assume ownership of the passed object. | | // does not assume ownership of the passed object. | |
| // | | // | |
| const object_pointer& pobj (p); | | const object_pointer& pobj (p); | |
| | | | |
| return persist_<T> (pobj); | | return persist_<T> (pobj); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline typename object_traits<T>::id_type database:: | |
| | | persist (const P<T, A1>& p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | return persist_<T> (pobj); | |
| | | } | |
| | | | |
| template <typename T, template <typename> class P> | | template <typename T, template <typename> class P> | |
| inline typename object_traits<T>::id_type database:: | | inline typename object_traits<T>::id_type database:: | |
| persist (P<T>& p) | | persist (P<T>& p) | |
| { | | { | |
| const P<T>& cr (p); | | const P<T>& cr (p); | |
| return persist<T, P> (cr); | | return persist<T, P> (cr); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline typename object_traits<T>::id_type database:: | |
| | | persist (P<T, A1>& p) | |
| | | { | |
| | | const P<T, A1>& cr (p); | |
| | | return persist<T, A1, P> (cr); | |
| | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline typename object_traits<T>::id_type database:: | | inline typename object_traits<T>::id_type database:: | |
| persist (const typename object_traits<T>::pointer_type& pobj) | | persist (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
| return persist_<T> (pobj); | | return persist_<T> (pobj); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| | | inline typename object_traits<T>::pointer_type database:: | |
| | | find (const typename object_traits<T>::id_type& id) | |
| | | { | |
| | | // T is always object_type. | |
| | | // | |
| | | | |
| | | // Compiler error pointing here? Perhaps the object doesn't have the | |
| | | // default constructor? | |
| | | // | |
| | | return object_traits<T>::find (*this, id); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline bool database:: | |
| | | find (const typename object_traits<T>::id_type& id, T& obj) | |
| | | { | |
| | | // T is always object_type. | |
| | | // | |
| | | return object_traits<T>::find (*this, id, obj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| inline void database:: | | inline void database:: | |
| reload (T* p) | | reload (T* p) | |
| { | | { | |
| reload<T> (*p); | | reload<T> (*p); | |
| } | | } | |
| | | | |
| template <typename T, template <typename> class P> | | template <typename T, template <typename> class P> | |
| inline void database:: | | inline void database:: | |
| reload (const P<T>& p) | | reload (const P<T>& p) | |
| { | | { | |
| reload (odb::pointer_traits< P<T> >::get_ref (p)); | | reload (odb::pointer_traits< P<T> >::get_ref (p)); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline void database:: | |
| | | reload (const P<T, A1>& p) | |
| | | { | |
| | | reload (odb::pointer_traits< P<T, A1> >::get_ref (p)); | |
| | | } | |
| | | | |
| template <typename T, template <typename> class P> | | template <typename T, template <typename> class P> | |
| inline void database:: | | inline void database:: | |
| reload (P<T>& p) | | reload (P<T>& p) | |
| { | | { | |
| reload (odb::pointer_traits< P<T> >::get_ref (p)); | | reload (odb::pointer_traits< P<T> >::get_ref (p)); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline void database:: | |
| | | reload (P<T, A1>& p) | |
| | | { | |
| | | reload (odb::pointer_traits< P<T, A1> >::get_ref (p)); | |
| | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline void database:: | | inline void database:: | |
| reload (const typename object_traits<T>::pointer_type& pobj) | | reload (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
| typedef typename object_traits<T>::pointer_type pointer_type; | | typedef typename object_traits<T>::pointer_type pointer_type; | |
| | | | |
| reload (odb::pointer_traits<pointer_type>::get_ref (pobj)); | | reload (odb::pointer_traits<pointer_type>::get_ref (pobj)); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| | | | |
| skipping to change at line 144 | | skipping to change at line 203 | |
| | | | |
| // The passed pointer should be the same or implicit-convertible | | // The passed pointer should be the same or implicit-convertible | |
| // to the object pointer. This way we make sure the object pointer | | // to the object pointer. This way we make sure the object pointer | |
| // does not assume ownership of the passed object. | | // does not assume ownership of the passed object. | |
| // | | // | |
| const object_pointer& pobj (p); | | const object_pointer& pobj (p); | |
| | | | |
| update_<T> (pobj); | | update_<T> (pobj); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline void database:: | |
| | | update (const P<T, A1>& p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | update_<T> (pobj); | |
| | | } | |
| | | | |
| template <typename T, template <typename> class P> | | template <typename T, template <typename> class P> | |
| inline void database:: | | inline void database:: | |
| update (P<T>& p) | | update (P<T>& p) | |
| { | | { | |
| const P<T>& cr (p); | | const P<T>& cr (p); | |
| update<T, P> (cr); | | update<T, P> (cr); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline void database:: | |
| | | update (P<T, A1>& p) | |
| | | { | |
| | | const P<T, A1>& cr (p); | |
| | | update<T, A1, P> (cr); | |
| | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline void database:: | | inline void database:: | |
| update (const typename object_traits<T>::pointer_type& pobj) | | update (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
| update_<T> (pobj); | | update_<T> (pobj); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline void database:: | | inline void database:: | |
|
| | | update (T& obj) | |
| | | { | |
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| | | // Compiler error pointing here? Perhaps the object is readonly or | |
| | | // doesn't have an object id? Such objects cannot be updated. | |
| | | // | |
| | | object_traits::update (*this, obj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| | | update_ (const typename object_traits<T>::pointer_type& pobj) | |
| | | { | |
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename odb::object_traits<T>::object_type object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| | | typedef typename odb::object_traits<T>::pointer_type pointer_type; | |
| | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| | | | |
| | | T& obj (pointer_traits::get_ref (pobj)); | |
| | | | |
| | | // Compiler error pointing here? Perhaps the object is readonly or | |
| | | // doesn't have an object id? Such objects cannot be updated. | |
| | | // | |
| | | object_traits::update (*this, obj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| erase (T* p) | | erase (T* p) | |
| { | | { | |
| typedef typename object_traits<T>::pointer_type object_pointer; | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| // The passed pointer should be the same or implicit-convertible | | // The passed pointer should be the same or implicit-convertible | |
| // to the object pointer. This way we make sure the object pointer | | // to the object pointer. This way we make sure the object pointer | |
| // does not assume ownership of the passed object. | | // does not assume ownership of the passed object. | |
| // | | // | |
| const object_pointer& pobj (p); | | const object_pointer& pobj (p); | |
| | | | |
| | | | |
| skipping to change at line 189 | | skipping to change at line 306 | |
| | | | |
| // The passed pointer should be the same or implicit-convertible | | // The passed pointer should be the same or implicit-convertible | |
| // to the object pointer. This way we make sure the object pointer | | // to the object pointer. This way we make sure the object pointer | |
| // does not assume ownership of the passed object. | | // does not assume ownership of the passed object. | |
| // | | // | |
| const object_pointer& pobj (p); | | const object_pointer& pobj (p); | |
| | | | |
| erase_<T> (pobj); | | erase_<T> (pobj); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline void database:: | |
| | | erase (const P<T, A1>& p) | |
| | | { | |
| | | typedef typename object_traits<T>::pointer_type object_pointer; | |
| | | | |
| | | // The passed pointer should be the same or implicit-convertible | |
| | | // to the object pointer. This way we make sure the object pointer | |
| | | // does not assume ownership of the passed object. | |
| | | // | |
| | | const object_pointer& pobj (p); | |
| | | | |
| | | erase_<T> (pobj); | |
| | | } | |
| | | | |
| template <typename T, template <typename> class P> | | template <typename T, template <typename> class P> | |
| inline void database:: | | inline void database:: | |
| erase (P<T>& p) | | erase (P<T>& p) | |
| { | | { | |
| const P<T>& cr (p); | | const P<T>& cr (p); | |
| erase<T, P> (cr); | | erase<T, P> (cr); | |
| } | | } | |
| | | | |
|
| | | template <typename T, typename A1, template <typename, typename> class P> | |
| | | inline void database:: | |
| | | erase (P<T, A1>& p) | |
| | | { | |
| | | const P<T, A1>& cr (p); | |
| | | erase<T, A1, P> (cr); | |
| | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline void database:: | | inline void database:: | |
| erase (const typename object_traits<T>::pointer_type& pobj) | | erase (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
| erase_<T> (pobj); | | erase_<T> (pobj); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline void database:: | | inline void database:: | |
| erase_ (const typename object_traits<T>::pointer_type& pobj) | | erase_ (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
| typedef typename object_traits<T>::pointer_type pointer_type; | | typedef typename object_traits<T>::pointer_type pointer_type; | |
| typedef pointer_traits<pointer_type> pointer_traits; | | typedef pointer_traits<pointer_type> pointer_traits; | |
| | | | |
| erase<T> (pointer_traits::get_ref (pobj)); | | erase<T> (pointer_traits::get_ref (pobj)); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| | | inline void database:: | |
| | | erase (const typename object_traits<T>::id_type& id) | |
| | | { | |
| | | // T is always object_type. | |
| | | // | |
| | | object_traits<T>::erase (*this, id); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | inline void database:: | |
| | | erase (T& obj) | |
| | | { | |
| | | // T can be const T while object_type will always be T. | |
| | | // | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | object_traits<object_type>::erase (*this, obj); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| inline unsigned long long database:: | | inline unsigned long long database:: | |
| erase_query () | | erase_query () | |
| { | | { | |
| // T is always object_type. | | // T is always object_type. | |
| // | | // | |
| return erase_query<T> (odb::query<T> ()); | | return erase_query<T> (odb::query<T> ()); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline unsigned long long database:: | | inline unsigned long long database:: | |
| | | | |
| skipping to change at line 242 | | skipping to change at line 402 | |
| template <typename T> | | template <typename T> | |
| inline unsigned long long database:: | | inline unsigned long long database:: | |
| erase_query (const std::string& q) | | erase_query (const std::string& q) | |
| { | | { | |
| // T is always object_type. | | // T is always object_type. | |
| // | | // | |
| return erase_query<T> (odb::query<T> (q)); | | return erase_query<T> (odb::query<T> (q)); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| | | inline unsigned long long database:: | |
| | | erase_query (const odb::query<T>& q) | |
| | | { | |
| | | // T is always object_type. | |
| | | // | |
| | | return object_traits<T>::erase_query (*this, q); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| inline result<T> database:: | | inline result<T> database:: | |
| query (bool cache) | | query (bool cache) | |
| { | | { | |
| return query<T> (odb::query<T> (), cache); | | return query<T> (odb::query<T> (), cache); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| inline result<T> database:: | | inline result<T> database:: | |
| query (const char* q, bool cache) | | query (const char* q, bool cache) | |
| { | | { | |
| | | | |
End of changes. 13 change blocks. |
| 1 lines changed or deleted | | 170 lines changed or added | |
|
| database.txx | | database.txx | |
| // file : odb/database.txx | | // file : odb/database.txx | |
| // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| #include <odb/transaction.hxx> | | #include <odb/transaction.hxx> | |
|
| #include <odb/session.hxx> | | #include <odb/no-op-cache-traits.hxx> | |
| #include <odb/callback.hxx> | | | |
| #include <odb/cache-traits.hxx> | | | |
| #include <odb/pointer-traits.hxx> | | #include <odb/pointer-traits.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::id_type database:: | | typename object_traits<T>::id_type database:: | |
| persist (T& obj) | | persist (T& obj) | |
| { | | { | |
| // T can be const T while object_type will always be T. | | // T can be const T while object_type will always be T. | |
| // | | // | |
| typedef typename odb::object_traits<T>::object_type object_type; | | typedef typename odb::object_traits<T>::object_type object_type; | |
| typedef odb::object_traits<object_type> object_traits; | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
|
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| object_traits::callback (*this, obj, callback_event::pre_persist); | | | |
| object_traits::persist (*this, obj); | | object_traits::persist (*this, obj); | |
|
| object_traits::callback (*this, obj, callback_event::post_persist); | | | |
| | | | |
|
| reference_cache_traits<T>::insert (*this, obj); | | object_traits::reference_cache_traits::insert ( | |
| | | *this, reference_cache_type<T>::convert (obj)); | |
| | | | |
| return object_traits::id (obj); | | return object_traits::id (obj); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::id_type database:: | | typename object_traits<T>::id_type database:: | |
| persist_ (const typename object_traits<T>::pointer_type& pobj) | | persist_ (const typename object_traits<T>::pointer_type& pobj) | |
| { | | { | |
| // T can be const T while object_type will always be T. | | // T can be const T while object_type will always be T. | |
| // | | // | |
| typedef typename odb::object_traits<T>::object_type object_type; | | typedef typename odb::object_traits<T>::object_type object_type; | |
| typedef odb::object_traits<object_type> object_traits; | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| typedef typename odb::object_traits<T>::pointer_type pointer_type; | | typedef typename odb::object_traits<T>::pointer_type pointer_type; | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | typedef odb::pointer_traits<pointer_type> pointer_traits; | |
| | | | |
|
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| T& obj (pointer_traits::get_ref (pobj)); | | T& obj (pointer_traits::get_ref (pobj)); | |
|
| | | | |
| object_traits::callback (*this, obj, callback_event::pre_persist); | | | |
| object_traits::persist (*this, obj); | | object_traits::persist (*this, obj); | |
|
| object_traits::callback (*this, obj, callback_event::post_persist); | | | |
| | | | |
|
| pointer_cache_traits<pointer_type>::insert (*this, pobj); | | // Get the canonical object pointer and insert it into object cache. | |
| | | // | |
| | | object_traits::pointer_cache_traits::insert ( | |
| | | *this, pointer_cache_type<pointer_type>::convert (pobj)); | |
| | | | |
| return object_traits::id (obj); | | return object_traits::id (obj); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_traits<T>::pointer_type database:: | | typename object_traits<T>::pointer_type database:: | |
| load (const typename object_traits<T>::id_type& id) | | load (const typename object_traits<T>::id_type& id) | |
| { | | { | |
| // T is always object_type. | | // T is always object_type. | |
| // | | // | |
| | | | |
| skipping to change at line 94 | | skipping to change at line 85 | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void database:: | | void database:: | |
| reload (T& obj) | | reload (T& obj) | |
| { | | { | |
| // T should be object_type (cannot be const). | | // T should be object_type (cannot be const). | |
| // | | // | |
| typedef odb::object_traits<T> object_traits; | | typedef odb::object_traits<T> object_traits; | |
| | | | |
|
| | | // We don't need to check for transaction here; | |
| | | // object_traits::reload () does this. | |
| | | | |
| if (!object_traits::reload (*this, obj)) | | if (!object_traits::reload (*this, obj)) | |
| throw object_not_persistent (); | | throw object_not_persistent (); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| typename object_traits<T>::pointer_type database:: | | | |
| find (const typename object_traits<T>::id_type& id) | | | |
| { | | | |
| // T is always object_type. | | | |
| // | | | |
| typedef odb::object_traits<T> object_traits; | | | |
| typedef typename object_traits::pointer_type pointer_type; | | | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | | |
| | | | |
| // First check the session. | | | |
| // | | | |
| { | | | |
| pointer_type p ( | | | |
| pointer_cache_traits<pointer_type>::find (*this, id)); | | | |
| | | | |
| if (!pointer_traits::null_ptr (p)) | | | |
| return p; | | | |
| } | | | |
| | | | |
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| // Compiler error pointing here? Perhaps the object doesn't have the | | | |
| // default constructor? | | | |
| // | | | |
| return pointer_type (object_traits::find (*this, id)); | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| bool database:: | | | |
| find (const typename object_traits<T>::id_type& id, T& obj) | | | |
| { | | | |
| // T is always object_type. | | | |
| // | | | |
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| return object_traits<T>::find (*this, id, obj); | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| void database:: | | | |
| update (T& obj) | | | |
| { | | | |
| // T can be const T while object_type will always be T. | | | |
| // | | | |
| typedef typename odb::object_traits<T>::object_type object_type; | | | |
| typedef odb::object_traits<object_type> object_traits; | | | |
| | | | |
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| object_traits::callback (*this, obj,callback_event::pre_update); | | | |
| | | | |
| // Compiler error pointing here? Perhaps the object is readonly or | | | |
| // doesn't have an object id? Such objects cannot be updated. | | | |
| // | | | |
| object_traits::update (*this, obj); | | | |
| | | | |
| object_traits::callback (*this, obj, callback_event::post_update); | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| void database:: | | | |
| update_ (const typename object_traits<T>::pointer_type& pobj) | | | |
| { | | | |
| // T can be const T while object_type will always be T. | | | |
| // | | | |
| typedef typename odb::object_traits<T>::object_type object_type; | | | |
| typedef odb::object_traits<object_type> object_traits; | | | |
| | | | |
| typedef typename odb::object_traits<T>::pointer_type pointer_type; | | | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | | |
| | | | |
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| T& obj (pointer_traits::get_ref (pobj)); | | | |
| | | | |
| object_traits::callback (*this, obj, callback_event::pre_update); | | | |
| | | | |
| // Compiler error pointing here? Perhaps the object is readonly or | | | |
| // doesn't have an object id? Such objects cannot be updated. | | | |
| // | | | |
| object_traits::update (*this, obj); | | | |
| | | | |
| object_traits::callback (*this, obj, callback_event::post_update); | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| void database:: | | | |
| erase (const typename object_traits<T>::id_type& id) | | | |
| { | | | |
| // T is always object_type. | | | |
| // | | | |
| typedef odb::object_traits<T> object_traits; | | | |
| typedef typename object_traits::pointer_type pointer_type; | | | |
| | | | |
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| object_traits::erase (*this, id); | | | |
| pointer_cache_traits<pointer_type>::erase (*this, id); | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| void database:: | | | |
| erase (T& obj) | | | |
| { | | | |
| // T can be const T while object_type will always be T. | | | |
| // | | | |
| typedef typename odb::object_traits<T>::object_type object_type; | | | |
| typedef odb::object_traits<object_type> object_traits; | | | |
| typedef typename object_traits::pointer_type pointer_type; | | | |
| | | | |
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| typename object_traits::id_type id (object_traits::id (obj)); | | | |
| | | | |
| object_traits::callback (*this, obj, callback_event::pre_erase); | | | |
| object_traits::erase (*this, obj); | | | |
| pointer_cache_traits<pointer_type>::erase (*this, id); | | | |
| object_traits::callback (*this, obj, callback_event::post_erase); | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| unsigned long long database:: | | | |
| erase_query (const odb::query<T>& q) | | | |
| { | | | |
| // T is always object_type. | | | |
| // | | | |
| if (!transaction::has_current ()) | | | |
| throw not_in_transaction (); | | | |
| | | | |
| return object_traits<T>::erase_query (*this, q); | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| struct database::query_<T, class_object> | | struct database::query_<T, class_object> | |
| { | | { | |
| static result<T> | | static result<T> | |
| call (database& db, const odb::query<T>& q) | | call (database& db, const odb::query<T>& q) | |
| { | | { | |
| return object_traits<T>::query (db, q); | | return object_traits<T>::query (db, q); | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| | | | |
End of changes. 10 change blocks. |
| 155 lines changed or deleted | | 10 lines changed or added | |
|
| lazy-ptr.hxx | | lazy-ptr.hxx | |
| // file : odb/lazy-ptr.hxx | | // file : odb/lazy-ptr.hxx | |
| // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_LAZY_PTR_HXX | | #ifndef ODB_LAZY_PTR_HXX | |
| #define ODB_LAZY_PTR_HXX | | #define ODB_LAZY_PTR_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
|
| #include <memory> // std::auto_ptr | | #include <memory> // std::auto_ptr, std::shared_ptr/weak_ptr | |
| | | #include <utility> // std::move | |
| | | | |
|
| #include <odb/forward.hxx> // odb::database | | #include <odb/forward.hxx> // odb::database | |
| #include <odb/traits.hxx> | | #include <odb/traits.hxx> | |
| #include <odb/lazy-ptr-impl.hxx> | | #include <odb/lazy-ptr-impl.hxx> | |
|
| | | #include <odb/details/config.hxx> // ODB_CXX11 | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
|
| | | // Raw pointer lazy version. | |
| | | // | |
| template <class T> | | template <class T> | |
| class lazy_ptr | | class lazy_ptr | |
| { | | { | |
| // Pointer interface. | | // Pointer interface. | |
| // | | // | |
| public: | | public: | |
| typedef T element_type; | | typedef T element_type; | |
| | | | |
| lazy_ptr (); | | lazy_ptr (); | |
| template <class Y> lazy_ptr (Y*); | | template <class Y> lazy_ptr (Y*); | |
| | | | |
| skipping to change at line 77 | | skipping to change at line 81 | |
| // equivalent to reset(). | | // equivalent to reset(). | |
| // | | // | |
| void unload () const; | | void unload () const; | |
| | | | |
| template <class ID> lazy_ptr (database_type&, const ID&); | | template <class ID> lazy_ptr (database_type&, const ID&); | |
| template <class Y> lazy_ptr (database_type&, Y*); | | template <class Y> lazy_ptr (database_type&, Y*); | |
| | | | |
| template <class ID> void reset (database_type&, const ID&); | | template <class ID> void reset (database_type&, const ID&); | |
| template <class Y> void reset (database_type&, Y*); | | template <class Y> void reset (database_type&, Y*); | |
| | | | |
|
| | | #ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT | |
| | | template <class O = T> | |
| | | #else | |
| template <class O /* = T */> | | template <class O /* = T */> | |
|
| | | #endif | |
| typename object_traits<O>::id_type object_id () const; | | typename object_traits<O>::id_type object_id () const; | |
| | | | |
| database_type& database () const; | | database_type& database () const; | |
| | | | |
| // Helpers. | | // Helpers. | |
| // | | // | |
| public: | | public: | |
| template <class Y> bool equal (const lazy_ptr<Y>&) const; | | template <class Y> bool equal (const lazy_ptr<Y>&) const; | |
| | | | |
| private: | | private: | |
| template <class Y> friend class lazy_ptr; | | template <class Y> friend class lazy_ptr; | |
| | | | |
| mutable T* p_; | | mutable T* p_; | |
| mutable lazy_ptr_impl<T> i_; | | mutable lazy_ptr_impl<T> i_; | |
| }; | | }; | |
| | | | |
| // operator< and operator<< are not provided. | | // operator< and operator<< are not provided. | |
| // | | // | |
|
| template<class T, class Y> | | template <class T, class Y> | |
| bool operator== (const lazy_ptr<T>&, const lazy_ptr<Y>&); | | bool operator== (const lazy_ptr<T>&, const lazy_ptr<Y>&); | |
| | | | |
|
| template<class T, class Y> | | template <class T, class Y> | |
| bool operator!= (const lazy_ptr<T>&, const lazy_ptr<Y>&); | | bool operator!= (const lazy_ptr<T>&, const lazy_ptr<Y>&); | |
| | | | |
|
| template<class T> void swap (lazy_ptr<T>&, lazy_ptr<T>&); | | template <class T> void swap (lazy_ptr<T>&, lazy_ptr<T>&); | |
| | | | |
|
| // | | // std::auto_ptr lazy version. | |
| // | | // | |
| template <class T> | | template <class T> | |
| struct lazy_auto_ptr_ref | | struct lazy_auto_ptr_ref | |
| { | | { | |
| explicit lazy_auto_ptr_ref (T*, const lazy_ptr_impl_ref&); | | explicit lazy_auto_ptr_ref (T*, const lazy_ptr_impl_ref&); | |
| | | | |
| T* p_; | | T* p_; | |
| lazy_ptr_impl_ref i_; | | lazy_ptr_impl_ref i_; | |
| }; | | }; | |
| | | | |
| template <class T> | | template <class T> | |
| class lazy_auto_ptr | | class lazy_auto_ptr | |
| { | | { | |
| // Standard auto_ptr interface. | | // Standard auto_ptr interface. | |
| // | | // | |
| public: | | public: | |
| typedef T element_type; | | typedef T element_type; | |
| | | | |
| explicit lazy_auto_ptr (T* = 0); | | explicit lazy_auto_ptr (T* = 0); | |
| lazy_auto_ptr (lazy_auto_ptr&); | | lazy_auto_ptr (lazy_auto_ptr&); | |
|
| template<class Y> lazy_auto_ptr (lazy_auto_ptr<Y>&); | | template <class Y> lazy_auto_ptr (lazy_auto_ptr<Y>&); | |
| | | | |
| lazy_auto_ptr& operator= (lazy_auto_ptr&); | | lazy_auto_ptr& operator= (lazy_auto_ptr&); | |
|
| template<class Y> lazy_auto_ptr& operator= (lazy_auto_ptr<Y>&); | | template <class Y> lazy_auto_ptr& operator= (lazy_auto_ptr<Y>&); | |
| | | | |
| T& operator* () const; | | T& operator* () const; | |
| T* operator-> () const; | | T* operator-> () const; | |
| T* get () const; | | T* get () const; | |
| T* release (); | | T* release (); | |
| void reset (T* = 0); | | void reset (T* = 0); | |
| | | | |
| lazy_auto_ptr (const lazy_auto_ptr_ref<T>&); | | lazy_auto_ptr (const lazy_auto_ptr_ref<T>&); | |
| lazy_auto_ptr& operator= (const lazy_auto_ptr_ref<T>&); | | lazy_auto_ptr& operator= (const lazy_auto_ptr_ref<T>&); | |
|
| template<class Y> operator lazy_auto_ptr_ref<Y> (); | | template <class Y> operator lazy_auto_ptr_ref<Y> (); | |
| template<class Y> operator lazy_auto_ptr<Y> (); | | template <class Y> operator lazy_auto_ptr<Y> (); | |
| | | | |
| // Extension: conversion to bool. | | // Extension: conversion to bool. | |
| // | | // | |
| public: | | public: | |
| typedef std::auto_ptr<T> lazy_auto_ptr::*unspecified_bool_type; | | typedef std::auto_ptr<T> lazy_auto_ptr::*unspecified_bool_type; | |
| operator unspecified_bool_type () const | | operator unspecified_bool_type () const | |
| { | | { | |
| return (p_.get () != 0 || i_) ? &lazy_auto_ptr::p_ : 0; | | return (p_.get () != 0 || i_) ? &lazy_auto_ptr::p_ : 0; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 188 | | skipping to change at line 196 | |
| void unload () const; | | void unload () const; | |
| | | | |
| template <class ID> lazy_auto_ptr (database_type&, const ID&); | | template <class ID> lazy_auto_ptr (database_type&, const ID&); | |
| lazy_auto_ptr (database_type&, T*); | | lazy_auto_ptr (database_type&, T*); | |
| template <class Y> lazy_auto_ptr (database_type&, std::auto_ptr<Y>&); | | template <class Y> lazy_auto_ptr (database_type&, std::auto_ptr<Y>&); | |
| | | | |
| template <class ID> void reset (database_type&, const ID&); | | template <class ID> void reset (database_type&, const ID&); | |
| void reset (database_type&, T*); | | void reset (database_type&, T*); | |
| template <class Y> void reset (database_type&, std::auto_ptr<Y>&); | | template <class Y> void reset (database_type&, std::auto_ptr<Y>&); | |
| | | | |
|
| | | #ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT | |
| | | template <class O = T> | |
| | | #else | |
| template <class O /* = T */> | | template <class O /* = T */> | |
|
| | | #endif | |
| typename object_traits<O>::id_type object_id () const; | | typename object_traits<O>::id_type object_id () const; | |
| | | | |
| database_type& database () const; | | database_type& database () const; | |
| | | | |
| private: | | private: | |
| template <class Y> friend class lazy_auto_ptr; | | template <class Y> friend class lazy_auto_ptr; | |
| | | | |
| // Note that it is possible to have a situation where p_ is NULL, | | // 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 | | // 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 | | // auto_ptr reference returned by load() is transferred to another | |
| // pointer or reset. | | // pointer or reset. | |
| // | | // | |
| mutable std::auto_ptr<T> p_; | | mutable std::auto_ptr<T> p_; | |
| mutable lazy_ptr_impl<T> i_; | | mutable lazy_ptr_impl<T> i_; | |
| }; | | }; | |
| | | | |
|
| | | #ifdef ODB_CXX11 | |
| | | | |
| | | // C++11 std::unique_ptr lazy version. | |
| | | // | |
| | | template <class T, class D = std::default_delete<T>> | |
| | | class lazy_unique_ptr | |
| | | { | |
| | | // Standard lazy_unique_ptr interface. | |
| | | // | |
| | | public: | |
| | | typedef T* pointer; // For now assume it is T*. | |
| | | typedef T element_type; | |
| | | typedef D deleter_type; | |
| | | | |
| | | /*constexpr*/ lazy_unique_ptr () /*noexcept*/; | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | /*constexpr*/ lazy_unique_ptr (std::nullptr_t) /*noexcept*/; | |
| | | #endif | |
| | | explicit lazy_unique_ptr (pointer) /*noexcept*/; | |
| | | | |
| | | // For now assume D is non-reference. | |
| | | // | |
| | | lazy_unique_ptr (pointer, const deleter_type&) /*noexcept*/; | |
| | | lazy_unique_ptr (pointer, deleter_type&&) /*noexcept*/; | |
| | | | |
| | | lazy_unique_ptr (lazy_unique_ptr&&) /*noexcept*/; | |
| | | template <class T1, class D1> lazy_unique_ptr (lazy_unique_ptr<T1, D1>& | |
| | | &) /*noexcept*/; | |
| | | template <class T1> lazy_unique_ptr (std::auto_ptr<T1>&&) /*noexcept*/; | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | lazy_unique_ptr& operator= (std::nullptr_t) /*noexcept*/; | |
| | | #endif | |
| | | lazy_unique_ptr& operator= (lazy_unique_ptr&&) /*noexcept*/; | |
| | | template <class T1, class D1> lazy_unique_ptr& operator= (lazy_unique_p | |
| | | tr<T1, D1>&&) /*noexcept*/; | |
| | | | |
| | | T& operator* () const; | |
| | | pointer operator-> () const /*noexcept*/; | |
| | | pointer get () const /*noexcept*/; | |
| | | #ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR | |
| | | explicit operator bool() const /*noexcept*/; | |
| | | #else | |
| | | typedef std::unique_ptr<T, D> lazy_unique_ptr::*unspecified_bool_type; | |
| | | operator unspecified_bool_type () const | |
| | | { | |
| | | return (p_ || i_) ? &lazy_unique_ptr::p_ : 0; | |
| | | } | |
| | | #endif | |
| | | | |
| | | pointer release () /*noexcept*/; | |
| | | void reset (pointer = pointer ()) /*noexcept*/; | |
| | | void swap (lazy_unique_ptr&) /*noexcept*/; | |
| | | | |
| | | deleter_type& get_deleter () /*noexcept*/; | |
| | | const deleter_type& get_deleter () const /*noexcept*/; | |
| | | | |
| | | #ifdef ODB_CXX11_DELETED_FUNCTION | |
| | | lazy_unique_ptr (const lazy_unique_ptr&) = delete; | |
| | | lazy_unique_ptr& operator= (const lazy_unique_ptr&) = delete; | |
| | | #else | |
| | | private: | |
| | | lazy_unique_ptr (const lazy_unique_ptr&); | |
| | | lazy_unique_ptr& operator= (const lazy_unique_ptr&); | |
| | | #endif | |
| | | | |
| | | // Initialization/assignment from unique_ptr. | |
| | | // | |
| | | public: | |
| | | template <class T1, class D1> lazy_unique_ptr (std::unique_ptr<T1, D1>& | |
| | | &) /*noexcept*/; | |
| | | template <class T1, class D1> lazy_unique_ptr& operator= (std::unique_p | |
| | | tr<T1, D1>&&) /*noexcept*/; | |
| | | | |
| | | // 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::unique_ptr<T, D>& load () const; | |
| | | | |
| | | // Unload the pointer. For transient objects this function is | |
| | | // equivalent to reset(). | |
| | | // | |
| | | void unload () const; | |
| | | | |
| | | template <class ID> lazy_unique_ptr (database_type&, const ID&); | |
| | | lazy_unique_ptr (database_type&, pointer); | |
| | | lazy_unique_ptr (database_type&, pointer, const deleter_type&); | |
| | | lazy_unique_ptr (database_type&, pointer, deleter_type&&); | |
| | | template <class T1, class D1> lazy_unique_ptr (database_type&, std::uni | |
| | | que_ptr<T1, D1>&&); | |
| | | template <class T1> lazy_unique_ptr (database_type&, std::auto_ptr<T1>& | |
| | | &); | |
| | | | |
| | | template <class ID> void reset (database_type&, const ID&); | |
| | | void reset (database_type&, pointer); | |
| | | template <class T1, class D1> void reset (database_type&, std::unique_p | |
| | | tr<T1, D1>&&); | |
| | | template <class T1> void reset (database_type&, std::auto_ptr<T1>&&); | |
| | | | |
| | | #ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT | |
| | | template <class O = T> | |
| | | #else | |
| | | template <class O /*= T*/> | |
| | | #endif | |
| | | typename object_traits<O>::id_type object_id () const; | |
| | | | |
| | | database_type& database () const; | |
| | | | |
| | | // Helpers. | |
| | | // | |
| | | public: | |
| | | template <class T1, class D1> bool equal (const lazy_unique_ptr<T1, D1> | |
| | | &) const; | |
| | | | |
| | | private: | |
| | | template <class T1, class D1> friend class lazy_unique_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 | |
| | | // unique_ptr reference returned by load() is transferred to | |
| | | // another pointer or reset. | |
| | | // | |
| | | mutable std::unique_ptr<T, D> p_; | |
| | | mutable lazy_ptr_impl<T> i_; | |
| | | }; | |
| | | | |
| | | template <class T> void swap (lazy_unique_ptr<T>&, lazy_unique_ptr<T>&) / | |
| | | *noexcept*/; | |
| | | | |
| | | // operator< and operator<< are not provided. | |
| | | // | |
| | | template <class T1, class D1, class T2, class D2> | |
| | | bool operator== (const lazy_unique_ptr<T1, D1>&, const lazy_unique_ptr<T2 | |
| | | , D2>&); | |
| | | | |
| | | template <class T1, class D1, class T2, class D2> | |
| | | bool operator!= (const lazy_unique_ptr<T1, D1>&, const lazy_unique_ptr<T2 | |
| | | , D2>&); | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T, class D> | |
| | | bool operator== (const lazy_unique_ptr<T, D>&, std::nullptr_t) /*noexcept | |
| | | */; | |
| | | | |
| | | template <class T, class D> | |
| | | bool operator== (std::nullptr_t, const lazy_unique_ptr<T, D>&) /*noexcept | |
| | | */; | |
| | | | |
| | | template <class T, class D> | |
| | | bool operator!= (const lazy_unique_ptr<T, D>&, std::nullptr_t) /*noexcept | |
| | | */; | |
| | | | |
| | | template <class T, class D> | |
| | | bool operator!= (std::nullptr_t, const lazy_unique_ptr<T, D>&) /*noexcept | |
| | | */; | |
| | | #endif | |
| | | | |
| | | // C++11 std::shared_ptr lazy version. | |
| | | // | |
| | | template <class T> | |
| | | class lazy_weak_ptr; | |
| | | | |
| | | template <class T> | |
| | | class lazy_shared_ptr | |
| | | { | |
| | | // The standard shared_ptr interface. | |
| | | // | |
| | | public: | |
| | | typedef T element_type; | |
| | | | |
| | | /*constexpr*/ lazy_shared_ptr () /*noexcept*/; | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | /*constexpr*/ lazy_shared_ptr (std::nullptr_t) /*noexcept*/; | |
| | | #endif | |
| | | template <class Y> explicit lazy_shared_ptr (Y*); | |
| | | template <class Y, class D> lazy_shared_ptr (Y*, D); | |
| | | template <class Y, class D, class A> lazy_shared_ptr (Y*, D, A); | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class D> lazy_shared_ptr (std::nullptr_t, D); | |
| | | template <class D, class A> lazy_shared_ptr (std::nullptr_t, D, A); | |
| | | #endif | |
| | | template <class Y> lazy_shared_ptr (const lazy_shared_ptr<Y>&, T*) /*no | |
| | | except*/; | |
| | | | |
| | | lazy_shared_ptr (const lazy_shared_ptr&) /*noexcept*/; | |
| | | template <class Y> lazy_shared_ptr (const lazy_shared_ptr<Y>&) /*noexce | |
| | | pt*/; | |
| | | lazy_shared_ptr (lazy_shared_ptr&&) /*noexcept*/; | |
| | | template <class Y> lazy_shared_ptr (lazy_shared_ptr<Y>&&) /*noexcept*/; | |
| | | template <class Y> explicit lazy_shared_ptr (const lazy_weak_ptr<Y>&); | |
| | | template <class Y> explicit lazy_shared_ptr (std::auto_ptr<Y>&&); | |
| | | template <class Y, class D> lazy_shared_ptr (std::unique_ptr<Y, D>&&); | |
| | | | |
| | | ~lazy_shared_ptr (); | |
| | | | |
| | | lazy_shared_ptr& operator= (const lazy_shared_ptr&) /*noexcept*/; | |
| | | template <class Y> lazy_shared_ptr& operator= (const lazy_shared_ptr<Y> | |
| | | &) /*noexcept*/; | |
| | | lazy_shared_ptr& operator= (lazy_shared_ptr&&) /*noexcept*/; | |
| | | template <class Y> lazy_shared_ptr& operator= (lazy_shared_ptr<Y>&&) /* | |
| | | noexcept*/; | |
| | | template <class Y> lazy_shared_ptr& operator= (std::auto_ptr<Y>&&); | |
| | | template <class Y, class D> lazy_shared_ptr& operator= (std::unique_ptr | |
| | | <Y, D>&&); | |
| | | | |
| | | void swap (lazy_shared_ptr&) /*noexcept*/; | |
| | | void reset () /*noexcept*/; | |
| | | template <class Y> void reset (Y*); | |
| | | template <class Y, class D> void reset (Y*, D); | |
| | | template <class Y, class D, class A> 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*/; | |
| | | #ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR | |
| | | explicit operator bool () const /*noexcept*/; | |
| | | #else | |
| | | typedef std::shared_ptr<T> lazy_shared_ptr::*unspecified_bool_type; | |
| | | operator unspecified_bool_type () const | |
| | | { | |
| | | return (p_ || i_) ? &lazy_shared_ptr::p_ : 0; | |
| | | } | |
| | | #endif | |
| | | | |
| | | // owner_before () is not provded. | |
| | | | |
| | | // Initialization/assignment from shared_ptr and weak_ptr. | |
| | | // | |
| | | public: | |
| | | template <class Y> lazy_shared_ptr (const std::shared_ptr<Y>&); | |
| | | template <class Y> lazy_shared_ptr (std::shared_ptr<Y>&&); | |
| | | template <class Y> explicit lazy_shared_ptr (const std::weak_ptr<Y>&); | |
| | | | |
| | | template <class Y> lazy_shared_ptr& operator= (const std::shared_ptr<Y> | |
| | | &); | |
| | | template <class Y> lazy_shared_ptr& operator= (std::shared_ptr<Y>&&); | |
| | | | |
| | | // 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<T> load () const; | |
| | | | |
| | | // Unload the pointer. For transient objects this function is | |
| | | // equivalent to reset(). | |
| | | // | |
| | | void unload () const; | |
| | | | |
| | | template <class ID> lazy_shared_ptr (database_type&, const ID&); | |
| | | template <class Y> lazy_shared_ptr (database_type&, Y*); | |
| | | template <class Y, class D> lazy_shared_ptr (database_type&, Y*, D); | |
| | | template <class Y, class D, class A> lazy_shared_ptr (database_type&, Y | |
| | | *, D, A); | |
| | | template <class Y> lazy_shared_ptr (database_type&, std::auto_ptr<Y>&&) | |
| | | ; | |
| | | template <class Y> lazy_shared_ptr (database_type&, const std::shared_p | |
| | | tr<Y>&); | |
| | | template <class Y> lazy_shared_ptr (database_type&, std::shared_ptr<Y>& | |
| | | &); | |
| | | template <class Y> lazy_shared_ptr (database_type&, const std::weak_ptr | |
| | | <Y>&); | |
| | | | |
| | | template <class ID> void reset (database_type&, const ID&); | |
| | | template <class Y> void reset (database_type&, Y*); | |
| | | template <class Y, class D> void reset (database_type&, Y*, D); | |
| | | template <class Y, class D, class A> void reset (database_type&, Y*, D, | |
| | | A); | |
| | | template <class Y> void reset (database_type&, std::auto_ptr<Y>&&); | |
| | | template <class Y> void reset (database_type&, const std::shared_ptr<Y> | |
| | | &); | |
| | | template <class Y> void reset (database_type&, std::shared_ptr<Y>&&); | |
| | | | |
| | | #ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT | |
| | | template <class O = T> | |
| | | #else | |
| | | template <class O /*= T*/> | |
| | | #endif | |
| | | typename object_traits<O>::id_type object_id () const; | |
| | | | |
| | | database_type& database () const; | |
| | | | |
| | | // Helpers. | |
| | | // | |
| | | public: | |
| | | template <class Y> bool equal (const lazy_shared_ptr<Y>&) const; | |
| | | | |
| | | private: | |
| | | template <class Y> friend class lazy_shared_ptr; | |
| | | template <class Y> friend class lazy_weak_ptr; | |
| | | | |
| | | mutable std::shared_ptr<T> p_; | |
| | | mutable lazy_ptr_impl<T> i_; | |
| | | }; | |
| | | | |
| | | template <class T> void swap (lazy_shared_ptr<T>&, lazy_shared_ptr<T>&) / | |
| | | *noexcept*/; | |
| | | | |
| | | template <class D, class T> | |
| | | D* get_deleter (const lazy_shared_ptr<T>&) /*noexcept*/; | |
| | | | |
| | | // operator< and operator<< are not provided. | |
| | | // | |
| | | template <class T, class Y> | |
| | | bool operator== (const lazy_shared_ptr<T>&, const lazy_shared_ptr<Y>&) /* | |
| | | noexcept*/; | |
| | | | |
| | | template <class T, class Y> | |
| | | bool operator!= (const lazy_shared_ptr<T>&, const lazy_shared_ptr<Y>&) /* | |
| | | noexcept*/; | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T> | |
| | | bool operator== (const lazy_shared_ptr<T>&, std::nullptr_t) /*noexcept*/; | |
| | | | |
| | | template <class T> | |
| | | bool operator== (std::nullptr_t, const lazy_shared_ptr<T>&) /*noexcept*/; | |
| | | | |
| | | template <class T> | |
| | | bool operator!= (const lazy_shared_ptr<T>&, std::nullptr_t) /*noexcept*/; | |
| | | | |
| | | template <class T> | |
| | | bool operator!= (std::nullptr_t, const lazy_shared_ptr<T>&) /*noexcept*/; | |
| | | #endif | |
| | | | |
| | | // C++11 std::weak_ptr lazy version. | |
| | | // | |
| | | template <class T> | |
| | | class lazy_weak_ptr | |
| | | { | |
| | | // The standard weak_ptr interface. | |
| | | // | |
| | | public: | |
| | | typedef T element_type; | |
| | | | |
| | | /*constexpr*/ lazy_weak_ptr () /*noexcept*/; | |
| | | template <class Y> lazy_weak_ptr (const lazy_shared_ptr<Y>&) /*noexcept | |
| | | */; | |
| | | lazy_weak_ptr (const lazy_weak_ptr&) /*noexcept*/; | |
| | | template <class Y> lazy_weak_ptr (const lazy_weak_ptr<Y>&) /*noexcept*/ | |
| | | ; | |
| | | | |
| | | ~lazy_weak_ptr (); | |
| | | | |
| | | lazy_weak_ptr& operator= (const lazy_weak_ptr&) /*noexcept*/; | |
| | | template <class Y> lazy_weak_ptr& operator= (const lazy_weak_ptr<Y>&) / | |
| | | *noexcept*/; | |
| | | template <class Y> lazy_weak_ptr& operator= (const lazy_shared_ptr<Y>&) | |
| | | /*noexcept*/; | |
| | | | |
| | | void swap (lazy_weak_ptr<T>&) /*noexcept*/; | |
| | | void reset () /*noexcept*/; | |
| | | | |
| | | long use_count () const /*noexcept*/; | |
| | | bool expired () const /*noexcept*/; | |
| | | | |
| | | lazy_shared_ptr<T> lock () const /*noexcept*/; | |
| | | | |
| | | // owner_before () is not provded. | |
| | | | |
| | | // Initialization/assignment from shared_ptr and weak_ptr. | |
| | | // | |
| | | public: | |
| | | template <class Y> lazy_weak_ptr (const std::weak_ptr<Y>&); | |
| | | template <class Y> lazy_weak_ptr (const std::shared_ptr<Y>&); | |
| | | | |
| | | template <class Y> lazy_weak_ptr& operator= (const std::weak_ptr<Y>&); | |
| | | template <class Y> lazy_weak_ptr& operator= (const std::shared_ptr<Y>&) | |
| | | ; | |
| | | | |
| | | // 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<T> load () const; | |
| | | | |
| | | // Unload the pointer. For transient objects this function is | |
| | | // equivalent to reset(). | |
| | | // | |
| | | void unload () const; | |
| | | | |
| | | template <class ID> lazy_weak_ptr (database_type&, const ID&); | |
| | | template <class Y> lazy_weak_ptr (database_type&, const std::shared_ptr | |
| | | <Y>&); | |
| | | template <class Y> lazy_weak_ptr (database_type&, const std::weak_ptr<Y | |
| | | >&); | |
| | | | |
| | | template <class ID> void reset (database_type&, const ID&); | |
| | | template <class Y> void reset (database_type&, const std::shared_ptr<Y> | |
| | | &); | |
| | | template <class Y> void reset (database_type&, const std::weak_ptr<Y>&) | |
| | | ; | |
| | | | |
| | | // The object_id() function can only be called when the object is | |
| | | // persistent, or: expired() XOR loaded() (can use != for XOR). | |
| | | // | |
| | | #ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT | |
| | | template <class O = T> | |
| | | #else | |
| | | template <class O /*= T*/> | |
| | | #endif | |
| | | typename object_traits<O>::id_type object_id () const; | |
| | | | |
| | | database_type& database () const; | |
| | | | |
| | | private: | |
| | | template <class Y> friend class lazy_shared_ptr; | |
| | | template <class Y> friend class lazy_weak_ptr; | |
| | | | |
| | | mutable std::weak_ptr<T> p_; | |
| | | mutable lazy_ptr_impl<T> i_; | |
| | | }; | |
| | | | |
| | | // operator< is not provided. | |
| | | // | |
| | | template <class T> void swap (lazy_weak_ptr<T>&, lazy_weak_ptr<T>&); | |
| | | | |
| | | #endif // ODB_CXX11 | |
| | | | |
| namespace core | | namespace core | |
| { | | { | |
| using odb::lazy_ptr; | | using odb::lazy_ptr; | |
| using odb::lazy_auto_ptr; | | using odb::lazy_auto_ptr; | |
|
| | | | |
| | | #ifdef ODB_CXX11 | |
| | | using odb::lazy_unique_ptr; | |
| | | using odb::lazy_shared_ptr; | |
| | | using odb::lazy_weak_ptr; | |
| | | #endif | |
| } | | } | |
| } | | } | |
| | | | |
| #include <odb/lazy-ptr.ixx> | | #include <odb/lazy-ptr.ixx> | |
| #include <odb/lazy-ptr.txx> | | #include <odb/lazy-ptr.txx> | |
| | | | |
| #include <odb/lazy-pointer-traits.hxx> | | #include <odb/lazy-pointer-traits.hxx> | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| | | | |
End of changes. 17 change blocks. |
| 10 lines changed or deleted | | 481 lines changed or added | |
|
| lazy-ptr.ixx | | lazy-ptr.ixx | |
| | | | |
| skipping to change at line 193 | | skipping to change at line 193 | |
| return p_ ? object_traits<object_type>::id (*p_) : i_.object_id<O> (); | | return p_ ? object_traits<object_type>::id (*p_) : i_.object_id<O> (); | |
| } | | } | |
| | | | |
| template <class T> | | template <class T> | |
| inline typename lazy_ptr<T>::database_type& lazy_ptr<T>:: | | inline typename lazy_ptr<T>::database_type& lazy_ptr<T>:: | |
| database () const | | database () const | |
| { | | { | |
| return *i_.database (); | | return *i_.database (); | |
| } | | } | |
| | | | |
|
| template<class T, class Y> | | template <class T, class Y> | |
| inline bool | | inline bool | |
| operator== (const lazy_ptr<T>& a, const lazy_ptr<Y>& b) | | operator== (const lazy_ptr<T>& a, const lazy_ptr<Y>& b) | |
| { | | { | |
| return a.equal (b); | | return a.equal (b); | |
| } | | } | |
| | | | |
|
| template<class T, class Y> | | template <class T, class Y> | |
| inline bool | | inline bool | |
| operator!= (const lazy_ptr<T>& a, const lazy_ptr<Y>& b) | | operator!= (const lazy_ptr<T>& a, const lazy_ptr<Y>& b) | |
| { | | { | |
| return !a.equal (b); | | return !a.equal (b); | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline void | | inline void | |
| swap (lazy_ptr<T>& a, lazy_ptr<T>& b) | | swap (lazy_ptr<T>& a, lazy_ptr<T>& b) | |
| { | | { | |
| a.swap (b); | | a.swap (b); | |
| } | | } | |
| | | | |
| // | | // | |
| // lazy_auto_ptr_ref | | // lazy_auto_ptr_ref | |
| // | | // | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr_ref<T>:: | | inline lazy_auto_ptr_ref<T>:: | |
| lazy_auto_ptr_ref (T* p, const lazy_ptr_impl_ref& i): p_ (p), i_ (i) {} | | lazy_auto_ptr_ref (T* p, const lazy_ptr_impl_ref& i): p_ (p), i_ (i) {} | |
| | | | |
| // | | // | |
| // lazy_auto_ptr | | // lazy_auto_ptr | |
| // | | // | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| lazy_auto_ptr (T* p): p_ (p) {} | | lazy_auto_ptr (T* p): p_ (p) {} | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| lazy_auto_ptr (lazy_auto_ptr& r) | | lazy_auto_ptr (lazy_auto_ptr& r) | |
| : p_ (r.p_), i_ (static_cast<lazy_ptr_impl_ref> (r.i_)) | | : p_ (r.p_), i_ (static_cast<lazy_ptr_impl_ref> (r.i_)) | |
| { | | { | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| template<class Y> | | template <class Y> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| lazy_auto_ptr (lazy_auto_ptr<Y>& r) | | lazy_auto_ptr (lazy_auto_ptr<Y>& r) | |
| : p_ (r.p_), i_ (static_cast<lazy_ptr_impl_ref> (r.i_)) | | : p_ (r.p_), i_ (static_cast<lazy_ptr_impl_ref> (r.i_)) | |
| { | | { | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | |
| operator= (lazy_auto_ptr& r) | | operator= (lazy_auto_ptr& r) | |
| { | | { | |
| p_ = r.p_; | | p_ = r.p_; | |
| i_ = static_cast<lazy_ptr_impl_ref> (r.i_); | | i_ = static_cast<lazy_ptr_impl_ref> (r.i_); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| template<class Y> | | template <class Y> | |
| inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | |
| operator= (lazy_auto_ptr<Y>& r) | | operator= (lazy_auto_ptr<Y>& r) | |
| { | | { | |
| p_ = r.p_; | | p_ = r.p_; | |
| i_ = static_cast<lazy_ptr_impl_ref> (r.i_); | | i_ = static_cast<lazy_ptr_impl_ref> (r.i_); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline T& lazy_auto_ptr<T>:: | | inline T& lazy_auto_ptr<T>:: | |
| operator* () const | | operator* () const | |
| { | | { | |
| return *p_; | | return *p_; | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline T* lazy_auto_ptr<T>:: | | inline T* lazy_auto_ptr<T>:: | |
| operator-> () const | | operator-> () const | |
| { | | { | |
| return p_.operator-> (); | | return p_.operator-> (); | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline T* lazy_auto_ptr<T>:: | | inline T* lazy_auto_ptr<T>:: | |
| get () const | | get () const | |
| { | | { | |
| return p_.get (); | | return p_.get (); | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline T* lazy_auto_ptr<T>:: | | inline T* lazy_auto_ptr<T>:: | |
| release () | | release () | |
| { | | { | |
| i_.reset (); | | i_.reset (); | |
| return p_.release (); | | return p_.release (); | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline void lazy_auto_ptr<T>:: | | inline void lazy_auto_ptr<T>:: | |
| reset (T* p) | | reset (T* p) | |
| { | | { | |
| i_.reset (); | | i_.reset (); | |
| p_.reset (p); | | p_.reset (p); | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| lazy_auto_ptr (const lazy_auto_ptr_ref<T>& r): p_ (r.p_), i_ (r.i_) {} | | lazy_auto_ptr (const lazy_auto_ptr_ref<T>& r): p_ (r.p_), i_ (r.i_) {} | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | |
| operator= (const lazy_auto_ptr_ref<T>& r) | | operator= (const lazy_auto_ptr_ref<T>& r) | |
| { | | { | |
| if (p_.get () != r.p_) | | if (p_.get () != r.p_) | |
| p_.reset (r.p_); | | p_.reset (r.p_); | |
| | | | |
| i_ = r.i_; | | i_ = r.i_; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| template<class Y> | | template <class Y> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| operator lazy_auto_ptr_ref<Y> () | | operator lazy_auto_ptr_ref<Y> () | |
| { | | { | |
| return lazy_auto_ptr_ref<Y> (p_.release (), i_); | | return lazy_auto_ptr_ref<Y> (p_.release (), i_); | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| template<class Y> | | template <class Y> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| operator lazy_auto_ptr<Y> () | | operator lazy_auto_ptr<Y> () | |
| { | | { | |
| return lazy_auto_ptr<Y> (*this); | | return lazy_auto_ptr<Y> (*this); | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| template <class Y> | | template <class Y> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| lazy_auto_ptr (std::auto_ptr<Y>& r): p_ (r) {} | | lazy_auto_ptr (std::auto_ptr<Y>& r): p_ (r) {} | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| lazy_auto_ptr (std::auto_ptr_ref<T> r): p_ (r) {} | | lazy_auto_ptr (std::auto_ptr_ref<T> r): p_ (r) {} | |
| | | | |
|
| template<class T> | | template <class T> | |
| template <class Y> | | template <class Y> | |
| inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | |
| operator= (std::auto_ptr<Y>& r) | | operator= (std::auto_ptr<Y>& r) | |
| { | | { | |
| p_ = r; | | p_ = r; | |
| i_.reset (); | | i_.reset (); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| template<class T> | | template <class T> | |
| inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>& lazy_auto_ptr<T>:: | |
| operator= (std::auto_ptr_ref<T> r) | | operator= (std::auto_ptr_ref<T> r) | |
| { | | { | |
| p_ = r; | | p_ = r; | |
| i_.reset (); | | i_.reset (); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template <class T> | | template <class T> | |
| inline bool lazy_auto_ptr<T>:: | | inline bool lazy_auto_ptr<T>:: | |
| | | | |
| skipping to change at line 416 | | skipping to change at line 416 | |
| if (p) | | if (p) | |
| i_.reset (db); | | i_.reset (db); | |
| } | | } | |
| | | | |
| template <class T> | | template <class T> | |
| template <class Y> | | template <class Y> | |
| inline lazy_auto_ptr<T>:: | | inline lazy_auto_ptr<T>:: | |
| lazy_auto_ptr (database_type& db, std::auto_ptr<Y>& p) | | lazy_auto_ptr (database_type& db, std::auto_ptr<Y>& p) | |
| : p_ (p) | | : p_ (p) | |
| { | | { | |
|
| if (p) | | if (p_.get () != 0) | |
| i_.reset (db); | | i_.reset (db); | |
| } | | } | |
| | | | |
| template <class T> | | template <class T> | |
| template <class ID> | | template <class ID> | |
| inline void lazy_auto_ptr<T>:: | | inline void lazy_auto_ptr<T>:: | |
| reset (database_type& db, const ID& id) | | reset (database_type& db, const ID& id) | |
| { | | { | |
| p_.reset (); | | p_.reset (); | |
| i_.reset (db, id); | | i_.reset (db, id); | |
| | | | |
| skipping to change at line 472 | | skipping to change at line 472 | |
| ? object_traits<object_type>::id (*p_) | | ? object_traits<object_type>::id (*p_) | |
| : i_.object_id<O> (); | | : i_.object_id<O> (); | |
| } | | } | |
| | | | |
| template <class T> | | template <class T> | |
| inline typename lazy_auto_ptr<T>::database_type& lazy_auto_ptr<T>:: | | inline typename lazy_auto_ptr<T>::database_type& lazy_auto_ptr<T>:: | |
| database () const | | database () const | |
| { | | { | |
| return *i_.database (); | | return *i_.database (); | |
| } | | } | |
|
| | | | |
| | | #ifdef ODB_CXX11 | |
| | | | |
| | | // | |
| | | // lazy_unique_ptr | |
| | | // | |
| | | | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr () {} | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (std::nullptr_t) {} | |
| | | #endif | |
| | | | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (pointer p): p_ (p) {} | |
| | | | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (pointer p, const deleter_type& d): p_ (p, d) {} | |
| | | | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (pointer p, deleter_type&& d): p_ (p, std::move (d)) {} | |
| | | | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (lazy_unique_ptr&& r) | |
| | | : p_ (std::move (r.p_)), i_ (std::move (r.i_)) {} | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1, class D1> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (lazy_unique_ptr<T1, D1>&& r) | |
| | | : p_ (std::move (r.p_)), i_ (std::move (r.i_)) {} | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (std::auto_ptr<T1>&& r): p_ (std::move (r)) {} | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>& lazy_unique_ptr<T, D>:: | |
| | | operator= (std::nullptr_t) | |
| | | { | |
| | | reset (); | |
| | | return *this; | |
| | | } | |
| | | #endif | |
| | | | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>& lazy_unique_ptr<T, D>:: | |
| | | operator= (lazy_unique_ptr&& r) | |
| | | { | |
| | | p_ = std::move (r.p_); | |
| | | i_ = std::move (r.i_); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1, class D1> | |
| | | lazy_unique_ptr<T, D>& lazy_unique_ptr<T, D>:: | |
| | | operator= (lazy_unique_ptr<T1, D1>&& r) | |
| | | { | |
| | | p_ = std::move (r.p_); | |
| | | i_ = std::move (r.i_); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | T& lazy_unique_ptr<T, D>:: | |
| | | operator* () const | |
| | | { | |
| | | return *p_; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | typename lazy_unique_ptr<T, D>::pointer lazy_unique_ptr<T, D>:: | |
| | | operator-> () const | |
| | | { | |
| | | return p_.operator-> (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | typename lazy_unique_ptr<T, D>::pointer lazy_unique_ptr<T, D>:: | |
| | | get () const | |
| | | { | |
| | | return p_.get (); | |
| | | } | |
| | | | |
| | | #ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR | |
| | | template <class T, class D> | |
| | | lazy_unique_ptr<T, D>:: | |
| | | operator bool() const | |
| | | { | |
| | | return p_ || i_; | |
| | | } | |
| | | #endif | |
| | | | |
| | | template <class T, class D> | |
| | | typename lazy_unique_ptr<T, D>::pointer lazy_unique_ptr<T, D>:: | |
| | | release () | |
| | | { | |
| | | i_.reset (); | |
| | | return p_.release (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | void lazy_unique_ptr<T, D>:: | |
| | | reset (pointer p) | |
| | | { | |
| | | p_.reset (p); | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | void lazy_unique_ptr<T, D>:: | |
| | | swap (lazy_unique_ptr& b) | |
| | | { | |
| | | p_.swap (b.p_); | |
| | | i_.swap (b.i_); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | typename lazy_unique_ptr<T, D>::deleter_type& lazy_unique_ptr<T, D>:: | |
| | | get_deleter () | |
| | | { | |
| | | return p_.get_deleter (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | const typename lazy_unique_ptr<T, D>::deleter_type& lazy_unique_ptr<T, D> | |
| | | :: | |
| | | get_deleter () const | |
| | | { | |
| | | return p_.get_deleter (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1, class D1> | |
| | | inline lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (std::unique_ptr<T1, D1>&& p) | |
| | | : p_ (std::move (p)) | |
| | | { | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1, class D1> | |
| | | inline lazy_unique_ptr<T, D>& lazy_unique_ptr<T, D>:: | |
| | | operator= (std::unique_ptr<T1, D1>&& p) | |
| | | { | |
| | | p_ = std::move (p); | |
| | | i_.reset (); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline bool lazy_unique_ptr<T, D>:: | |
| | | loaded () const | |
| | | { | |
| | | bool i (i_); | |
| | | return !p_ != i; // !p_ XOR i_ | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline std::unique_ptr<T, D>& lazy_unique_ptr<T, D>:: | |
| | | load () const | |
| | | { | |
| | | if (!loaded ()) | |
| | | p_ = std::unique_ptr<T, D> (i_.template load<T> (true)); // Reset id. | |
| | | | |
| | | return p_; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline void lazy_unique_ptr<T, D>:: | |
| | | unload () const | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | if (p_) | |
| | | { | |
| | | if (i_.database () != 0) | |
| | | i_.reset_id (object_traits<object_type>::id (*p_)); | |
| | | | |
| | | p_.reset (); | |
| | | } | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class ID> | |
| | | inline lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (database_type& db, const ID& id): i_ (db, id) {} | |
| | | | |
| | | template <class T, class D> | |
| | | inline lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (database_type& db, T* p) | |
| | | : p_ (p) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (database_type& db, T* p, const deleter_type& d) | |
| | | : p_ (p, d) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (database_type& db, T* p, deleter_type&& d) | |
| | | : p_ (p, std::move (d)) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1, class D1> | |
| | | inline lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (database_type& db, std::unique_ptr<T1, D1>&& p) | |
| | | : p_ (std::move (p)) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1> | |
| | | inline lazy_unique_ptr<T, D>:: | |
| | | lazy_unique_ptr (database_type& db, std::auto_ptr<T1>&& p) | |
| | | : p_ (std::move (p)) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class ID> | |
| | | inline void lazy_unique_ptr<T, D>:: | |
| | | reset (database_type& db, const ID& id) | |
| | | { | |
| | | p_.reset (); | |
| | | i_.reset (db, id); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline void lazy_unique_ptr<T, D>:: | |
| | | reset (database_type& db, T* p) | |
| | | { | |
| | | p_.reset (p); | |
| | | | |
| | | if (p) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1, class D1> | |
| | | inline void lazy_unique_ptr<T, D>:: | |
| | | reset (database_type& db, std::unique_ptr<T1, D1>&& p) | |
| | | { | |
| | | p_ = std::move (p); | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class T1> | |
| | | inline void lazy_unique_ptr<T, D>:: | |
| | | reset (database_type& db, std::auto_ptr<T1>&& p) | |
| | | { | |
| | | p_ = std::unique_ptr<T, D> (std::move (p)); | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | template <class O> | |
| | | inline typename object_traits<O>::id_type lazy_unique_ptr<T, D>:: | |
| | | object_id () const | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | return p_ ? object_traits<object_type>::id (*p_) : i_.object_id<O> (); | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline typename lazy_unique_ptr<T, D>::database_type& lazy_unique_ptr<T, | |
| | | D>:: | |
| | | database () const | |
| | | { | |
| | | return *i_.database (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void | |
| | | swap (lazy_unique_ptr<T>& a, lazy_unique_ptr<T>& b) | |
| | | { | |
| | | a.swap (b); | |
| | | } | |
| | | | |
| | | template <class T1, class D1, class T2, class D2> | |
| | | inline bool | |
| | | operator== (const lazy_unique_ptr<T1, D1>& a, | |
| | | const lazy_unique_ptr<T2, D2>& b) | |
| | | { | |
| | | return a.equal (b); | |
| | | } | |
| | | | |
| | | template <class T1, class D1, class T2, class D2> | |
| | | inline bool | |
| | | operator!= (const lazy_unique_ptr<T1, D1>& a, | |
| | | const lazy_unique_ptr<T2, D2>& b) | |
| | | { | |
| | | return !a.equal (b); | |
| | | } | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T, class D> | |
| | | inline bool | |
| | | operator== (const lazy_unique_ptr<T, D>& a, std::nullptr_t) | |
| | | { | |
| | | return !a; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline bool | |
| | | operator== (std::nullptr_t, const lazy_unique_ptr<T, D>& b) | |
| | | { | |
| | | return !b; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline bool | |
| | | operator!= (const lazy_unique_ptr<T, D>& a, std::nullptr_t) | |
| | | { | |
| | | return a; | |
| | | } | |
| | | | |
| | | template <class T, class D> | |
| | | inline bool | |
| | | operator!= (std::nullptr_t, const lazy_unique_ptr<T, D>& b) | |
| | | { | |
| | | return b; | |
| | | } | |
| | | #endif | |
| | | | |
| | | // | |
| | | // lazy_shared_ptr | |
| | | // | |
| | | | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr () {} | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (std::nullptr_t) {} | |
| | | #endif | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (Y* p): p_ (p) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (Y* p, D d): p_ (p, d) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D, class A> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (Y* p, D d, A a): p_ (p, d, a) {} | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T> | |
| | | template <class D> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (std::nullptr_t p, D d): p_ (p, d) {} | |
| | | | |
| | | template <class T> | |
| | | template <class D, class A> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (std::nullptr_t p, D d, A a): p_ (p, d, a) {} | |
| | | #endif | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (const lazy_shared_ptr<Y>& r, T* p) | |
| | | // r.p_ has to be loaded | |
| | | : p_ (r.p_, p) {} | |
| | | | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (const lazy_shared_ptr& r): p_ (r.p_), i_ (r.i_) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (const lazy_shared_ptr<Y>& r): p_ (r.p_), i_ (r.i_) {} | |
| | | | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (lazy_shared_ptr&& r) | |
| | | : p_ (std::move (r.p_)), i_ (std::move (r.i_)) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (lazy_shared_ptr<Y>&& r) | |
| | | : p_ (std::move (r.p_)), i_ (std::move (r.i_)) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (const lazy_weak_ptr<Y>& r): i_ (r.i_) | |
| | | { | |
| | | // If the pointer has expired but can be re-loaded, then don't throw. | |
| | | // | |
| | | p_ = r.lock (); | |
| | | | |
| | | if (!p_ && !i_) | |
| | | throw std::bad_weak_ptr (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (std::auto_ptr<Y>&& r): p_ (std::move (r)) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (std::unique_ptr<Y, D>&& r): p_ (std::move (r)) {} | |
| | | | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | ~lazy_shared_ptr () {} | |
| | | | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (const lazy_shared_ptr& r) | |
| | | { | |
| | | p_ = r.p_; | |
| | | i_ = r.i_; | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (const lazy_shared_ptr<Y>& r) | |
| | | { | |
| | | p_ = r.p_; | |
| | | i_ = r.i_; | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (lazy_shared_ptr&& r) | |
| | | { | |
| | | p_ = std::move (r.p_); | |
| | | i_ = std::move (r.i_); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (lazy_shared_ptr<Y>&& r) | |
| | | { | |
| | | p_ = std::move (r.p_); | |
| | | i_ = std::move (r.i_); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (std::auto_ptr<Y>&& r) | |
| | | { | |
| | | p_ = std::move (r); | |
| | | i_.reset (); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (std::unique_ptr<Y, D>&& r) | |
| | | { | |
| | | p_ = std::move (r); | |
| | | i_.reset (); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | swap (lazy_shared_ptr& b) | |
| | | { | |
| | | p_.swap (b.p_); | |
| | | i_.swap (b.i_); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset () | |
| | | { | |
| | | p_.reset (); | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (Y* p) | |
| | | { | |
| | | p_.reset (p); | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (Y* p, D d) | |
| | | { | |
| | | p_.reset (p, d); | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D, class A> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (Y* p, D d, A a) | |
| | | { | |
| | | p_.reset (p, d, a); | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline T& lazy_shared_ptr<T>:: | |
| | | operator* () const | |
| | | { | |
| | | return *p_; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline T* lazy_shared_ptr<T>:: | |
| | | operator-> () const | |
| | | { | |
| | | return p_.operator-> (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline T* lazy_shared_ptr<T>:: | |
| | | get () const | |
| | | { | |
| | | return p_.get (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline bool lazy_shared_ptr<T>:: | |
| | | unique () const | |
| | | { | |
| | | return p_.unique (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline long lazy_shared_ptr<T>:: | |
| | | use_count () const | |
| | | { | |
| | | return p_.use_count (); | |
| | | } | |
| | | | |
| | | #ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR | |
| | | template <class T> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | operator bool () const | |
| | | { | |
| | | return p_ || i_; | |
| | | } | |
| | | #endif | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (const std::shared_ptr<Y>& r): p_ (r) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (std::shared_ptr<Y>&& r): p_ (std::move (r)) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (const std::weak_ptr<Y>& r): p_ (r) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (const std::shared_ptr<Y>& r) | |
| | | { | |
| | | p_ = r; | |
| | | i_.reset (); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>& lazy_shared_ptr<T>:: | |
| | | operator= (std::shared_ptr<Y>&& r) | |
| | | { | |
| | | p_ = std::move (r); | |
| | | i_.reset (); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline bool lazy_shared_ptr<T>:: | |
| | | loaded () const | |
| | | { | |
| | | bool i (i_); | |
| | | return !p_ != i; // !p_ XOR i_ | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline std::shared_ptr<T> lazy_shared_ptr<T>:: | |
| | | load () const | |
| | | { | |
| | | if (!loaded ()) | |
| | | p_ = i_.template load<T> (true); // Reset id. | |
| | | | |
| | | return p_; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | unload () const | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | if (p_) | |
| | | { | |
| | | if (i_.database () != 0) | |
| | | i_.reset_id (object_traits<object_type>::id (*p_)); | |
| | | | |
| | | p_.reset (); | |
| | | } | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class ID> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, const ID& id): i_ (db, id) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, Y* p) | |
| | | : p_ (p) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, Y* p, D d) | |
| | | : p_ (p, d) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D, class A> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, Y* p, D d, A a) | |
| | | : p_ (p, d, a) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, std::auto_ptr<Y>&& r) | |
| | | : p_ (std::move (r)) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, const std::shared_ptr<Y>& r) | |
| | | : p_ (r) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, std::shared_ptr<Y>&& r) | |
| | | : p_ (std::move (r)) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_shared_ptr<T>:: | |
| | | lazy_shared_ptr (database_type& db, const std::weak_ptr<Y>& r) | |
| | | : p_ (r) | |
| | | { | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class ID> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (database_type& db, const ID& id) | |
| | | { | |
| | | p_.reset (); | |
| | | i_.reset (db, id); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (database_type& db, Y* p) | |
| | | { | |
| | | p_.reset (p); | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (database_type& db, Y* p, D d) | |
| | | { | |
| | | p_.reset (p, d); | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y, class D, class A> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (database_type& db, Y* p, D d, A a) | |
| | | { | |
| | | p_.reset (p, d, a); | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (database_type& db, std::auto_ptr<Y>&& r) | |
| | | { | |
| | | p_ = std::move (r); | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (database_type& db, const std::shared_ptr<Y>& r) | |
| | | { | |
| | | p_ = r; | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline void lazy_shared_ptr<T>:: | |
| | | reset (database_type& db, std::shared_ptr<Y>&& r) | |
| | | { | |
| | | p_ = std::move (r); | |
| | | | |
| | | if (p_) | |
| | | i_.reset (db); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class O> | |
| | | inline typename object_traits<O>::id_type lazy_shared_ptr<T>:: | |
| | | object_id () const | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | return p_ ? object_traits<object_type>::id (*p_) : i_.object_id<O> (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline typename lazy_shared_ptr<T>::database_type& lazy_shared_ptr<T>:: | |
| | | database () const | |
| | | { | |
| | | return *i_.database (); | |
| | | } | |
| | | | |
| | | template <class T, class Y> | |
| | | inline bool | |
| | | operator== (const lazy_shared_ptr<T>& a, const lazy_shared_ptr<Y>& b) | |
| | | { | |
| | | return a.equal (b); | |
| | | } | |
| | | | |
| | | template <class T, class Y> | |
| | | inline bool | |
| | | operator!= (const lazy_shared_ptr<T>& a, const lazy_shared_ptr<Y>& b) | |
| | | { | |
| | | return !a.equal (b); | |
| | | } | |
| | | | |
| | | #ifdef ODB_CXX11_NULLPTR | |
| | | template <class T> | |
| | | inline bool | |
| | | operator== (const lazy_shared_ptr<T>& p, std::nullptr_t) | |
| | | { | |
| | | return !p; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline bool | |
| | | operator== (std::nullptr_t, const lazy_shared_ptr<T>& p) | |
| | | { | |
| | | return !p; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline bool | |
| | | operator!= (const lazy_shared_ptr<T>& p, std::nullptr_t) | |
| | | { | |
| | | return p; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline bool | |
| | | operator!= (std::nullptr_t, const lazy_shared_ptr<T>& p) | |
| | | { | |
| | | return p; | |
| | | } | |
| | | #endif | |
| | | | |
| | | template <class T> | |
| | | inline void | |
| | | swap (lazy_shared_ptr<T>& a, lazy_shared_ptr<T>& b) | |
| | | { | |
| | | a.swap (b); | |
| | | } | |
| | | | |
| | | template <class D, class T> | |
| | | inline D* | |
| | | get_deleter (const lazy_shared_ptr<T>& p) | |
| | | { | |
| | | return std::get_deleter<D> (p.p_); | |
| | | } | |
| | | | |
| | | // | |
| | | // lazy_weak_ptr | |
| | | // | |
| | | | |
| | | template <class T> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr () {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (const lazy_shared_ptr<Y>& r): p_ (r.p_), i_ (r.i_) {} | |
| | | | |
| | | template <class T> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (const lazy_weak_ptr& r): p_ (r.p_), i_ (r.i_) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (const lazy_weak_ptr<Y>& r): p_ (r.p_), i_ (r.i_) {} | |
| | | | |
| | | template <class T> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | ~lazy_weak_ptr () {} | |
| | | | |
| | | template <class T> | |
| | | inline lazy_weak_ptr<T>& lazy_weak_ptr<T>:: | |
| | | operator= (const lazy_weak_ptr& r) | |
| | | { | |
| | | p_ = r.p_; | |
| | | i_ = r.i_; | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>& lazy_weak_ptr<T>:: | |
| | | operator= (const lazy_weak_ptr<Y>& r) | |
| | | { | |
| | | p_ = r.p_; | |
| | | i_ = r.i_; | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>& lazy_weak_ptr<T>:: | |
| | | operator= (const lazy_shared_ptr<Y>& r) | |
| | | { | |
| | | p_ = r.p_; | |
| | | i_ = r.i_; | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void lazy_weak_ptr<T>:: | |
| | | swap (lazy_weak_ptr<T>& r) | |
| | | { | |
| | | p_.swap (r.p_); | |
| | | i_.swap (r.i_); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void lazy_weak_ptr<T>:: | |
| | | reset () | |
| | | { | |
| | | p_.reset (); | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline long lazy_weak_ptr<T>:: | |
| | | use_count () const | |
| | | { | |
| | | return p_.use_count (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline bool lazy_weak_ptr<T>:: | |
| | | expired () const | |
| | | { | |
| | | return p_.expired (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (const std::weak_ptr<Y>& r): p_ (r) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (const std::shared_ptr<Y>& r): p_ (r) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>& lazy_weak_ptr<T>:: | |
| | | operator= (const std::weak_ptr<Y>& r) | |
| | | { | |
| | | p_ = r; | |
| | | i_.reset (); | |
| | | return this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>& lazy_weak_ptr<T>:: | |
| | | operator= (const std::shared_ptr<Y>& r) | |
| | | { | |
| | | p_ = r; | |
| | | i_.reset (); | |
| | | return this; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline bool lazy_weak_ptr<T>:: | |
| | | loaded () const | |
| | | { | |
| | | bool i (i_); | |
| | | return expired () != i; // expired () XOR i_ | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline std::shared_ptr<T> lazy_weak_ptr<T>:: | |
| | | load () const | |
| | | { | |
| | | std::shared_ptr<T> r (p_.lock ()); | |
| | | | |
| | | if (r || !i_) | |
| | | return r; | |
| | | | |
| | | r = i_.template load<T> (false); // Keep id. | |
| | | p_ = r; | |
| | | return r; | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void lazy_weak_ptr<T>:: | |
| | | unload () const | |
| | | { | |
| | | // With weak pointer we always keep i_ up to date. | |
| | | // | |
| | | p_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class ID> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (database_type& db, const ID& id): i_ (db, id) {} | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (database_type& db, const std::shared_ptr<Y>& r) | |
| | | : p_ (r) | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | if (r) | |
| | | i_.reset (db, object_traits<object_type>::id (*r)); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline lazy_weak_ptr<T>:: | |
| | | lazy_weak_ptr (database_type& db, const std::weak_ptr<Y>& r) | |
| | | : p_ (r) | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | std::shared_ptr<T> sp (p_.lock ()); | |
| | | | |
| | | if (sp) | |
| | | i_.reset (db, object_traits<object_type>::id (*sp)); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class ID> | |
| | | inline void lazy_weak_ptr<T>:: | |
| | | reset (database_type& db, const ID& id) | |
| | | { | |
| | | p_.reset (); | |
| | | i_.reset (db, id); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline void lazy_weak_ptr<T>:: | |
| | | reset (database_type& db, const std::shared_ptr<Y>& r) | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | p_ = r; | |
| | | | |
| | | if (r) | |
| | | i_.reset (db, object_traits<object_type>::id (*r)); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class Y> | |
| | | inline void lazy_weak_ptr<T>:: | |
| | | reset (database_type& db, const std::weak_ptr<Y>& r) | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | p_ = r; | |
| | | std::shared_ptr<T> sp (p_.lock ()); | |
| | | | |
| | | if (sp) | |
| | | i_.reset (db, object_traits<object_type>::id (*sp)); | |
| | | else | |
| | | i_.reset (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | template <class O> | |
| | | inline typename object_traits<O>::id_type lazy_weak_ptr<T>:: | |
| | | object_id () const | |
| | | { | |
| | | typedef typename object_traits<T>::object_type object_type; | |
| | | | |
| | | std::shared_ptr<T> sp (p_.lock ()); | |
| | | return sp ? object_traits<object_type>::id (*sp) : i_.object_id<O> (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline typename lazy_weak_ptr<T>::database_type& lazy_weak_ptr<T>:: | |
| | | database () const | |
| | | { | |
| | | return *i_.database (); | |
| | | } | |
| | | | |
| | | template <class T> | |
| | | inline void | |
| | | swap (lazy_weak_ptr<T>& a, lazy_weak_ptr<T>& b) | |
| | | { | |
| | | a.swap (b); | |
| | | } | |
| | | | |
| | | #endif // ODB_CXX11 | |
| | | | |
| } | | } | |
| | | | |
End of changes. 24 change blocks. |
| 27 lines changed or deleted | | 1180 lines changed or added | |
|
| object-result.hxx | | object-result.hxx | |
| // file : odb/object-result.hxx | | // file : odb/object-result.hxx | |
| // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_OBJECT_RESULT_HXX | | #ifndef ODB_OBJECT_RESULT_HXX | |
| #define ODB_OBJECT_RESULT_HXX | | #define ODB_OBJECT_RESULT_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
|
| #include <cstddef> // std::ptrdiff_t, std::size_t | | #include <cstddef> // std::ptrdiff_t | |
| #include <iterator> // iterator categories | | #include <iterator> // iterator categories | |
| | | | |
| #include <odb/forward.hxx> | | #include <odb/forward.hxx> | |
|
| | | #include <odb/traits.hxx> | |
| #include <odb/result.hxx> | | #include <odb/result.hxx> | |
| #include <odb/pointer-traits.hxx> | | #include <odb/pointer-traits.hxx> | |
| | | | |
|
| #include <odb/details/shared-ptr.hxx> | | | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
|
| | | // | |
| | | // object_result_impl | |
| | | // | |
| template <typename T> | | template <typename T> | |
| class object_result_impl; | | class object_result_impl; | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| class object_result_impl_no_id; | | class polymorphic_object_result_impl; | |
| | | | |
|
| template <typename T, typename ID> | | template <typename T> | |
| class object_result_iterator; | | class no_id_object_result_impl; | |
| | | | |
| | | // | |
| | | // object_result_impl_selector | |
| | | // | |
| | | template <typename T, | |
| | | typename ID = typename object_traits<T>::id_type, | |
| | | bool polymorphic = object_traits<T>::polymorphic> | |
| | | struct object_result_impl_selector; | |
| | | | |
|
| template <typename T, typename ID = typename object_traits<T>::id_type> | | template <typename T, typename ID> | |
| struct object_result_impl_selector | | struct object_result_impl_selector<T, ID, false> | |
| { | | { | |
| typedef object_result_impl<T> type; | | typedef object_result_impl<T> type; | |
| }; | | }; | |
| | | | |
|
| template <typename T> | | template <typename T, typename ID> | |
| struct object_result_impl_selector<T, void> | | struct object_result_impl_selector<T, ID, true> | |
| { | | { | |
|
| typedef object_result_impl_no_id<T> type; | | typedef polymorphic_object_result_impl<T> type; | |
| }; | | }; | |
| | | | |
|
| // Implementation for objects with object id. | | | |
| // | | | |
| template <typename T> | | template <typename T> | |
|
| class object_result_impl: public details::shared_base | | struct object_result_impl_selector<T, void, false> | |
| { | | { | |
|
| public: | | typedef no_id_object_result_impl<T> type; | |
| virtual | | | |
| ~object_result_impl (); | | | |
| | | | |
| protected: | | | |
| typedef odb::database database_type; | | | |
| | | | |
| // In result_impl, T is always non-const and the same as object_type. | | | |
| // | | | |
| typedef T object_type; | | | |
| typedef odb::object_traits<object_type> object_traits; | | | |
| typedef typename object_traits::id_type id_type; | | | |
| | | | |
| typedef typename object_traits::pointer_type pointer_type; | | | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | | |
| | | | |
| friend class result<T>; | | | |
| friend class result<const T>; | | | |
| friend class result_iterator<T, class_object>; | | | |
| friend class result_iterator<const T, class_object>; | | | |
| friend class object_result_iterator<T, id_type>; | | | |
| friend class object_result_iterator<const T, id_type>; | | | |
| | | | |
| protected: | | | |
| object_result_impl (database_type& db) | | | |
| : begin_ (true), end_ (false), db_ (db), current_ () | | | |
| { | | | |
| } | | | |
| | | | |
| database_type& | | | |
| database () const | | | |
| { | | | |
| return db_; | | | |
| } | | | |
| | | | |
| // To make this work with all kinds of pointers (raw, std::auto_ptr, | | | |
| // shared), we need to make sure we don't make any copies of the | | | |
| // pointer on the return path. | | | |
| // | | | |
| pointer_type& | | | |
| current (); | | | |
| | | | |
| void | | | |
| release () | | | |
| { | | | |
| current_ = pointer_type (); | | | |
| guard_.release (); | | | |
| } | | | |
| | | | |
| void | | | |
| begin () | | | |
| { | | | |
| if (begin_) | | | |
| { | | | |
| next (); | | | |
| begin_ = false; | | | |
| } | | | |
| } | | | |
| | | | |
| bool | | | |
| end () const | | | |
| { | | | |
| return end_; | | | |
| } | | | |
| | | | |
| protected: | | | |
| // The fetch argument is a hint to the implementation. If it is | | | |
| // false then it means load_id() was already called (and presumably | | | |
| // fetched the data into the object image) and the object image | | | |
| // is still valid (so the implementation doesn't need to fetch | | | |
| // the data again). | | | |
| // | | | |
| virtual void | | | |
| load (object_type&, bool fetch = true) = 0; | | | |
| | | | |
| virtual id_type | | | |
| load_id () = 0; | | | |
| | | | |
| virtual void | | | |
| next () = 0; | | | |
| | | | |
| virtual void | | | |
| cache () = 0; | | | |
| | | | |
| virtual std::size_t | | | |
| size () = 0; | | | |
| | | | |
| protected: | | | |
| void | | | |
| current (pointer_type p) | | | |
| { | | | |
| current_ = p; | | | |
| guard_.reset (current_); | | | |
| } | | | |
| | | | |
| bool begin_; | | | |
| bool end_; | | | |
| | | | |
| private: | | | |
| database_type& db_; | | | |
| pointer_type current_; | | | |
| typename pointer_traits::guard guard_; | | | |
| }; | | | |
| | | | |
| // Implementation for objects without object id. | | | |
| // | | | |
| template <typename T> | | | |
| class object_result_impl_no_id: public details::shared_base | | | |
| { | | | |
| public: | | | |
| virtual | | | |
| ~object_result_impl_no_id (); | | | |
| | | | |
| protected: | | | |
| typedef odb::database database_type; | | | |
| | | | |
| // In result_impl, T is always non-const and the same as object_type. | | | |
| // | | | |
| typedef T object_type; | | | |
| typedef odb::object_traits<object_type> object_traits; | | | |
| | | | |
| typedef typename object_traits::pointer_type pointer_type; | | | |
| typedef odb::pointer_traits<pointer_type> pointer_traits; | | | |
| | | | |
| friend class result<T>; | | | |
| friend class result<const T>; | | | |
| friend class result_iterator<T, class_object>; | | | |
| friend class result_iterator<const T, class_object>; | | | |
| friend class object_result_iterator<T, void>; | | | |
| friend class object_result_iterator<const T, void>; | | | |
| | | | |
| protected: | | | |
| object_result_impl_no_id (database_type& db) | | | |
| : begin_ (true), end_ (false), db_ (db), current_ () | | | |
| { | | | |
| } | | | |
| | | | |
| database_type& | | | |
| database () const | | | |
| { | | | |
| return db_; | | | |
| } | | | |
| | | | |
| // To make this work with all kinds of pointers (raw, std::auto_ptr, | | | |
| // shared), we need to make sure we don't make any copies of the | | | |
| // pointer on the return path. | | | |
| // | | | |
| pointer_type& | | | |
| current (); | | | |
| | | | |
| void | | | |
| release () | | | |
| { | | | |
| current_ = pointer_type (); | | | |
| guard_.release (); | | | |
| } | | | |
| | | | |
| void | | | |
| begin () | | | |
| { | | | |
| if (begin_) | | | |
| { | | | |
| next (); | | | |
| begin_ = false; | | | |
| } | | | |
| } | | | |
| | | | |
| bool | | | |
| end () const | | | |
| { | | | |
| return end_; | | | |
| } | | | |
| | | | |
| protected: | | | |
| virtual void | | | |
| load (object_type&) = 0; | | | |
| | | | |
| virtual void | | | |
| next () = 0; | | | |
| | | | |
| virtual void | | | |
| cache () = 0; | | | |
| | | | |
| virtual std::size_t | | | |
| size () = 0; | | | |
| | | | |
| protected: | | | |
| void | | | |
| current (pointer_type p) | | | |
| { | | | |
| current_ = p; | | | |
| guard_.reset (current_); | | | |
| } | | | |
| | | | |
| bool begin_; | | | |
| bool end_; | | | |
| | | | |
| private: | | | |
| database_type& db_; | | | |
| pointer_type current_; | | | |
| typename pointer_traits::guard guard_; | | | |
| }; | | }; | |
| | | | |
| // | | // | |
| // result_iterator | | // result_iterator | |
| // | | // | |
| | | | |
|
| template <typename T, typename ID> | | template <typename T, typename ID, bool polymorphic> | |
| class object_result_iterator | | class object_result_iterator; | |
| { | | | |
| public: | | | |
| // T can be const T while object_type is always non-const. | | | |
| // | | | |
| typedef typename object_traits<T>::object_type object_type; | | | |
| typedef typename object_traits<T>::id_type id_type; | | | |
| | | | |
| typedef object_result_impl<object_type> result_impl_type; | | | |
| | | | |
| public: | | | |
| object_result_iterator (result_impl_type* res) | | | |
| : res_ (res) | | | |
| { | | | |
| } | | | |
| | | | |
| public: | | | |
| typename object_traits<T>::pointer_type | | | |
| load () | | | |
| { | | | |
| typename object_traits<T>::pointer_type r (res_->current ()); | | | |
| res_->release (); | | | |
| return r; | | | |
| } | | | |
| | | | |
| void | | | |
| load (object_type&); | | | |
| | | | |
| id_type | | | |
| id () | | | |
| { | | | |
| return res_->load_id (); | | | |
| } | | | |
| | | | |
| protected: | | | |
| result_impl_type* res_; | | | |
| }; | | | |
| | | | |
| template <typename T> | | | |
| class object_result_iterator<T, void> | | | |
| { | | | |
| public: | | | |
| // T can be const T while object_type is always non-const. | | | |
| // | | | |
| typedef typename object_traits<T>::object_type object_type; | | | |
| | | | |
| typedef object_result_impl_no_id<object_type> result_impl_type; | | | |
| | | | |
| public: | | | |
| object_result_iterator (result_impl_type* res) | | | |
| : res_ (res) | | | |
| { | | | |
| } | | | |
| | | | |
| public: | | | |
| typename object_traits<T>::pointer_type | | | |
| load () | | | |
| { | | | |
| typename object_traits<T>::pointer_type r (res_->current ()); | | | |
| res_->release (); | | | |
| return r; | | | |
| } | | | |
| | | | |
| void | | | |
| load (object_type& obj) | | | |
| { | | | |
| // Objects without ids are not stored in session cache. | | | |
| // | | | |
| if (!res_->end ()) | | | |
| res_->load (obj); | | | |
| } | | | |
| | | | |
| protected: | | | |
| result_impl_type* res_; | | | |
| }; | | | |
| | | | |
| template <typename T> | | template <typename T> | |
| class result_iterator<T, class_object>: public object_result_iterator< | | class result_iterator<T, class_object>: public object_result_iterator< | |
| T, | | T, | |
|
| typename object_traits<T>::id_type> | | typename object_traits<T>::id_type, | |
| | | object_traits<T>::polymorphic> | |
| { | | { | |
| public: | | public: | |
| typedef T value_type; | | typedef T value_type; | |
| typedef value_type& reference; | | typedef value_type& reference; | |
| typedef value_type* pointer; | | typedef value_type* pointer; | |
| typedef std::ptrdiff_t difference_type; | | typedef std::ptrdiff_t difference_type; | |
| typedef std::input_iterator_tag iterator_category; | | typedef std::input_iterator_tag iterator_category; | |
| | | | |
| // T can be const T while object_type is always non-const. | | // T can be const T while object_type is always non-const. | |
| // | | // | |
| typedef | | typedef | |
|
| object_result_iterator<T, typename object_traits<T>::id_type> | | object_result_iterator<T, | |
| base_type; | | typename object_traits<T>::id_type, | |
| | | object_traits<T>::polymorphic> base_type; | |
| | | | |
| public: | | public: | |
| explicit | | explicit | |
| result_iterator (typename base_type::result_impl_type* res = 0) | | result_iterator (typename base_type::result_impl_type* res = 0) | |
| : base_type (res) | | : base_type (res) | |
| { | | { | |
| } | | } | |
| | | | |
| // Input iterator requirements. | | // Input iterator requirements. | |
| // | | // | |
| | | | |
| skipping to change at line 427 | | skipping to change at line 163 | |
| | | | |
| // T can be const T while object_type is always non-const. | | // T can be const T while object_type is always non-const. | |
| // | | // | |
| typedef typename object_traits<T>::object_type object_type; | | typedef typename object_traits<T>::object_type object_type; | |
| typedef | | typedef | |
| typename object_result_impl_selector<object_type>::type | | typename object_result_impl_selector<object_type>::type | |
| result_impl_type; | | result_impl_type; | |
| }; | | }; | |
| } | | } | |
| | | | |
|
| #include <odb/object-result.txx> | | | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_OBJECT_RESULT_HXX | | #endif // ODB_OBJECT_RESULT_HXX | |
| | | | |
End of changes. 16 change blocks. |
| 296 lines changed or deleted | | 30 lines changed or added | |
|
| pointer-traits.hxx | | pointer-traits.hxx | |
| // file : odb/pointer-traits.hxx | | // file : odb/pointer-traits.hxx | |
| // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_POINTER_TRAITS_HXX | | #ifndef ODB_POINTER_TRAITS_HXX | |
| #define ODB_POINTER_TRAITS_HXX | | #define ODB_POINTER_TRAITS_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <new> // operators new/delete | | #include <new> // operators new/delete | |
|
| #include <memory> // std::auto_ptr | | #include <memory> // std::auto_ptr, std::unique_ptr, std::shared_ptr/weak_
ptr | |
| #include <cstddef> // std::size_t | | #include <cstddef> // std::size_t | |
| | | | |
|
| | | #include <odb/details/config.hxx> // ODB_CXX11 | |
| #include <odb/details/meta/remove-const.hxx> | | #include <odb/details/meta/remove-const.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| enum pointer_kind | | enum pointer_kind | |
| { | | { | |
| pk_raw, // Raw pointer or equivalent (i.e., unmanaged). | | pk_raw, // Raw pointer or equivalent (i.e., unmanaged). | |
| pk_unique, // Smart pointer that doesn't support sharing. | | pk_unique, // Smart pointer that doesn't support sharing. | |
| pk_shared, // Smart pointer that supports sharing. | | pk_shared, // Smart pointer that supports sharing. | |
| pk_weak // Weak counterpart for shared pointer. | | pk_weak // Weak counterpart for shared pointer. | |
| | | | |
| skipping to change at line 49 | | skipping to change at line 50 | |
| ~raw_ptr_guard () {delete p_;} | | ~raw_ptr_guard () {delete p_;} | |
| raw_ptr_guard (): p_ (0) {} | | raw_ptr_guard (): p_ (0) {} | |
| | | | |
| explicit | | explicit | |
| raw_ptr_guard (P p): p_ (p) {} | | raw_ptr_guard (P p): p_ (p) {} | |
| | | | |
| void | | void | |
| release () {p_ = 0;} | | release () {p_ = 0;} | |
| | | | |
| void | | void | |
|
| reset (P p) {delete p_; p_ = p;} | | reset (P p = 0) {delete p_; p_ = p;} | |
| | | | |
| private: | | private: | |
| P p_; | | P p_; | |
| }; | | }; | |
| | | | |
| // No-op pointer guard for smart pointers. | | // No-op pointer guard for smart pointers. | |
| // | | // | |
| template <typename P> | | template <typename P> | |
| class smart_ptr_guard | | class smart_ptr_guard | |
| { | | { | |
| public: | | public: | |
| smart_ptr_guard () {} | | smart_ptr_guard () {} | |
| | | | |
| explicit | | explicit | |
| smart_ptr_guard (const P&) {} | | smart_ptr_guard (const P&) {} | |
| | | | |
| void | | void | |
| release () {} | | release () {} | |
| | | | |
| void | | void | |
|
| | | reset () {} | |
| | | | |
| | | void | |
| reset (const P&) {} | | reset (const P&) {} | |
| }; | | }; | |
| | | | |
| // Specialization for raw pointers. | | // Specialization for raw pointers. | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| class pointer_traits<T*> | | class pointer_traits<T*> | |
| { | | { | |
| public: | | public: | |
| static const pointer_kind kind = pk_raw; | | static const pointer_kind kind = pk_raw; | |
| | | | |
| skipping to change at line 113 | | skipping to change at line 117 | |
| } | | } | |
| | | | |
| // Return true if the pointer is NULL. | | // Return true if the pointer is NULL. | |
| // | | // | |
| static bool | | static bool | |
| null_ptr (pointer_type p) | | null_ptr (pointer_type p) | |
| { | | { | |
| return p == 0; | | return p == 0; | |
| } | | } | |
| | | | |
|
| // Cast away constness. | | // Casts. | |
| // | | // | |
| static unrestricted_pointer_type | | static unrestricted_pointer_type | |
|
| cast (pointer_type p) | | const_pointer_cast (pointer_type p) | |
| { | | { | |
| return const_cast<unrestricted_pointer_type> (p); | | return const_cast<unrestricted_pointer_type> (p); | |
| } | | } | |
| | | | |
|
| | | template <typename T1> | |
| | | static T1* | |
| | | static_pointer_cast (pointer_type p) | |
| | | { | |
| | | return static_cast<T1*> (p); | |
| | | } | |
| | | | |
| | | template <typename T1> | |
| | | static T1* | |
| | | dynamic_pointer_cast (pointer_type p) | |
| | | { | |
| | | return dynamic_cast<T1*> (p); | |
| | | } | |
| | | | |
| public: | | public: | |
| // Allocate memory for an element that will be managed by this | | // Allocate memory for an element that will be managed by this | |
| // pointer. | | // pointer. | |
| // | | // | |
| static void* | | static void* | |
| allocate (std::size_t n) | | allocate (std::size_t n) | |
| { | | { | |
| return operator new (n); | | return operator new (n); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 176 | | skipping to change at line 194 | |
| { | | { | |
| return *p; | | return *p; | |
| } | | } | |
| | | | |
| static bool | | static bool | |
| null_ptr (const pointer_type& p) | | null_ptr (const pointer_type& p) | |
| { | | { | |
| return p.get () == 0; | | return p.get () == 0; | |
| } | | } | |
| | | | |
|
| // cast() is not provided since it transfers the ownership. | | // const_pointer_cast() is not provided. | |
| | | // | |
| | | | |
| | | // Note: transfers ownership. | |
| | | // | |
| | | template <typename T1> | |
| | | static std::auto_ptr<T1> | |
| | | static_pointer_cast (pointer_type& p) | |
| | | { | |
| | | return std::auto_ptr<T1> (static_cast<T1*> (p.release ())); | |
| | | } | |
| | | | |
| | | // Note: transfers ownership if successful. | |
| | | // | |
| | | template <typename T1> | |
| | | static std::auto_ptr<T1> | |
| | | dynamic_pointer_cast (pointer_type& p) | |
| | | { | |
| | | T1* p1 (dynamic_cast<T1*> (p.get ())); | |
| | | | |
| | | if (p1 != 0) | |
| | | p.release (); | |
| | | | |
| | | return std::auto_ptr<T1> (p1); | |
| | | } | |
| | | | |
| | | public: | |
| | | static void* | |
| | | allocate (std::size_t n) | |
| | | { | |
| | | return operator new (n); | |
| | | } | |
| | | | |
| | | static void | |
| | | free (void* p) | |
| | | { | |
| | | operator delete (p); | |
| | | } | |
| | | }; | |
| | | | |
| | | #ifdef ODB_CXX11 | |
| | | | |
| | | // Specialization for C++11 std::unique_ptr. | |
| | | // | |
| | | template <typename T, typename D> | |
| | | class pointer_traits<std::unique_ptr<T, D>> | |
| | | { | |
| | | public: | |
| | | static const pointer_kind kind = pk_unique; | |
| | | static const bool lazy = false; | |
| | | | |
| | | typedef T element_type; | |
| | | typedef std::unique_ptr<element_type, D> pointer_type; | |
| | | typedef std::unique_ptr<const element_type, D> const_pointer_type; | |
| | | typedef smart_ptr_guard<pointer_type> guard; | |
| | | | |
| | | static element_type* | |
| | | get_ptr (const pointer_type& p) | |
| | | { | |
| | | return p.get (); | |
| | | } | |
| | | | |
| | | static element_type& | |
| | | get_ref (const pointer_type& p) | |
| | | { | |
| | | return *p; | |
| | | } | |
| | | | |
| | | static bool | |
| | | null_ptr (const pointer_type& p) | |
| | | { | |
| | | return !p; | |
| | | } | |
| | | | |
| | | // const_pointer_cast() is not provided. | |
| | | // | |
| | | | |
| | | // Note: transfers ownership. | |
| | | // | |
| | | template <typename T1> | |
| | | static std::unique_ptr<T1> | |
| | | static_pointer_cast (pointer_type& p) | |
| | | { | |
| | | return std::unique_ptr<T1> (static_cast<T1*> (p.release ())); | |
| | | } | |
| | | | |
| | | // Note: transfers ownership if successful. | |
| // | | // | |
|
| | | template <typename T1> | |
| | | static std::unique_ptr<T1> | |
| | | dynamic_pointer_cast (pointer_type& p) | |
| | | { | |
| | | T1* p1 (dynamic_cast<T1*> (p.get ())); | |
| | | | |
| | | if (p1 != 0) | |
| | | p.release (); | |
| | | | |
| | | return std::unique_ptr<T1> (p1); | |
| | | } | |
| | | | |
| | | public: | |
| | | static void* | |
| | | allocate (std::size_t n) | |
| | | { | |
| | | return operator new (n); | |
| | | } | |
| | | | |
| | | static void | |
| | | free (void* p) | |
| | | { | |
| | | operator delete (p); | |
| | | } | |
| | | }; | |
| | | | |
| | | // Specialization for C++11 std::shared_ptr. | |
| | | // | |
| | | template <typename T> | |
| | | class pointer_traits<std::shared_ptr<T>> | |
| | | { | |
| | | public: | |
| | | static const pointer_kind kind = pk_shared; | |
| | | static const bool lazy = false; | |
| | | | |
| | | typedef T element_type; | |
| | | typedef std::shared_ptr<element_type> pointer_type; | |
| | | typedef std::shared_ptr<const element_type> const_pointer_type; | |
| | | typedef typename odb::details::meta::remove_const<element_type>::result | |
| | | unrestricted_element_type; | |
| | | typedef std::shared_ptr<unrestricted_element_type> | |
| | | unrestricted_pointer_type; | |
| | | typedef smart_ptr_guard<pointer_type> guard; | |
| | | | |
| | | static element_type* | |
| | | get_ptr (const pointer_type& p) | |
| | | { | |
| | | return p.get (); | |
| | | } | |
| | | | |
| | | static element_type& | |
| | | get_ref (const pointer_type& p) | |
| | | { | |
| | | return *p; | |
| | | } | |
| | | | |
| | | static bool | |
| | | null_ptr (const pointer_type& p) | |
| | | { | |
| | | return !p; | |
| | | } | |
| | | | |
| | | static unrestricted_pointer_type | |
| | | const_pointer_cast (const pointer_type& p) | |
| | | { | |
| | | return std::const_pointer_cast<unrestricted_element_type> (p); | |
| | | } | |
| | | | |
| | | template <typename T1> | |
| | | static std::shared_ptr<T1> | |
| | | static_pointer_cast (const pointer_type& p) | |
| | | { | |
| | | return std::static_pointer_cast<T1> (p); | |
| | | } | |
| | | | |
| | | template <typename T1> | |
| | | static std::shared_ptr<T1> | |
| | | dynamic_pointer_cast (const pointer_type& p) | |
| | | { | |
| | | return std::dynamic_pointer_cast<T1> (p); | |
| | | } | |
| | | | |
| public: | | public: | |
| static void* | | static void* | |
| allocate (std::size_t n) | | allocate (std::size_t n) | |
| { | | { | |
| return operator new (n); | | return operator new (n); | |
| } | | } | |
| | | | |
| static void | | static void | |
| free (void* p) | | free (void* p) | |
| { | | { | |
| operator delete (p); | | operator delete (p); | |
| } | | } | |
| }; | | }; | |
|
| | | | |
| | | // Specialization for C++11 std::weak_ptr. | |
| | | // | |
| | | template <typename T> | |
| | | class pointer_traits<std::weak_ptr<T>> | |
| | | { | |
| | | public: | |
| | | static const pointer_kind kind = pk_weak; | |
| | | static const bool lazy = false; | |
| | | | |
| | | typedef T element_type; | |
| | | typedef std::weak_ptr<element_type> pointer_type; | |
| | | typedef std::shared_ptr<element_type> strong_pointer_type; | |
| | | | |
| | | static strong_pointer_type | |
| | | lock (const pointer_type& p) | |
| | | { | |
| | | return p.lock (); | |
| | | } | |
| | | }; | |
| | | | |
| | | #endif // ODB_CXX11 | |
| | | | |
| } | | } | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_POINTER_TRAITS_HXX | | #endif // ODB_POINTER_TRAITS_HXX | |
| | | | |
End of changes. 10 change blocks. |
| 5 lines changed or deleted | | 213 lines changed or added | |
|