]> git.sesse.net Git - casparcg/blob - common/scope_exit.h
[scene] #564 Made a crawler example scene.
[casparcg] / common / scope_exit.h
1 #pragma once
2
3 #include "except.h"
4
5 #include <functional>
6
7 namespace caspar {
8
9 namespace detail 
10 {
11     template<typename T>
12     class scope_exit
13     {
14                 scope_exit(const scope_exit&);
15                 scope_exit& operator=(const scope_exit&);
16     public:         
17
18                 template<typename T2>
19         explicit scope_exit(T2&& func) 
20                         : func_(std::forward<T2>(func))
21                         , valid_(true)
22                 {
23                 }
24                 
25                 scope_exit(scope_exit&& other)
26                         : func_(std::move(other.func_))
27                         , valid_(std::move(other.valid_))
28                 {
29                         other.valid_ = false;
30                 }
31
32                 scope_exit& operator=(scope_exit&& other)
33                 {
34                         func_  = std::move(other.func_);
35                         valid_ = std::move(other.valid_);
36
37                         other.valid_ = false;
38
39                         return *this;
40                 }
41
42         ~scope_exit()
43                 {
44                         try
45                         {
46                                 if(valid_)
47                                         func_();
48                         }
49                         catch(...)
50                         {
51                                 if(!std::uncaught_exception()) 
52 #pragma warning(push)
53 #pragma warning(disable: 4297)
54                                         throw;
55 #pragma warning(pop)
56                                 else
57                                         CASPAR_LOG_CURRENT_EXCEPTION();
58                         }
59                 }
60     private:
61         T func_;
62                 bool valid_;
63     };          
64         
65         class scope_exit_helper {};
66
67         template <typename T>
68         scope_exit<typename std::decay<T>::type> operator+(scope_exit_helper, T&& exitScope)
69         {
70                 return scope_exit<typename std::decay<T>::type>(std::forward<T>(exitScope));
71         }
72 }
73
74 #define _CASPAR_EXIT_SCOPE_LINENAME_CAT(name, line) name##line
75 #define _CASPAR_EXIT_SCOPE_LINENAME(name, line) _CASPAR_EXIT_SCOPE_LINENAME_CAT(name, line)
76 #define CASPAR_SCOPE_EXIT auto _CASPAR_EXIT_SCOPE_LINENAME(EXIT, __LINE__) = ::caspar::detail::scope_exit_helper() + [&]() mutable
77
78 }