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); +} + | 
