ObjectPtr.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *
00003  * Copyright (C) 2009-2011 Cassio Neri Moreira
00004  *
00005  * This file is part of the KeyValue library.
00006  *
00007  * The KeyValue library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License as published
00009  * by the Free Software Foundation, either version 3 of the License, or (at
00010  * your option) any later version.
00011  *
00012  * The KeyValue library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
00015  * Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License along
00018  * with KeyValue. If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  * If you modify this library, or any covered work, by linking or combining
00021  * it with Excel (or a modified version of that program), containing parts
00022  * covered by the terms of End-User License Agreement for Microsoft
00023  * Software, the licensors of KeyValue grant you additional permission to
00024  * convey the resulting work.
00025  *
00026  **************************************************************************/
00027 
00034 #ifndef KEYVALUE_VALUE_OBJECTPTR_H_
00035 #define KEYVALUE_VALUE_OBJECTPTR_H_
00036 
00037 #include <boost/type_traits/is_base_of.hpp>
00038 #include <boost/utility/enable_if.hpp>
00039 
00040 #include "keyvalue/extern/SharedPtr.h"
00041 #include "keyvalue/value/Object.h"
00042 #include "keyvalue/value/PtrTraits.h"
00043 
00044 namespace keyvalue {
00045 namespace value {
00046 
00062 class ObjectPtr {
00063 
00064 public:
00065 
00072   ObjectPtr();
00073 
00080   template <typename ObjectType>
00081   ObjectPtr(const shared_ptr<ObjectType>& ptr, typename
00082     ::boost::enable_if< ::boost::is_base_of<Object, ObjectType> >::type*
00083     dummy = 0);
00084 
00095   template <typename ObjectType, template <typename> class SmartPtr>
00096   ObjectPtr(const SmartPtr<ObjectType>& ptr, typename
00097     ::boost::disable_if< ::boost::is_base_of<Object, ObjectType> >::type*
00098     dummy = 0);
00099 
00107   template <typename Rhs>
00108   ObjectPtr(const Rhs& rhs);
00109 
00119   template <typename Rhs>
00120   ObjectPtr&
00121   operator =(const Rhs& rhs);
00122 
00128   operator bool() const;
00129 
00140   template <typename ObjectType>
00141   shared_ptr<ObjectType>
00142   cast(typename
00143     ::boost::enable_if< ::boost::is_base_of<Object, ObjectType> >::type*
00144     dummy = 0) const;
00145 
00156   template <typename ObjectType>
00157   typename PtrTraits<ObjectType>::Type_
00158   cast(typename 
00159     ::boost::disable_if< ::boost::is_base_of<Object, ObjectType> >::type*
00160     dummy = 0) const;
00161 
00162 private:
00163 
00169   void
00170   swap(ObjectPtr& other);
00171 
00172   shared_ptr<Object>     kvPtr_; // Pointer to KeyValue objects.
00173   PtrTraits<void>::Type_ ptr_;   // Pointer to users objects.
00174 
00175 }; // class ObjectPtr
00176 
00177 /*
00178  * ATTENTION: If you make changes here, please, update doc in Parent.h
00179  *
00180  * In value hierarchy:
00181  *
00182  *  ObjectPtr
00183  *  +- shared_ptr<Object>
00184  *  |  `- Object*
00185  *  `- PtrTraits<ObjectType>::Type_
00186  *     `- ObjectType*
00187  */
00188 
00189 template <typename Rhs>
00190 struct Parent;
00191 
00192 template <typename ObjectType, template <typename> class SmartPtr>
00193 struct Parent<SmartPtr<ObjectType> > {
00194   typedef ObjectPtr Type_;
00195 };
00196 
00197 template <typename ObjectType,
00198   bool isObject = ::boost::is_base_of<Object, ObjectType>::value>
00199 struct PointerParent;
00200 
00201 template <typename ObjectType>
00202 struct PointerParent<ObjectType, true> {
00203   typedef shared_ptr<Object> Type_;
00204 };
00205 
00206 template <typename ObjectType>
00207 struct PointerParent<ObjectType, false> {
00208   typedef typename PtrTraits<ObjectType>::Type_ Type_;
00209 };
00210 
00211 template <typename ObjectType>
00212 struct Parent<ObjectType*> {
00213   typedef typename PointerParent<ObjectType>::Type_ Type_;
00214 };
00215 
00216 /*--------------------------------------------------------------------------
00217  * ObjectPtr::ObjectPtr()
00218  *------------------------------------------------------------------------*/
00219 
00220 template <typename ObjectType>
00221 ObjectPtr::ObjectPtr(const shared_ptr<ObjectType>& ptr, typename
00222   ::boost::enable_if< ::boost::is_base_of<Object, ObjectType> >::type*) :
00223   kvPtr_(ptr) {
00224 }
00225 
00226 template <typename ObjectType, template <typename> class SmartPtr>
00227 ObjectPtr::ObjectPtr(const SmartPtr<ObjectType>& ptr, typename 
00228   ::boost::disable_if< ::boost::is_base_of<Object, ObjectType> >::type*) :
00229   ptr_(ptr) {
00230 }
00231 
00232 template <typename Rhs>
00233 ObjectPtr::ObjectPtr(const Rhs& rhs) {
00234 
00235   /*
00236    * If you get an error here about 'keyvalue::value::Parent<Rhs>', this
00237    * means that Rhs isn't in a lower level in the hierarchy.
00238    */
00239 
00240   typename Parent<Rhs>::Type_ tmp(rhs);
00241   ObjectPtr other(tmp);
00242   swap(other);
00243 }
00244 
00245 /*--------------------------------------------------------------------------
00246  * operator =()
00247  *------------------------------------------------------------------------*/
00248 
00249 template <typename Rhs>
00250 ObjectPtr&
00251 ObjectPtr::operator =(const Rhs& rhs) {
00252 
00253   /*
00254    * If you get an error here about 'keyvalue::value::Parent<P>', this
00255    * means that Rhs isn't in a lower level in the hierarchy.
00256    */
00257 
00258   return *this = typename Parent<Rhs>::Type_(rhs);
00259 }
00260 
00261 /*--------------------------------------------------------------------------
00262  * cast()
00263  *------------------------------------------------------------------------*/
00264 
00265 template <typename ObjectType>
00266 shared_ptr<ObjectType>
00267 ObjectPtr::cast(typename
00268   ::boost::enable_if< ::boost::is_base_of<Object, ObjectType> >::type*)
00269   const {
00270   return dynamic_pointer_cast<ObjectType>(kvPtr_);
00271 }
00272 
00273 template <typename ObjectType>
00274 typename PtrTraits<ObjectType>::Type_
00275 ObjectPtr::cast(typename
00276   ::boost::disable_if< ::boost::is_base_of<Object, ObjectType> >::type*)
00277   const {
00278   return dynamic_pointer_cast<ObjectType>(ptr_);
00279 }
00280 
00281 } // namespace value
00282 } // namespace keyvalue
00283 
00284 #endif // KEYVALUE_VALUE_OBJECTPTR_H_