00001 /* 00002 * XrdClFwd.hh 00003 * 00004 * Created on: Oct 19, 2018 00005 * Author: simonm 00006 */ 00007 00008 #ifndef SRC_XRDCL_XRDCLFWD_HH_ 00009 #define SRC_XRDCL_XRDCLFWD_HH_ 00010 00011 #include <memory> 00012 #include <stdexcept> 00013 00014 namespace XrdCl 00015 { 00016 //---------------------------------------------------------------------------- 00022 //---------------------------------------------------------------------------- 00023 template<typename T> 00024 struct FwdStorage 00025 { 00026 //-------------------------------------------------------------------------- 00028 //-------------------------------------------------------------------------- 00029 FwdStorage() : ptr( nullptr ) { } 00030 00031 //-------------------------------------------------------------------------- 00034 //-------------------------------------------------------------------------- 00035 FwdStorage( const T &value ) : ptr( new( &storage.memory ) T( value ) ) 00036 { 00037 } 00038 00039 //-------------------------------------------------------------------------- 00042 //-------------------------------------------------------------------------- 00043 FwdStorage& operator=( const T &value ) 00044 { 00045 if( ptr ) throw std::logic_error( "XrdCl::Fwd already contains value." ); 00046 ptr = new( &storage.memory ) T( value ); 00047 return *this; 00048 } 00049 00050 //-------------------------------------------------------------------------- 00053 //-------------------------------------------------------------------------- 00054 FwdStorage( T && value ) : ptr( new( &storage.memory ) T( std::move( value ) ) ) 00055 { 00056 } 00057 00058 //-------------------------------------------------------------------------- 00061 //-------------------------------------------------------------------------- 00062 FwdStorage& operator=( T && value ) 00063 { 00064 if( ptr ) throw std::logic_error( "XrdCl::Fwd already contains value." ); 00065 ptr = new( &storage.memory ) T( std::move( value ) ); 00066 return *this; 00067 } 00068 00069 //-------------------------------------------------------------------------- 00071 //-------------------------------------------------------------------------- 00072 ~FwdStorage() 00073 { 00074 if( ptr ) ptr->~T(); 00075 } 00076 00077 //-------------------------------------------------------------------------- 00079 //-------------------------------------------------------------------------- 00080 union Memory 00081 { 00082 //------------------------------------------------------------------------ 00084 //------------------------------------------------------------------------ 00085 Memory() { } 00086 00087 //------------------------------------------------------------------------ 00089 //------------------------------------------------------------------------ 00090 ~Memory() { } 00091 00092 //------------------------------------------------------------------------ 00094 //------------------------------------------------------------------------ 00095 T memory; 00096 }; 00097 00098 //-------------------------------------------------------------------------- 00100 //-------------------------------------------------------------------------- 00101 Memory storage; 00102 00103 //-------------------------------------------------------------------------- 00105 //-------------------------------------------------------------------------- 00106 T *ptr; 00107 }; 00108 00109 //---------------------------------------------------------------------------- 00115 //---------------------------------------------------------------------------- 00116 template<typename T> 00117 class Fwd : protected std::shared_ptr<FwdStorage<T>> 00118 { 00119 public: 00120 00121 //------------------------------------------------------------------------ 00126 //------------------------------------------------------------------------ 00127 Fwd() : std::shared_ptr<FwdStorage<T>>( new FwdStorage<T>() ) 00128 { 00129 } 00130 00131 //------------------------------------------------------------------------ 00133 //------------------------------------------------------------------------ 00134 Fwd( const Fwd &fwd ) : std::shared_ptr<FwdStorage<T>>( fwd ) 00135 { 00136 } 00137 00138 //------------------------------------------------------------------------ 00140 //------------------------------------------------------------------------ 00141 Fwd( Fwd && fwd ) : std::shared_ptr<FwdStorage<T>>( std::move( fwd ) ) 00142 { 00143 } 00144 00145 //------------------------------------------------------------------------ 00151 //------------------------------------------------------------------------ 00152 const Fwd& operator=( const T &value ) const 00153 { 00154 *this->get() = value; 00155 return *this; 00156 } 00157 00158 //------------------------------------------------------------------------ 00164 //------------------------------------------------------------------------ 00165 const Fwd& operator=( T && value ) const 00166 { 00167 *this->get() = std::move( value ); 00168 return *this; 00169 } 00170 00171 //------------------------------------------------------------------------ 00177 //------------------------------------------------------------------------ 00178 T& operator*() const 00179 { 00180 if( !bool( this->get()->ptr ) ) throw std::logic_error( "XrdCl::Fwd contains no value!" ); 00181 return *this->get()->ptr; 00182 } 00183 00184 //------------------------------------------------------------------------ 00190 //------------------------------------------------------------------------ 00191 T* operator->() const 00192 { 00193 if( !bool( this->get()->ptr ) ) throw std::logic_error( "XrdCl::Fwd contains no value!" ); 00194 return this->get()->ptr; 00195 } 00196 00197 }; 00198 } 00199 00200 00201 #endif /* SRC_XRDCL_XRDCLFWD_HH_ */