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 executed 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 dispose function and using default constructed value. */
112 explicit AutoDispose( const Dispose & dispose_r )
113 : _pimpl( new Impl( value_type(), dispose_r ) )
116 /** Ctor taking value and no dispose function. */
117 explicit AutoDispose( param_type value_r )
118 : _pimpl( new Impl( value_r ) )
121 /** Ctor taking value and dispose function. */
122 AutoDispose( param_type value_r, const Dispose & dispose_r )
123 : _pimpl( new Impl( value_r, dispose_r ) )
128 /** Provide implicit conversion to \c Tp\&. */
129 operator reference() const
130 { return _pimpl->_value; }
132 /** Reference to the \c Tp object. */
133 reference value() const
134 { return _pimpl->_value; }
136 /** Reference to the \c Tp object. */
137 reference operator*() const
138 { return _pimpl->_value; }
140 /** Pointer to the \c Tp object (asserted to be <tt>!= NULL</tt>). */
141 value_type * operator->() const
142 { return & _pimpl->_value; }
144 /** Reset to default Ctor values. */
146 { AutoDispose().swap( *this ); }
148 /** Exchange the contents of two AutoDispose objects. */
149 void swap( AutoDispose & rhs )
150 { _pimpl.swap( rhs._pimpl ); }
153 /** Return the current dispose function. */
154 const Dispose & getDispose() const
155 { return _pimpl->_dispose; }
157 /** Set a new dispose function. */
158 void setDispose( const Dispose & dispose_r )
159 { _pimpl->_dispose = dispose_r; }
161 /** Set no dispose function. */
163 { setDispose( Dispose() ); }
165 /** Exchange the dispose function. +*/
166 void swapDispose( Dispose & dispose_r )
167 { _pimpl->_dispose.swap( dispose_r ); }
170 struct Impl : private base::NonCopyable
172 Impl( param_type value_r )
175 Impl( param_type value_r, const Dispose & dispose_r )
177 , _dispose( dispose_r )
182 try { _dispose( _value ); } catch(...) {}
188 shared_ptr<Impl> _pimpl;
190 ///////////////////////////////////////////////////////////////////
192 /** \relates AutoDispose Stream output of the \c Tp object. */
194 inline std::ostream & operator<<( std::ostream & str, const AutoDispose<Tp> & obj )
195 { return str << obj.value(); }
197 /////////////////////////////////////////////////////////////////
199 ///////////////////////////////////////////////////////////////////
200 #endif // ZYPP_AUTODISPOSE_H