stack_unwinding это маленькая header-only библиотека, которая реализует примитив(class unwinding_indicator) позволяющий определить, был ли вызван деструктор объекта из-за раскрутки стэка или "нормальным" образом
Библиотека позволяет определить в каких случаях реально опасно кидать исключение из деструктора. То есть когда исключение покинувшее деструктор может привести к вызову std::terminate.
В результате, возможно достичь такого же эффекта, как ручная расстановка ".close()" в конце блока, автоматически.
{
File a,b;
// ...
b.close(); // may throw
a.close(); // may throw
}
станет
{
File a,b;
// ...
}
В более общем случае, это поможет созданию "продвинутого" Scope Guard, который не требует ручного вызова commit/release, а также "понимает" исключения из деструкторов.
Язык D имеет scope(success) и scope(failure), которые позволяют задать отложенное действие на конец блока, которое выполняются(либо нет) в зависимости от того, произошёл ли выход из блока по исключению или обычным образом.
В этой библиотеке есть примеры реализаций "scope(success)" и "scope(failure)" (C++03, без лямбд):
{
cout << "Case #1: stack unwinding" << endl;
scope_action exit=make<scope_exit>(Print(" exit"));
scope_action failure=make<scope_failure>(Print(" failure"));
scope_action success=make<scope_success>(Print(" success"));
throw 1;
}
В Boost есть библиотека "Scope Exit", которая в примерах использует решение похожее на ручной вызов release/commit (там используется bool переменная).
Цитата из мануала Boost.ScopeExit:
Boost.ScopeExit is similar to scope(exit) feature built into the D programming language.
A curious reader may notice that the library does not implement scope(success) and scope(failure) of the D language.
Unfortunately, these are not possible in C++ because failure or success conditions cannot be determined by calling std::uncaught_exception (see Guru of the Week #47 for details about std::uncaught_exception and if it has any good use at all).
However, this is not a big problem because these two D's constructs can be expressed in terms of scope(exit) and a bool commit variable (similarly to some examples presented in the Tutorial section).
Работоспособность библиотеки была проверенна на: {MSVC2005,MSVC2008,MSVC2010,MSVC2012,GCC 4.1.2,Clang 3.2}x{x32,x64}x{дефолтные настройки}
На данный момент, библиотека реализована поверх платформо-зависимой реализации функции uncaught_exception_count.
uncaught_exception_count — это функция подобная std::uncaught_exception из стандартной библиотеки, но вместо булевского результата возвращает unsigned int, показывающий текущее количество uncaught exceptions
Ссылки:
*
http://www.boost.org/doc/libs/1_51_0/libs/scope_exit/doc/html/index.html
*
http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D
*
http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758
*
http://www.gotw.ca/gotw/047.htm
*
https://github.com/panaseleus/stack_unwinding