00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #ifndef ZYPP_AUTODISPOSE_H 00013 #define ZYPP_AUTODISPOSE_H 00014 00015 #include <iosfwd> 00016 #include <boost/call_traits.hpp> 00017 00018 #include "zypp/base/NonCopyable.h" 00019 #include "zypp/base/PtrTypes.h" 00020 #include "zypp/base/Function.h" 00021 00023 namespace zypp 00024 { 00025 00027 // 00028 // CLASS NAME : AutoDispose<_Tp> 00029 // 00091 template<class _Tp> 00092 class AutoDispose 00093 { 00094 public: 00095 typedef typename boost::call_traits<_Tp>::param_type param_type; 00096 typedef typename boost::call_traits<_Tp>::reference reference; 00097 typedef typename boost::call_traits<_Tp>::const_reference const_reference; 00098 typedef _Tp value_type; 00099 typedef typename boost::call_traits<_Tp>::value_type result_type; 00100 00101 public: 00103 typedef function<void ( param_type )> Dispose; 00104 00106 static void nodispose( param_type ) {} 00107 00108 public: 00110 AutoDispose() 00111 : _pimpl( new Impl( value_type(), nodispose ) ) 00112 {} 00113 00115 AutoDispose( param_type value_r ) 00116 : _pimpl( new Impl( value_r, nodispose ) ) 00117 {} 00118 00120 AutoDispose( param_type value_r, const Dispose & dispose_r ) 00121 : _pimpl( new Impl( value_r, dispose_r ) ) 00122 {} 00123 00124 public: 00125 00127 operator reference() const 00128 { return _pimpl->_value; } 00129 00131 reference value() const 00132 { return _pimpl->_value; } 00133 00135 reference operator*() const 00136 { return _pimpl->_value; } 00137 00139 value_type * operator->() const 00140 { return & _pimpl->_value; } 00141 00143 void reset() 00144 { AutoDispose().swap( *this ); } 00145 00147 void swap( AutoDispose & rhs ) 00148 { _pimpl.swap( rhs._pimpl ); } 00149 00150 public: 00152 const Dispose & getDispose() const 00153 { return _pimpl->_dispose; } 00154 00156 void setDispose( const Dispose & dispose_r ) 00157 { _pimpl->_dispose = dispose_r; } 00158 00160 void resetDispose() 00161 { setDispose( nodispose ); } 00162 00164 void swapDispose( Dispose & dispose_r ) 00165 { _pimpl->_dispose.swap( dispose_r ); } 00166 00167 private: 00168 struct Impl : private base::NonCopyable 00169 { 00170 Impl( param_type value_r, const Dispose & dispose_r ) 00171 : _value( value_r ) 00172 , _dispose( dispose_r ) 00173 {} 00174 ~Impl() 00175 { 00176 if ( _dispose != nodispose ) 00177 try { _dispose( _value ); } catch(...) {} 00178 } 00179 value_type _value; 00180 Dispose _dispose; 00181 }; 00182 00183 shared_ptr<Impl> _pimpl; 00184 }; 00186 00188 template<class _Tp> 00189 inline std::ostream & operator<<( std::ostream & str, const AutoDispose<_Tp> & obj ) 00190 { return str << obj.value(); } 00191 00193 } // namespace zypp 00195 #endif // ZYPP_AUTODISPOSE_H
1.4.6