// file : odb/pointer-traits.hxx // copyright : Copyright (c) 2009-2017 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_POINTER_TRAITS_HXX #define ODB_POINTER_TRAITS_HXX #include #include // operators new/delete #include // std::auto_ptr, std::unique_ptr, std::shared_ptr/weak_ptr #include // std::size_t #include // ODB_CXX11 #include namespace odb { enum pointer_kind { pk_raw, // Raw pointer or equivalent (i.e., unmanaged). pk_unique, // Smart pointer that doesn't support sharing. pk_shared, // Smart pointer that supports sharing. pk_weak // Weak counterpart for shared pointer. }; template class pointer_traits; // // Standard pointer guards. // // Raw pointer guard. // template class raw_ptr_guard { public: ~raw_ptr_guard () {delete p_;} raw_ptr_guard (): p_ (0) {} explicit raw_ptr_guard (P p): p_ (p) {} void release () {p_ = 0;} void reset (P p = 0) {delete p_; p_ = p;} private: P p_; }; // No-op pointer guard for smart pointers. // template class smart_ptr_guard { public: smart_ptr_guard () {} explicit smart_ptr_guard (const P&) {} void release () {} void reset () {} void reset (const P&) {} }; // Specialization for raw pointers. // template class pointer_traits { public: static const pointer_kind kind = pk_raw; static const bool lazy = false; typedef T element_type; typedef T* pointer_type; typedef const T* const_pointer_type; typedef typename odb::details::meta::remove_const::result* unrestricted_pointer_type; typedef raw_ptr_guard guard; // Return raw pointer to the pointed-to element, including NULL. // static element_type* get_ptr (pointer_type p) { return p; } // Return reference to the pointed-to element. // static element_type& get_ref (pointer_type p) { return *p; } // Return true if the pointer is NULL. // static bool null_ptr (pointer_type p) { return p == 0; } // Casts. // static unrestricted_pointer_type const_pointer_cast (pointer_type p) { return const_cast (p); } template static T1* static_pointer_cast (pointer_type p) { return static_cast (p); } template static T1* dynamic_pointer_cast (pointer_type p) { return dynamic_cast (p); } public: // Allocate memory for an element that will be managed by this // pointer. // static void* allocate (std::size_t n) { return operator new (n); } // Free memory allocated for an element. This functions is only // called if the constructor of the element being created fails. // Otherwise, the pointer (or guard) is used to delete the object // and free the memory. This behavior is identical to the one // used by operator delete overloading. // static void free (void* p) { operator delete (p); } }; // Specialization for std::auto_ptr. // #ifndef ODB_CXX11 template class pointer_traits< std::auto_ptr > { public: static const pointer_kind kind = pk_unique; static const bool lazy = false; typedef T element_type; typedef std::auto_ptr pointer_type; typedef std::auto_ptr const_pointer_type; typedef smart_ptr_guard 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.get () == 0; } // const_pointer_cast() is not provided. // // Note: transfers ownership. // template static std::auto_ptr static_pointer_cast (pointer_type& p) { return std::auto_ptr (static_cast (p.release ())); } // Note: transfers ownership if successful. // template static std::auto_ptr dynamic_pointer_cast (pointer_type& p) { T1* p1 (dynamic_cast (p.get ())); if (p1 != 0) p.release (); return std::auto_ptr (p1); } public: static void* allocate (std::size_t n) { return operator new (n); } static void free (void* p) { operator delete (p); } }; #endif #ifdef ODB_CXX11 // Specialization for C++11 std::unique_ptr. // template class D> class pointer_traits>> { public: static const pointer_kind kind = pk_unique; static const bool lazy = false; typedef T element_type; typedef std::unique_ptr> pointer_type; typedef std::unique_ptr> const_pointer_type; typedef smart_ptr_guard 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 static std::unique_ptr> static_pointer_cast (pointer_type& p) { return std::unique_ptr> (static_cast (p.release ())); } // Note: transfers ownership if successful. // template static std::unique_ptr> dynamic_pointer_cast (pointer_type& p) { T1* p1 (dynamic_cast (p.get ())); if (p1 != 0) p.release (); return std::unique_ptr> (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 class pointer_traits> { public: static const pointer_kind kind = pk_shared; static const bool lazy = false; typedef T element_type; typedef std::shared_ptr pointer_type; typedef std::shared_ptr const_pointer_type; typedef typename odb::details::meta::remove_const::result unrestricted_element_type; typedef std::shared_ptr unrestricted_pointer_type; typedef smart_ptr_guard 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 (p); } template static std::shared_ptr static_pointer_cast (const pointer_type& p) { return std::static_pointer_cast (p); } template static std::shared_ptr dynamic_pointer_cast (const pointer_type& p) { return std::dynamic_pointer_cast (p); } 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::weak_ptr. // template class pointer_traits> { public: static const pointer_kind kind = pk_weak; static const bool lazy = false; typedef T element_type; typedef std::weak_ptr pointer_type; typedef std::shared_ptr strong_pointer_type; static strong_pointer_type lock (const pointer_type& p) { return p.lock (); } }; #endif // ODB_CXX11 } #include #endif // ODB_POINTER_TRAITS_HXX