libzypp 17.37.17
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#include <utility>
18
22#include <zypp-core/Pathname.h>
23
25namespace zypp
26{
27
29 //
30 // CLASS NAME : AutoDispose<Tp>
31 //
93 template<class Tp>
95 {
96 public:
97 using param_type = typename boost::call_traits<Tp>::param_type;
98 using reference = typename boost::call_traits<Tp>::reference;
99 using const_reference = typename boost::call_traits<Tp>::const_reference;
100 using value_type = Tp;
101 using result_type = typename boost::call_traits<Tp>::value_type;
102 // bsc#1194597: Header is exposed in the public API, so it must be c++11:
103 // using dispose_param_type = std::conditional_t< std::is_pointer_v<Tp> || std::is_integral_v<Tp>, Tp const, reference >;
105
106 public:
108 using Dispose = function<void ( dispose_param_type )>;
109
110 public:
113 : _pimpl( new Impl( value_type() ) )
114 {}
115
117 explicit AutoDispose( Dispose dispose_r )
118 : _pimpl( new Impl( value_type(), std::move(dispose_r) ) )
119 {}
120
122 explicit AutoDispose( value_type value_r )
123 : _pimpl( new Impl( std::move(value_r) ) )
124 {}
125
127 AutoDispose( value_type value_r, Dispose dispose_r )
128 : _pimpl( new Impl( std::move(value_r), std::move(dispose_r) ) )
129 {}
130
131 public:
132
134 operator reference() const
135 { return _pimpl->_value; }
136
139 { return _pimpl->_value; }
140
143 { return _pimpl->_value; }
144
147 { return & _pimpl->_value; }
148
150 void reset()
151 { AutoDispose().swap( *this ); }
152
154 void swap( AutoDispose & rhs ) noexcept
155 { _pimpl.swap( rhs._pimpl ); }
156
158 bool unique () const
159 { return _pimpl.unique(); }
160
161 public:
163 const Dispose & getDispose() const
164 { return _pimpl->_dispose; }
165
167 void setDispose( const Dispose & dispose_r )
168 { _pimpl->_dispose = dispose_r; }
169
172 { setDispose( Dispose() ); }
173
175 void swapDispose( Dispose & dispose_r )
176 { _pimpl->_dispose.swap( dispose_r ); }
177
178 private:
179 struct Impl : private base::NonCopyable
180 {
181 template <typename T>
182 Impl( T &&value_r )
183 : _value( std::forward<T>(value_r) )
184 {}
185 template <typename T, typename D>
186 Impl( T &&value_r, D &&dispose_r )
187 : _value( std::forward<T>(value_r) )
188 , _dispose( std::forward<D>(dispose_r) )
189 {}
191 {
192 if ( _dispose )
193 try { _dispose( _value ); } catch(...) {}
194 }
197 };
198
200 };
201
202 template<>
203 class AutoDispose<void>
204 {
205 public:
207 using Dispose = function<void ()>;
208
209 public:
212 : _pimpl( new Impl() )
213 {}
214
216 explicit AutoDispose( const Dispose & dispose_r )
217 : _pimpl( new Impl( dispose_r ) )
218 {}
219
220 public:
221
223 void reset()
224 { AutoDispose().swap( *this ); }
225
227 void swap( AutoDispose & rhs ) noexcept
228 { _pimpl.swap( rhs._pimpl ); }
229
230 public:
232 const Dispose & getDispose() const
233 { return _pimpl->_dispose; }
234
236 void setDispose( const Dispose & dispose_r )
237 { _pimpl->_dispose = dispose_r; }
238
240 void resetDispose()
241 { setDispose( Dispose() ); }
242
244 void swapDispose( Dispose & dispose_r )
245 { _pimpl->_dispose.swap( dispose_r ); }
246
247 private:
248 struct Impl : private base::NonCopyable
249 {
251 {}
252
253 Impl( Dispose dispose_r )
254 : _dispose(std::move( dispose_r ))
255 {}
256
258 {
259 if ( _dispose )
260 try { _dispose(); } catch(...) {}
261 }
262 Dispose _dispose;
263 };
264 shared_ptr<Impl> _pimpl;
265 };
266
277
278 struct Deferred : public AutoDispose<void>
279 {
280 template <typename F>
281 Deferred( F&&cb );
282 };
283
284 template<typename F>
285 Deferred::Deferred(F &&cb) : AutoDispose( std::forward<F>(cb) ){}
286
287#define __zypp_defer_concatenate(__lhs, __rhs) \
288 __lhs##__rhs
289
290#define __zypp_defer_declarator(__id) \
291 zypp::Deferred __zypp_defer_concatenate(__defer, __id) = [&]()
292
293#define zypp_defer \
294 __zypp_defer_declarator(__LINE__)
295
297
299 template<class Tp>
300 inline std::ostream & operator<<( std::ostream & str, const AutoDispose<Tp> & obj )
301 { return str << obj.value(); }
302
303
309 struct AutoFD : public AutoDispose<int>
310 {
311 AutoFD( int fd_r = -1 ) : AutoDispose<int>( fd_r, [] ( int fd_r ) { if ( fd_r != -1 ) ::close( fd_r ); } ) {}
312 };
313
320 struct AutoFILE : public AutoDispose<FILE*>
321 {
322 AutoFILE( FILE* file_r = nullptr ) : AutoDispose<FILE*>( file_r, [] ( FILE* file_r ) { if ( file_r ) ::fclose( file_r ); } ) {}
323 };
324
330 template <typename Tp>
331 struct AutoFREE : public AutoDispose<Tp*>
332 {
333 AutoFREE( Tp* ptr_r = nullptr ) : AutoDispose<Tp*>( ptr_r, [] ( Tp* ptr_r ) { if ( ptr_r ) ::free( ptr_r ); } ) {}
334 AutoFREE( void* ptr_r ) : AutoFREE( static_cast<Tp*>(ptr_r) ) {}
335 };
336
337 template <>
338 struct AutoFREE<void> : public AutoDispose<void*>
339 {
340 AutoFREE( void* ptr_r = nullptr ) : AutoDispose<void*>( ptr_r, [] ( void* ptr_r ) { if ( ptr_r ) ::free( ptr_r ); } ) {}
341 };
342
344} // namespace zypp
346#endif // ZYPP_AUTODISPOSE_H
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
value_type * operator->() const
Pointer to the Tp object (asserted to be != NULL).
void swap(AutoDispose &rhs) noexcept
Exchange the contents of two AutoDispose objects.
reference value() const
Reference to the Tp object.
std::ostream & operator<<(std::ostream &str, const AutoDispose< Tp > &obj)
Stream output of the Tp object.
const Dispose & getDispose() const
Return the current dispose function.
void resetDispose()
Set no dispose function.
function< void(dispose_param_type)> Dispose
Dispose function signatue.
AutoDispose(Dispose dispose_r)
Ctor taking dispose function and using default constructed value.
AutoDispose()
Default Ctor using default constructed value and no dispose function.
std::conditional_t< std::is_pointer_v< Tp >||std::is_integral_v< Tp >, Tp const, reference > dispose_param_type
reference operator*() const
Reference to the Tp object.
typename boost::call_traits< Tp >::const_reference const_reference
Definition AutoDispose.h:99
void reset()
Reset to default Ctor values.
void swapDispose(Dispose &dispose_r)
Exchange the dispose function.
bool unique() const
Returns true if this is the only AutoDispose instance managing the current data object.
void setDispose(const Dispose &dispose_r)
Set a new dispose function.
typename boost::call_traits< Tp >::param_type param_type
Definition AutoDispose.h:97
typename boost::call_traits< Tp >::reference reference
Definition AutoDispose.h:98
AutoDispose(value_type value_r, Dispose dispose_r)
Ctor taking value and dispose function.
AutoDispose(value_type value_r)
Ctor taking value and no dispose function.
typename boost::call_traits< Tp >::value_type result_type
Definition Arch.h:364
constexpr bool is_integral_v
Definition TypeTraits.h:30
typename conditional< B, T, F >::type conditional_t
Definition TypeTraits.h:39
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
Easy-to use interface to the ZYPP dependency resolver.
AutoDispose< void > OnScopeExit
Impl(T &&value_r, D &&dispose_r)
AutoFD(int fd_r=-1)
AutoFILE(FILE *file_r=nullptr)
AutoFREE(void *ptr_r=nullptr)
AutoFREE(void *ptr_r)
AutoFREE(Tp *ptr_r=nullptr)