1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/AutoDispose.h
12 #ifndef ZYPP_AUTODISPOSE_H
13 #define ZYPP_AUTODISPOSE_H
16 #include <boost/call_traits.hpp>
18 #include "zypp/base/NonCopyable.h"
19 #include "zypp/base/PtrTypes.h"
20 #include "zypp/base/Function.h"
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////
28 // CLASS NAME : AutoDispose<_Tp>
30 /** Reference counted access to a \c _Tp object calling a custom
31 * \c Dispose function when the last AutoDispose handle to it is
34 * \note As with pointers, constness of an \c AutoDispose object does
35 * \b not apply to the stored \c _Tp object. If the stored \c _Tp object
36 * should be immutable, you should use <tt>AutoDispose\<const _Tp\></tt>.
38 * Pass a filename to the application and provide the appropriate
39 * code to be exectued when the file is no longer needed:
44 * void releaseFile( const Pathname & );
47 * static FileCache cache;
49 * void unlink( const Pathname & file_r );
51 * AutoDispose<const Pathname> provideFile( ... )
53 * if ( file_is_in_cache )
55 * // will call 'cache.releaseFile( file )'
56 * return AutoDispose<const Pathname>( cache.getFile(),
57 * bind( &FileCache::releaseFile, ref(cache), _1 ) );
59 * else if ( file_is_temporary )
61 * // will call 'unlink( file )'
62 * return AutoDispose<const Pathname>( file, unlink );
64 * else if ( file_is_permanent )
67 * return AutoDispose<const Pathname>( file );
72 * return AutoDispose<const Pathname>();
77 * Exception safe handling of temporary files:
79 * void provideFileAt( const Pathname & destination )
81 * AutoDispose<const Pathname> guard( destination, unlink );
83 * // Any exception here will lead to 'unlink( destination )'
86 * // On success: reset the dispose function to NOOP.
87 * guard.resetDispose();
95 typedef typename boost::call_traits<_Tp>::param_type param_type;
96 typedef typename boost::call_traits<_Tp>::reference reference;
97 typedef typename boost::call_traits<_Tp>::const_reference const_reference;
98 typedef _Tp value_type;
99 typedef typename boost::call_traits<_Tp>::value_type result_type;
102 /** Dispose function signatue. */
103 typedef function<void ( param_type )> Dispose;
106 /** Default Ctor using default constructed value and no dispose function. */
108 : _pimpl( new Impl( value_type() ) )
111 /** Ctor taking value and no dispose function. */
112 AutoDispose( param_type value_r )
113 : _pimpl( new Impl( value_r ) )
116 /** Ctor taking value and dispose function. */
117 AutoDispose( param_type value_r, const Dispose & dispose_r )
118 : _pimpl( new Impl( value_r, dispose_r ) )
123 /** Provide implicit conversion to \c _Tp\&. */
124 operator reference() const
125 { return _pimpl->_value; }
127 /** Reference to the \c _Tp object. */
128 reference value() const
129 { return _pimpl->_value; }
131 /** Reference to the \c _Tp object. */
132 reference operator*() const
133 { return _pimpl->_value; }
135 /** Pointer to the \c _Tp object (asserted to be <tt>!= NULL</tt>). */
136 value_type * operator->() const
137 { return & _pimpl->_value; }
139 /** Reset to default Ctor values. */
141 { AutoDispose().swap( *this ); }
143 /** Exchange the contents of two AutoDispose objects. */
144 void swap( AutoDispose & rhs )
145 { _pimpl.swap( rhs._pimpl ); }
148 /** Return the current dispose function. */
149 const Dispose & getDispose() const
150 { return _pimpl->_dispose; }
152 /** Set a new dispose function. */
153 void setDispose( const Dispose & dispose_r )
154 { _pimpl->_dispose = dispose_r; }
156 /** Set no dispose function. */
158 { setDispose( Dispose() ); }
160 /** Exchange the dispose function. +*/
161 void swapDispose( Dispose & dispose_r )
162 { _pimpl->_dispose.swap( dispose_r ); }
165 struct Impl : private base::NonCopyable
167 Impl( param_type value_r )
170 Impl( param_type value_r, const Dispose & dispose_r )
172 , _dispose( dispose_r )
177 try { _dispose( _value ); } catch(...) {}
183 shared_ptr<Impl> _pimpl;
185 ///////////////////////////////////////////////////////////////////
187 /** \relates AutoDispose<_Tp> Stream output of the \c _Tp object. */
189 inline std::ostream & operator<<( std::ostream & str, const AutoDispose<_Tp> & obj )
190 { return str << obj.value(); }
192 /////////////////////////////////////////////////////////////////
194 ///////////////////////////////////////////////////////////////////
195 #endif // ZYPP_AUTODISPOSE_H