00001 //------------------------------------------------------------------------------ 00002 // Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN) 00003 // Author: Lukasz Janyst <ljanyst@cern.ch> 00004 //------------------------------------------------------------------------------ 00005 // XRootD is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // XRootD is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with XRootD. If not, see <http://www.gnu.org/licenses/>. 00017 //------------------------------------------------------------------------------ 00018 00019 #ifndef __XRD_CL_ANY_OBJECT_HH__ 00020 #define __XRD_CL_ANY_OBJECT_HH__ 00021 00022 #include <typeinfo> 00023 #include <cstring> 00024 00025 namespace XrdCl 00026 { 00027 //---------------------------------------------------------------------------- 00031 //---------------------------------------------------------------------------- 00032 class AnyObject 00033 { 00034 public: 00035 //------------------------------------------------------------------------ 00037 //------------------------------------------------------------------------ 00038 AnyObject(): pHolder(0), pTypeInfo(0), pOwn( true ) {}; 00039 00040 //------------------------------------------------------------------------ 00042 //------------------------------------------------------------------------ 00043 ~AnyObject() 00044 { 00045 if( pHolder && pOwn ) 00046 pHolder->Delete(); 00047 delete pHolder; 00048 } 00049 00050 //------------------------------------------------------------------------ 00058 //------------------------------------------------------------------------ 00059 template <class Type> void Set( Type object, bool own = true ) 00060 { 00061 if( !object ) 00062 { 00063 delete pHolder; 00064 pHolder = 0; 00065 pTypeInfo = 0; 00066 return; 00067 } 00068 00069 delete pHolder; 00070 pHolder = new ConcreteHolder<Type>( object ); 00071 pOwn = own; 00072 pTypeInfo = &typeid( Type ); 00073 } 00074 00075 //------------------------------------------------------------------------ 00077 //------------------------------------------------------------------------ 00078 template <class Type> void Get( Type &object ) 00079 { 00080 if( !pHolder || (strcmp( pTypeInfo->name(), typeid( Type ).name() )) ) 00081 { 00082 object = 0; 00083 return; 00084 } 00085 object = static_cast<Type>( pHolder->Get() ); 00086 } 00087 00088 //------------------------------------------------------------------------ 00090 //------------------------------------------------------------------------ 00091 bool HasOwnership() const 00092 { 00093 return pOwn; 00094 } 00095 00096 private: 00097 //------------------------------------------------------------------------ 00098 // Abstract holder object 00099 //------------------------------------------------------------------------ 00100 class Holder 00101 { 00102 public: 00103 virtual ~Holder() {} 00104 virtual void Delete() = 0; 00105 virtual void *Get() = 0; 00106 }; 00107 00108 //------------------------------------------------------------------------ 00109 // Concrete holder 00110 //------------------------------------------------------------------------ 00111 template<class Type> 00112 class ConcreteHolder: public Holder 00113 { 00114 public: 00115 ConcreteHolder( Type object ): pObject( object ) {} 00116 virtual void Delete() 00117 { 00118 delete pObject; 00119 } 00120 00121 virtual void *Get() 00122 { 00123 return (void *)pObject; 00124 } 00125 00126 private: 00127 Type pObject; 00128 }; 00129 00130 Holder *pHolder; 00131 const std::type_info *pTypeInfo; 00132 bool pOwn; 00133 }; 00134 } 00135 00136 #endif // __XRD_CL_ANY_OBJECT_HH__