diff options
-rw-r--r-- | libadhocutil/scopeExit.cpp | 22 | ||||
-rw-r--r-- | libadhocutil/scopeExit.h | 24 | ||||
-rw-r--r-- | libadhocutil/unittests/Jamfile.jam | 10 | ||||
-rw-r--r-- | libadhocutil/unittests/testScopeExit.cpp | 27 |
4 files changed, 83 insertions, 0 deletions
diff --git a/libadhocutil/scopeExit.cpp b/libadhocutil/scopeExit.cpp new file mode 100644 index 0000000..fa914c5 --- /dev/null +++ b/libadhocutil/scopeExit.cpp @@ -0,0 +1,22 @@ +#include "scopeExit.h" + +ScopeExit::ScopeExit(const Event & onexitpre, const Event & onsuccess, const Event & onfailure, const Event & onexitpost) : + onExitPre(onexitpre), + onSuccess(onsuccess), + onFailure(onfailure), + onExitPost(onexitpost) +{ +} + +ScopeExit::~ScopeExit() +{ + if (onExitPre) onExitPre(); + if (std::uncaught_exception()) { + if (onFailure) onFailure(); + } + else { + if (onSuccess) onSuccess(); + } + if (onExitPost) onExitPost(); +} + diff --git a/libadhocutil/scopeExit.h b/libadhocutil/scopeExit.h new file mode 100644 index 0000000..d9854d5 --- /dev/null +++ b/libadhocutil/scopeExit.h @@ -0,0 +1,24 @@ +#ifndef LIBADHOC_SCOPEEXIT_H +#define LIBADHOC_SCOPEEXIT_H + +#include <boost/function.hpp> +#include "visibility.h" + +class DLL_PUBLIC ScopeExit { + public: + typedef boost::function<void()> Event; + ScopeExit(const Event &, const Event & = Event(), const Event & = Event(), const Event & = Event()); + ~ScopeExit(); + + ScopeExit(const ScopeExit &) = delete; + void operator=(const ScopeExit &) = delete; + + private: + const Event onExitPre; + const Event onSuccess; + const Event onFailure; + const Event onExitPost; +}; + +#endif + diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam index c8abcb9..610a3c4 100644 --- a/libadhocutil/unittests/Jamfile.jam +++ b/libadhocutil/unittests/Jamfile.jam @@ -63,3 +63,13 @@ run testMapFinds ; +run + testScopeExit.cpp + : : : + <define>BOOST_TEST_DYN_LINK + <library>..//adhocutil + <library>boost_utf + : + testScopeExit + ; + diff --git a/libadhocutil/unittests/testScopeExit.cpp b/libadhocutil/unittests/testScopeExit.cpp new file mode 100644 index 0000000..80574f9 --- /dev/null +++ b/libadhocutil/unittests/testScopeExit.cpp @@ -0,0 +1,27 @@ +#define BOOST_TEST_MODULE ScopeExit +#include <boost/test/unit_test.hpp> + +#include "scopeExit.h" +#include <string> + +BOOST_AUTO_TEST_CASE ( cleanexit ) +{ + std::string log; + { + ScopeExit se([&log]{ log += "before"; }, [&log]{ log += "clean"; }, [&log]{ log += "error"; }, [&log]{ log += "after"; }); + } + BOOST_REQUIRE_EQUAL(log, "beforecleanafter"); +} + +BOOST_AUTO_TEST_CASE ( uncaught ) +{ + BOOST_REQUIRE_THROW({ + std::string log; + { + ScopeExit se([&log]{ log += "before"; }, [&log]{ log += "clean"; }, [&log]{ log += "error"; }, [&log]{ log += "after"; }); + throw std::runtime_error("test unclean exit"); + } + BOOST_REQUIRE_EQUAL(log, "beforeerrorafter"); + }, std::runtime_error); +} + |