Advertisement
Guest User

Untitled

a guest
Jan 17th, 2017
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.79 KB | None | 0 0
  1. #ifndef SCOPE
  2. #define SCOPE
  3.  
  4. #include <exception>
  5. #include <type_traits>
  6.  
  7. namespace xstd
  8. {
  9.  
  10. // scope_exit
  11.  
  12. template <class EF>
  13. class scope_exit
  14. {
  15. EF ef_;
  16. bool execute_ = true;
  17.  
  18. public:
  19. ~scope_exit();
  20. scope_exit(scope_exit&& rhs) noexcept;
  21.  
  22. explicit scope_exit(EF f) noexcept;
  23. void release() noexcept;
  24. };
  25.  
  26. template <class EF>
  27. inline
  28. scope_exit<EF>::~scope_exit()
  29. {
  30. if (execute_)
  31. ef_();
  32. }
  33.  
  34. template <class EF>
  35. inline
  36. scope_exit<EF>::scope_exit(scope_exit&& rhs) noexcept
  37. : ef_(std::forward<EF>(rhs.ef_))
  38. , execute_(rhs.execute_)
  39. {
  40. rhs.release();
  41. }
  42.  
  43. template <class EF>
  44. inline
  45. scope_exit<EF>::scope_exit(EF f) noexcept
  46. : ef_(std::forward<EF>(f))
  47. {
  48. }
  49.  
  50. template <class EF>
  51. inline
  52. void
  53. scope_exit<EF>::release() noexcept
  54. {
  55. execute_ = false;
  56. }
  57.  
  58. // make_scope_xxx
  59.  
  60. template <class EF>
  61. inline
  62. scope_exit<EF>
  63. make_scope_exit(EF ef) noexcept
  64. {
  65. return scope_exit<EF>{std::move(ef)};
  66. }
  67.  
  68. template <class EF>
  69. auto
  70. make_scope_fail(EF ef) noexcept
  71. {
  72. return make_scope_exit([ef = std::move(ef), ec = std::uncaught_exceptions()]
  73. {
  74. if (ec < std::uncaught_exceptions())
  75. ef();
  76. });
  77. }
  78.  
  79. template <class EF>
  80. auto
  81. make_scope_success(EF ef) noexcept
  82. {
  83. return make_scope_exit([ef = std::move(ef), ec = std::uncaught_exceptions()]
  84. {
  85. if (!(ec < std::uncaught_exceptions()))
  86. ef();
  87. });
  88. }
  89.  
  90. // unique_resource
  91.  
  92. template<class R, class D>
  93. class unique_resource
  94. {
  95. R r_;
  96. D d_;
  97. bool execute_;
  98.  
  99. public:
  100. ~unique_resource();
  101. unique_resource(unique_resource&& rhs) noexcept;
  102. unique_resource& operator=(unique_resource&& rhs) noexcept;
  103.  
  104. unique_resource(R r, D d) noexcept;
  105.  
  106. void reset();
  107. void reset(R r);
  108. R release() noexcept;
  109. R const& get() const noexcept;
  110. operator R const& () const noexcept;
  111. template <class Constraint = std::integral_constant<bool, std::is_pointer<R>::value &&
  112. (std::is_class<std::remove_pointer_t<R>>::value ||
  113. std::is_union<std::remove_pointer_t<R>>::value)>>
  114. std::enable_if_t<Constraint::value, R>
  115. operator->() const noexcept;
  116. template <class T = void, class Constraint = std::enable_if_t<std::is_void<T>::value &&
  117. std::is_pointer<R>::value>>
  118. decltype(auto)
  119. operator* () const noexcept;
  120. const D& get_deleter() const noexcept;
  121. };
  122.  
  123. template<class R, class D>
  124. inline
  125. unique_resource<R, D>::~unique_resource()
  126. {
  127. reset();
  128. }
  129.  
  130. template<class R, class D>
  131. inline
  132. unique_resource<R, D>::unique_resource(unique_resource&& rhs) noexcept
  133. : r_(std::move(rhs.r_))
  134. , d_(std::move(rhs.d_))
  135. , execute_(std::move(rhs.execute_))
  136. {
  137. rhs.release();
  138. }
  139.  
  140. template<class R, class D>
  141. unique_resource<R, D>&
  142. unique_resource<R, D>::operator=(unique_resource&& rhs) noexcept
  143. {
  144. reset();
  145. r_ = std::move(rhs.r_);
  146. d_ = std::move(rhs.d_);
  147. execute_ = std::move(rhs.execute_);
  148. rhs.release();
  149. return *this;
  150. }
  151.  
  152. template<class R, class D>
  153. inline
  154. unique_resource<R, D>::unique_resource(R r, D d) noexcept
  155. : r_(std::move(r))
  156. , d_(std::move(d))
  157. , execute_(true)
  158. {
  159. }
  160.  
  161. template<class R, class D>
  162. inline
  163. void
  164. unique_resource<R, D>::reset()
  165. {
  166. if (execute_)
  167. {
  168. execute_ = false;
  169. d_(r_);
  170. }
  171. }
  172.  
  173. template<class R, class D>
  174. inline
  175. void
  176. unique_resource<R, D>::reset(R r)
  177. {
  178. reset();
  179. r_ = std::move(r);
  180. execute_ = true;
  181. }
  182.  
  183. template<class R, class D>
  184. inline
  185. R
  186. unique_resource<R, D>::release() noexcept
  187. {
  188. execute_ = false;
  189. return std::move(r_);
  190. }
  191.  
  192. template<class R, class D>
  193. inline
  194. R const&
  195. unique_resource<R, D>::get() const noexcept
  196. {
  197. return r_;
  198. }
  199.  
  200. template<class R, class D>
  201. inline
  202. unique_resource<R, D>::operator R const& () const noexcept
  203. {
  204. return r_;
  205. }
  206.  
  207. template<class R, class D>
  208. template <class Constraint>
  209. inline
  210. std::enable_if_t<Constraint::value, R>
  211. unique_resource<R, D>::operator->() const noexcept
  212. {
  213. return r_;
  214. }
  215.  
  216. template<class R, class D>
  217. template <class T, class Constraint>
  218. inline
  219. decltype(auto)
  220. unique_resource<R, D>::operator* () const noexcept
  221. {
  222. return *r_;
  223. }
  224.  
  225. template<class R, class D>
  226. inline
  227. const D&
  228. unique_resource<R, D>::get_deleter() const noexcept
  229. {
  230. return d_;
  231. }
  232.  
  233. template<class R,class D>
  234. inline
  235. unique_resource<R, D>
  236. make_unique_resource(R r, D d) noexcept
  237. {
  238. return unique_resource<R, D>{std::move(r), std::move(d)};
  239. }
  240.  
  241. template<class R, class D, class RI = R>
  242. inline
  243. unique_resource<R, D>
  244. make_unique_resource_checked(R r, RI invalid, D d) noexcept
  245. {
  246. auto ur = unique_resource<R,D>(std::move(r), std::move(d));
  247. if (static_cast<bool>(r == invalid))
  248. ur.release();
  249. return ur;
  250. }
  251.  
  252. } // namespace xstd
  253.  
  254. #endif // SCOPE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement