- Create the cache directly from the schema (installed) file.
[platform/upstream/libzypp.git] / zypp / AutoDispose.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/AutoDispose.h
10  *
11 */
12 #ifndef ZYPP_AUTODISPOSE_H
13 #define ZYPP_AUTODISPOSE_H
14
15 #include <iosfwd>
16 #include <boost/call_traits.hpp>
17
18 #include "zypp/base/NonCopyable.h"
19 #include "zypp/base/PtrTypes.h"
20 #include "zypp/base/Function.h"
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 { /////////////////////////////////////////////////////////////////
25
26   ///////////////////////////////////////////////////////////////////
27   //
28   //    CLASS NAME : AutoDispose<_Tp>
29   //
30   /** Reference counted access to a \c _Tp object calling a custom
31    *  \c Dispose function when the last AutoDispose handle to it is
32    *  destroyed or reset.
33    *
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>.
37    *
38    * Pass a filename to the application and provide the appropriate
39    * code to be exectued when the file is no longer needed:
40    * \code
41    * struct FileCache
42    * {
43    *   Pathname getFile();
44    *   void     releaseFile( const Pathname & );
45    * };
46    *
47    * static FileCache cache;
48    *
49    * void unlink( const Pathname & file_r );
50    *
51    * AutoDispose<const Pathname> provideFile( ... )
52    * {
53    *   if ( file_is_in_cache )
54    *     {
55    *       // will call 'cache.releaseFile( file )'
56    *       return AutoDispose<const Pathname>( cache.getFile(),
57    *                                           bind( &FileCache::releaseFile, ref(cache), _1 ) );
58    *     }
59    *   else if ( file_is_temporary )
60    *     {
61    *       // will call 'unlink( file )'
62    *       return AutoDispose<const Pathname>( file, unlink );
63    *     }
64    *   else if ( file_is_permanent )
65    *     {
66    *       // will do nothing.
67    *       return AutoDispose<const Pathname>( file );
68    *     }
69    *   else
70    *     {
71    *       // will do nothing.
72    *       return AutoDispose<const Pathname>();
73    *     }
74    * }
75    * \endcode
76    *
77    * Exception safe handling of temporary files:
78    * \code
79    * void provideFileAt( const Pathname & destination )
80    * {
81    *   AutoDispose<const Pathname> guard( destination, unlink );
82    *
83    *   // Any exception here will lead to 'unlink( destination )'
84    *   // ...
85    *
86    *   // On success: reset the dispose function to NOOP.
87    *   guard.resetDispose();
88    * }
89    * \endcode
90   */
91   template<class _Tp>
92     class AutoDispose
93     {
94     public:
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;
100
101     public:
102       /** Dispose function signatue. */
103       typedef function<void ( param_type )> Dispose;
104
105     public:
106       /** Default Ctor using default constructed value and no dispose function. */
107       AutoDispose()
108       : _pimpl( new Impl( value_type() ) )
109       {}
110
111       /** Ctor taking value and no dispose function. */
112       AutoDispose( param_type value_r )
113       : _pimpl( new Impl( value_r ) )
114       {}
115
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 ) )
119       {}
120
121     public:
122
123       /** Provide implicit conversion to \c _Tp\&. */
124       operator reference() const
125       { return _pimpl->_value; }
126
127       /** Reference to the \c _Tp object. */
128       reference value() const
129       { return _pimpl->_value; }
130
131       /** Reference to the \c _Tp object. */
132       reference operator*() const
133       { return _pimpl->_value; }
134
135       /** Pointer to the \c _Tp object (asserted to be <tt>!= NULL</tt>). */
136       value_type * operator->() const
137       { return & _pimpl->_value; }
138
139       /** Reset to default Ctor values. */
140       void reset()
141       { AutoDispose().swap( *this ); }
142
143       /** Exchange the contents of two AutoDispose objects. */
144       void swap( AutoDispose & rhs )
145       { _pimpl.swap( rhs._pimpl ); }
146
147     public:
148       /** Return the current dispose function. */
149       const Dispose & getDispose() const
150       { return _pimpl->_dispose; }
151
152       /** Set a new dispose function. */
153       void setDispose( const Dispose & dispose_r )
154       { _pimpl->_dispose = dispose_r; }
155
156       /** Set no dispose function. */
157       void resetDispose()
158       { setDispose( Dispose() ); }
159
160       /** Exchange the dispose function. +*/
161       void swapDispose( Dispose & dispose_r )
162       { _pimpl->_dispose.swap( dispose_r ); }
163
164     private:
165       struct Impl : private base::NonCopyable
166       {
167         Impl( param_type value_r )
168         : _value( value_r )
169         {}
170         Impl( param_type value_r, const Dispose & dispose_r )
171         : _value( value_r )
172         , _dispose( dispose_r )
173         {}
174         ~Impl()
175         {
176           if ( _dispose )
177             try { _dispose( _value ); } catch(...) {}
178         }
179         value_type _value;
180         Dispose    _dispose;
181       };
182
183       shared_ptr<Impl> _pimpl;
184     };
185   ///////////////////////////////////////////////////////////////////
186
187   /** \relates AutoDispose<_Tp> Stream output of the \c _Tp object. */
188   template<class _Tp>
189     inline std::ostream & operator<<( std::ostream & str, const AutoDispose<_Tp> & obj )
190     { return str << obj.value(); }
191
192   /////////////////////////////////////////////////////////////////
193 } // namespace zypp
194 ///////////////////////////////////////////////////////////////////
195 #endif // ZYPP_AUTODISPOSE_H