libzypp  17.14.0
AutoDispose.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
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 
23 namespace zypp
24 {
25 
27  //
28  // CLASS NAME : AutoDispose<Tp>
29  //
91  template<class Tp>
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:
103  typedef function<void ( param_type )> Dispose;
104 
105  public:
108  : _pimpl( new Impl( value_type() ) )
109  {}
110 
112  explicit AutoDispose( const Dispose & dispose_r )
113  : _pimpl( new Impl( value_type(), dispose_r ) )
114  {}
115 
117  explicit AutoDispose( param_type value_r )
118  : _pimpl( new Impl( value_r ) )
119  {}
120 
122  AutoDispose( param_type value_r, const Dispose & dispose_r )
123  : _pimpl( new Impl( value_r, dispose_r ) )
124  {}
125 
126  public:
127 
129  operator reference() const
130  { return _pimpl->_value; }
131 
133  reference value() const
134  { return _pimpl->_value; }
135 
138  { return _pimpl->_value; }
139 
142  { return & _pimpl->_value; }
143 
145  void reset()
146  { AutoDispose().swap( *this ); }
147 
149  void swap( AutoDispose & rhs )
150  { _pimpl.swap( rhs._pimpl ); }
151 
152  public:
154  const Dispose & getDispose() const
155  { return _pimpl->_dispose; }
156 
158  void setDispose( const Dispose & dispose_r )
159  { _pimpl->_dispose = dispose_r; }
160 
163  { setDispose( Dispose() ); }
164 
166  void swapDispose( Dispose & dispose_r )
167  { _pimpl->_dispose.swap( dispose_r ); }
168 
169  private:
170  struct Impl : private base::NonCopyable
171  {
172  Impl( param_type value_r )
173  : _value( value_r )
174  {}
175  Impl( param_type value_r, const Dispose & dispose_r )
176  : _value( value_r )
177  , _dispose( dispose_r )
178  {}
180  {
181  if ( _dispose )
182  try { _dispose( _value ); } catch(...) {}
183  }
186  };
187 
188  shared_ptr<Impl> _pimpl;
189  };
191 
193  template<class Tp>
194  inline std::ostream & operator<<( std::ostream & str, const AutoDispose<Tp> & obj )
195  { return str << obj.value(); }
196 
197 
203  struct AutoFD : public AutoDispose<int>
204  {
205  AutoFD( int fd_r = -1 ) : AutoDispose<int>( fd_r, [] ( int fd_r ) { if ( fd_r != -1 ) ::close( fd_r ); } ) {}
206  };
207 
214  struct AutoFILE : public AutoDispose<FILE*>
215  {
216  AutoFILE( FILE* file_r = nullptr ) : AutoDispose<FILE*>( file_r, [] ( FILE* file_r ) { if ( file_r ) ::fclose( file_r ); } ) {}
217  };
218 
224  template <typename Tp>
225  struct AutoFREE : public AutoDispose<Tp*>
226  {
227  AutoFREE( Tp* ptr_r = nullptr ) : AutoDispose<Tp*>( ptr_r, [] ( Tp* ptr_r ) { if ( ptr_r ) ::free( ptr_r ); } ) {}
228  AutoFREE( void* ptr_r ) : AutoFREE( static_cast<Tp*>(ptr_r) ) {}
229  };
230 
231  template <>
232  struct AutoFREE<void> : public AutoDispose<void*>
233  {
234  AutoFREE( void* ptr_r = nullptr ) : AutoDispose<void*>( ptr_r, [] ( void* ptr_r ) { if ( ptr_r ) ::free( ptr_r ); } ) {}
235  };
237 } // namespace zypp
239 #endif // ZYPP_AUTODISPOSE_H