Synchronize notmuch mail across machines
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cleanup.h 2.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // -*- C++ -*-
  2. /** \file cleanup.h
  3. * \brief Classes to facilitate use of RIAA cleanup.
  4. */
  5. #ifndef _CLEANUP_H_
  6. #define _CLEANUP_H_ 1
  7. #include <functional>
  8. inline std::function<void()> &&
  9. voidify(std::function<void()> &&f) {
  10. return move(f);
  11. }
  12. inline const std::function<void()> &
  13. voidify(const std::function<void()> &f) {
  14. return f;
  15. }
  16. template<typename F> inline std::function<void()>
  17. voidify(F &&f)
  18. {
  19. return [f]() { f(); };
  20. }
  21. /** \brief Container for a cleanup action.
  22. */
  23. class cleanup {
  24. std::function<void()> action_;
  25. static void nop() {}
  26. public:
  27. cleanup() : action_ (nop) {}
  28. cleanup(const cleanup &) = delete;
  29. cleanup(cleanup &&c) : action_(c.action_) { c.release(); }
  30. template<typename F> cleanup(F &&f) : action_ (std::forward<F>(f)) {}
  31. template<typename... Args> cleanup(Args... args)
  32. : action_(voidify(std::bind(args...))) {}
  33. ~cleanup() { action_(); }
  34. cleanup &operator=(cleanup &&c) { action_.swap(c.action_); return *this; }
  35. void reset() {
  36. std::function<void()> old (action_);
  37. release();
  38. old();
  39. }
  40. template<typename F> void reset(F &&f) {
  41. std::function<void()> old (action_);
  42. action_ = std::forward<F>(f);
  43. old();
  44. }
  45. template<typename... Args> void reset(Args... args) {
  46. std::function<void()> old (action_);
  47. action_ = std::bind(args...);
  48. old();
  49. }
  50. void release() { action_ = nop; }
  51. };
  52. /** \brief Like a \ref std::unique_ptr, but half the size because the
  53. * cleanup function is specified as part of the type.
  54. */
  55. template<typename T, void(destructor)(T*)>
  56. class unique_obj {
  57. T *obj_;
  58. public:
  59. unique_obj() noexcept : obj_(nullptr) {}
  60. explicit unique_obj(T *obj) noexcept : obj_(obj) {}
  61. unique_obj(unique_obj &&uo) noexcept : obj_(uo.obj_) { uo.obj_ = nullptr; }
  62. ~unique_obj() { if (obj_) destructor(obj_); }
  63. void reset(T *obj) { T *old = obj_; obj_ = obj; destructor(old); }
  64. T *release() noexcept { T *old = obj_; obj_ = nullptr; return old; }
  65. T *get() const noexcept { return obj_; }
  66. T *&get() noexcept { return obj_; }
  67. operator T*() const noexcept { return obj_; }
  68. };
  69. #endif /* !_CLEANUP_H_ */