Home | History | Annotate | Download | only in win_text
      1 #pragma once
      2 
      3 namespace unwinder { namespace detail {
      4 
      5         template<typename Function>
      6         class unwinder
      7         {
      8         public:
      9             ~unwinder() noexcept
     10             {
     11                 if (!!function)
     12                 {
     13                     (*function)();
     14                 }
     15             }
     16 
     17             explicit unwinder(Function* functionArg)
     18                 : function(functionArg)
     19             {
     20             }
     21 
     22             void dismiss()
     23             {
     24                 function = nullptr;
     25             }
     26 
     27             unwinder& operator=(nullptr_t) {
     28                 dismiss();
     29                 return *this;
     30             }
     31 
     32         private:
     33             unwinder();
     34             unwinder(const unwinder&);
     35             unwinder& operator=(const unwinder&);
     36 
     37             Function* function;
     38         };
     39 } }
     40 
     41 #define UNWIND_MAKE_IDENTIFIER_EXPLICIT_PASTER(Prefix, Suffix) Prefix ## Suffix
     42 #define UNWIND_MAKE_IDENTIFIER_EXPLICIT(Prefix, Suffix) UNWIND_MAKE_IDENTIFIER_EXPLICIT_PASTER(Prefix, Suffix)
     43 
     44 #define UNWIND_MAKE_IDENTIFIER(Prefix) UNWIND_MAKE_IDENTIFIER_EXPLICIT(Prefix, __LINE__)
     45 
     46 #define ON_UNWIND(Name, Function) \
     47 	ON_UNWIND_EXPLICIT(uwfunc_ ## Name, Name, Function)
     48 
     49 #define ON_UNWIND_AUTO(Function) \
     50 	ON_UNWIND_EXPLICIT(UNWIND_MAKE_IDENTIFIER(uwfunc_), UNWIND_MAKE_IDENTIFIER(unwind_), Function)
     51 
     52 #define ON_UNWIND_EXPLICIT(FunctionName, UnwinderName, Function) \
     53 	auto FunctionName = (Function); \
     54 	::unwinder::detail::unwinder<decltype(FunctionName)> UnwinderName(std::addressof(FunctionName))
     55