summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/scope_exit/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/scope_exit/test')
-rw-r--r--src/boost/libs/scope_exit/test/Jamfile.v252
-rw-r--r--src/boost/libs/scope_exit/test/native.cpp194
-rw-r--r--src/boost/libs/scope_exit/test/native_const_error.cpp17
-rw-r--r--src/boost/libs/scope_exit/test/native_cv_error.cpp20
-rw-r--r--src/boost/libs/scope_exit/test/native_this.cpp43
-rw-r--r--src/boost/libs/scope_exit/test/native_this_tpl.cpp45
-rw-r--r--src/boost/libs/scope_exit/test/native_tpl.cpp73
-rw-r--r--src/boost/libs/scope_exit/test/native_tu1.cpp12
-rw-r--r--src/boost/libs/scope_exit/test/native_tu2.cpp12
-rw-r--r--src/boost/libs/scope_exit/test/native_tu_test.cpp21
-rw-r--r--src/boost/libs/scope_exit/test/nova.hpp21
-rw-r--r--src/boost/libs/scope_exit/test/same_line.cpp79
-rw-r--r--src/boost/libs/scope_exit/test/same_line_seq.cpp71
-rw-r--r--src/boost/libs/scope_exit/test/same_line_seq_nova.cpp10
-rw-r--r--src/boost/libs/scope_exit/test/tu_test.hpp48
-rw-r--r--src/boost/libs/scope_exit/test/world.cpp58
-rw-r--r--src/boost/libs/scope_exit/test/world_checkpoint.cpp112
-rw-r--r--src/boost/libs/scope_exit/test/world_checkpoint_all.cpp116
-rw-r--r--src/boost/libs/scope_exit/test/world_checkpoint_all_seq.cpp110
-rw-r--r--src/boost/libs/scope_exit/test/world_checkpoint_all_seq_nova.cpp10
-rw-r--r--src/boost/libs/scope_exit/test/world_checkpoint_seq.cpp99
-rw-r--r--src/boost/libs/scope_exit/test/world_checkpoint_seq_nova.cpp10
-rw-r--r--src/boost/libs/scope_exit/test/world_seq.cpp51
-rw-r--r--src/boost/libs/scope_exit/test/world_seq_nova.cpp10
-rw-r--r--src/boost/libs/scope_exit/test/world_this.cpp58
-rw-r--r--src/boost/libs/scope_exit/test/world_this_seq.cpp49
-rw-r--r--src/boost/libs/scope_exit/test/world_this_seq_nova.cpp10
-rw-r--r--src/boost/libs/scope_exit/test/world_tpl.cpp59
-rw-r--r--src/boost/libs/scope_exit/test/world_tpl_seq.cpp50
-rw-r--r--src/boost/libs/scope_exit/test/world_tpl_seq_nova.cpp10
-rw-r--r--src/boost/libs/scope_exit/test/world_void.cpp48
-rw-r--r--src/boost/libs/scope_exit/test/world_void_nova.cpp11
32 files changed, 1589 insertions, 0 deletions
diff --git a/src/boost/libs/scope_exit/test/Jamfile.v2 b/src/boost/libs/scope_exit/test/Jamfile.v2
new file mode 100644
index 000000000..fbd332f69
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/Jamfile.v2
@@ -0,0 +1,52 @@
+
+# Copyright (C) 2006-2009, 2012 Alexander Nasonov
+# Copyright (C) 2012 Lorenzo Caminiti
+# Distributed under the Boost Software License, Version 1.0
+# (see accompanying file LICENSE_1_0.txt or a copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+# Home at http://www.boost.org/libs/scope_exit
+
+import testing ;
+import ../../config/checks/config : requires ;
+
+rule run-vaseq ( target : requirements * )
+{
+ run $(target).cpp : : : $(requirements) ;
+ run $(target)_seq.cpp : : : $(requirements) ;
+ run $(target)_seq_nova.cpp : : : $(requirements) ;
+}
+
+rule run-typeof ( native_target emulation_target )
+{
+ run $(native_target).cpp : : : <define>BOOST_TYPEOF_NATIVE ;
+ run $(native_target).cpp : : : <define>BOOST_TYPEOF_EMULATION :
+ $(emulation_target) : ;
+}
+
+rule compile-fail-typeof ( native_target emulation_target )
+{
+ compile-fail $(native_target).cpp : <define>BOOST_TYPEOF_NATIVE ;
+ compile-fail $(native_target).cpp : <define>BOOST_TYPEOF_EMULATION :
+ $(emulation_target) : ;
+}
+
+run-vaseq same_line ;
+run-vaseq world ;
+run-vaseq world_checkpoint ;
+run-vaseq world_checkpoint_all : [ requires cxx11_lambdas ] ;
+run-vaseq world_this ;
+run-vaseq world_tpl ;
+run world_void.cpp ;
+run world_void_nova.cpp ;
+
+run-typeof native emulation ;
+run-typeof native_tpl emulation_tpl ;
+run-typeof native_this emulation_this ;
+run-typeof native_this_tpl emulation_this_tpl ;
+compile-fail-typeof native_const_error emulation_const_error ;
+compile-fail-typeof native_cv_error emulation_cv_error ;
+run native_tu_test.cpp native_tu1.cpp native_tu2.cpp : : :
+ <define>BOOST_TYPEOF_NATIVE ;
+run native_tu_test.cpp native_tu1.cpp native_tu2.cpp : : :
+ <define>BOOST_TYPEOF_EMULATION : emulation_tu_test : ;
+
diff --git a/src/boost/libs/scope_exit/test/native.cpp b/src/boost/libs/scope_exit/test/native.cpp
new file mode 100644
index 000000000..682e11269
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native.cpp
@@ -0,0 +1,194 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/config.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/string.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <ostream>
+#include <string>
+
+std::string g_str;
+
+template<int Dummy = 0>
+struct Holder {
+ static long g_long;
+};
+
+template<int Dummy> long Holder<Dummy>::g_long;
+
+void test_non_local(void) {
+ // ... and one local variable as well:
+ int i = 0;
+
+ BOOST_SCOPE_EXIT(void) {
+ BOOST_TEST(Holder<>::g_long == 3);
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_SCOPE_EXIT( (i) ) {
+ BOOST_TEST(i == 0);
+ BOOST_TEST(Holder<>::g_long == 3);
+ BOOST_TEST(g_str == "try: g_str");
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_SCOPE_EXIT( (&i) ) {
+ BOOST_TEST(i == 3);
+ BOOST_TEST(Holder<>::g_long == 3);
+ BOOST_TEST(g_str == "try: g_str");
+ } BOOST_SCOPE_EXIT_END
+
+ {
+ g_str = "";
+ Holder<>::g_long = 1;
+
+ BOOST_SCOPE_EXIT( (&i) ) {
+ i = 1;
+ g_str = "g_str";
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_SCOPE_EXIT( (&i) ) {
+ try {
+ i = 2;
+ Holder<>::g_long = 2;
+ throw 0;
+ } catch(...) {}
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_TEST(i == 0);
+ BOOST_TEST(g_str == "");
+ BOOST_TEST(Holder<>::g_long == 1);
+ }
+
+ BOOST_TEST(Holder<>::g_long == 2);
+ BOOST_TEST(g_str == "g_str");
+ BOOST_TEST(i == 1); // Check that first declared is executed last.
+
+ BOOST_SCOPE_EXIT( (&i) ) {
+ BOOST_TEST(i == 3);
+ BOOST_TEST(Holder<>::g_long == 3);
+ BOOST_TEST(g_str == "try: g_str");
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_SCOPE_EXIT( (i) ) {
+ BOOST_TEST(i == 1);
+ BOOST_TEST(Holder<>::g_long == 3);
+ BOOST_TEST(g_str == "try: g_str");
+ } BOOST_SCOPE_EXIT_END
+
+ try {
+ BOOST_SCOPE_EXIT( (&i) ) {
+ i = 3;
+ g_str = "try: g_str";
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_SCOPE_EXIT( (&i) ) {
+ i = 4;
+ Holder<>::g_long = 3;
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_TEST(i == 1);
+ BOOST_TEST(g_str == "g_str");
+ BOOST_TEST(Holder<>::g_long == 2);
+
+ throw 0;
+ } catch(int) {
+ BOOST_TEST(Holder<>::g_long == 3);
+ BOOST_TEST(g_str == "try: g_str");
+ BOOST_TEST(i == 3); // Check that first declared is executed last.
+ }
+}
+
+bool foo(void) { return true; }
+
+bool foo2(void) { return false; }
+
+void test_types(void) {
+ bool (*pf)(void) = 0;
+ bool (&rf)(void) = foo;
+ bool results[2] = {};
+
+ {
+ BOOST_SCOPE_EXIT( (&results) (&pf) (&rf) ) {
+ results[0] = pf();
+ results[1] = rf();
+ }
+ BOOST_SCOPE_EXIT_END
+
+ pf = &foo;
+
+ BOOST_TEST(results[0] == false);
+ BOOST_TEST(results[1] == false);
+ }
+
+ BOOST_TEST(results[0] == true);
+ BOOST_TEST(results[1] == true);
+
+ {
+ BOOST_SCOPE_EXIT( (&results) (pf) ) {
+ results[0] = !pf();
+ results[1] = !pf();
+ pf = &foo2; // modify a copy
+ }
+ BOOST_SCOPE_EXIT_END
+
+ pf = 0;
+
+ BOOST_TEST(results[0] == true);
+ BOOST_TEST(results[1] == true);
+ }
+
+ BOOST_TEST(pf == 0);
+ BOOST_TEST(results[0] == false);
+ BOOST_TEST(results[1] == false);
+}
+
+void test_capture_all(void) {
+#ifndef BOOST_NO_CXX11_LAMBDAS
+ int i = 0, j = 1;
+
+ {
+ BOOST_SCOPE_EXIT_ALL(=) {
+ i = j = 1; // modify copies
+ };
+ }
+ BOOST_TEST(i == 0);
+ BOOST_TEST(j == 1);
+
+ {
+ BOOST_SCOPE_EXIT_ALL(&) {
+ i = 1;
+ j = 2;
+ };
+ BOOST_TEST(i == 0);
+ BOOST_TEST(j == 1);
+ }
+ BOOST_TEST(i == 1);
+ BOOST_TEST(j == 2);
+
+ {
+ BOOST_SCOPE_EXIT_ALL(=, &j) {
+ i = 2; // modify a copy
+ j = 3;
+ };
+ BOOST_TEST(i == 1);
+ BOOST_TEST(j == 2);
+ }
+ BOOST_TEST(i == 1);
+ BOOST_TEST(j == 3);
+#endif // lambdas
+}
+
+int main(void) {
+ test_non_local();
+ test_types();
+ test_capture_all();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/native_const_error.cpp b/src/boost/libs/scope_exit/test/native_const_error.cpp
new file mode 100644
index 000000000..f162f54ec
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_const_error.cpp
@@ -0,0 +1,17 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+
+int main(void) {
+ int const i = 0;
+ BOOST_SCOPE_EXIT( (&i) ) {
+ i = 5;
+ } BOOST_SCOPE_EXIT_END
+}
+
diff --git a/src/boost/libs/scope_exit/test/native_cv_error.cpp b/src/boost/libs/scope_exit/test/native_cv_error.cpp
new file mode 100644
index 000000000..f0b7bf2fa
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_cv_error.cpp
@@ -0,0 +1,20 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/string.hpp>
+#include <string>
+
+int main(void) {
+ std::string const volatile s;
+ BOOST_SCOPE_EXIT( (&s) ) {
+ s = "";
+ } BOOST_SCOPE_EXIT_END
+}
+
diff --git a/src/boost/libs/scope_exit/test/native_this.cpp b/src/boost/libs/scope_exit/test/native_this.cpp
new file mode 100644
index 000000000..e6254786e
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_this.cpp
@@ -0,0 +1,43 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/config.hpp>
+#include <boost/typeof/typeof.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+
+struct this_tester;
+BOOST_TYPEOF_REGISTER_TYPE(this_tester) // Register before `this_` capture.
+
+struct this_tester {
+ void check(void) {
+ value_ = -1;
+
+ BOOST_SCOPE_EXIT( (this_) ) {
+ BOOST_TEST(this_->value_ == 0);
+ } BOOST_SCOPE_EXIT_END
+
+#ifndef BOOST_NO_CXX11_LAMBDAS
+ BOOST_SCOPE_EXIT_ALL(&, this) {
+ BOOST_TEST(this->value_ == 0);
+ };
+#endif // lambdas
+
+ value_ = 0;
+ }
+
+private:
+ int value_;
+};
+
+int main(void) {
+ this_tester().check();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/native_this_tpl.cpp b/src/boost/libs/scope_exit/test/native_this_tpl.cpp
new file mode 100644
index 000000000..bf5e78736
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_this_tpl.cpp
@@ -0,0 +1,45 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/config.hpp>
+#include <boost/typeof/typeof.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+
+template<typename T>
+struct this_tester;
+BOOST_TYPEOF_REGISTER_TEMPLATE(this_tester, 1) // Before`this_` capture.
+
+template<typename T>
+struct this_tester {
+ void check(void) {
+ value_ = -1;
+
+ BOOST_SCOPE_EXIT_TPL( (this_) ) {
+ BOOST_TEST(this_->value_ == 0);
+ } BOOST_SCOPE_EXIT_END
+
+#ifndef BOOST_NO_CXX11_LAMBDAS
+ BOOST_SCOPE_EXIT_ALL(&, this) {
+ BOOST_TEST(this->value_ == 0);
+ };
+#endif // lambdas
+
+ value_ = 0;
+ }
+
+private:
+ T value_;
+};
+
+int main(void) {
+ this_tester<int>().check();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/native_tpl.cpp b/src/boost/libs/scope_exit/test/native_tpl.cpp
new file mode 100644
index 000000000..edda6f3e6
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_tpl.cpp
@@ -0,0 +1,73 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/rational.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+template<class type>
+void tpl_long(
+ type tval
+ , type & t
+ , type const& tc
+ , type volatile& tv
+ , type const volatile& tcv
+) {
+ int i = 0; // non-dependent name
+ type const remember(tval);
+
+ {
+ BOOST_SCOPE_EXIT_TPL( (&tval) (&t) (&tc) (&tv) (&tcv) (&i) ) {
+ tval = 1;
+ ++t;
+ ++tv;
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_TEST(t == remember);
+ BOOST_TEST(tval == remember);
+ }
+
+ BOOST_TEST(tval == 1);
+ BOOST_TEST(t == remember + 2);
+}
+
+template<class Vector, int Value>
+void tpl_vector(
+ Vector vval
+ , Vector & v
+ , Vector const& vc
+) {
+ Vector const remember(vval);
+
+ {
+ BOOST_SCOPE_EXIT_TPL( (&vval) (&v) (&vc) ) {
+ v.push_back(-Value);
+ vval.push_back(Value);
+ } BOOST_SCOPE_EXIT_END
+
+ BOOST_TEST(v.size() == remember.size());
+ BOOST_TEST(vval.size() == remember.size());
+ }
+
+ BOOST_TEST(v.size() == 1 + remember.size());
+ BOOST_TEST(vval.size() == 1 + remember.size());
+}
+
+int main(void) {
+ long l = 137;
+ tpl_long(l, l, l, l, l);
+
+ std::vector<int> v(10, 137);
+ tpl_vector<std::vector<int>, 13>(v, v, v);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/native_tu1.cpp b/src/boost/libs/scope_exit/test/native_tu1.cpp
new file mode 100644
index 000000000..c90015475
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_tu1.cpp
@@ -0,0 +1,12 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "tu_test.hpp"
+
+int tu1(void) { return inline_f() + template_f(1); }
+
diff --git a/src/boost/libs/scope_exit/test/native_tu2.cpp b/src/boost/libs/scope_exit/test/native_tu2.cpp
new file mode 100644
index 000000000..11389327a
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_tu2.cpp
@@ -0,0 +1,12 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "tu_test.hpp"
+
+int tu2(void) { return inline_f() + template_f(2); }
+
diff --git a/src/boost/libs/scope_exit/test/native_tu_test.cpp b/src/boost/libs/scope_exit/test/native_tu_test.cpp
new file mode 100644
index 000000000..336e95146
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/native_tu_test.cpp
@@ -0,0 +1,21 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "tu_test.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+void test(void) {
+ BOOST_TEST(tu1() == 1);
+ BOOST_TEST(tu2() == 2);
+}
+
+int main(void) {
+ test();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/nova.hpp b/src/boost/libs/scope_exit/test/nova.hpp
new file mode 100644
index 000000000..ceef87eed
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/nova.hpp
@@ -0,0 +1,21 @@
+
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#ifndef NOVA_HPP_
+#define NOVA_HPP_
+
+#include <boost/config.hpp>
+
+// WARNING: This file must be included first in each compilation unit.
+
+// Force no variadic macros but avoiding macro redefinition warning/error.
+#ifndef BOOST_NO_CXX11_VARIADIC_MACROS
+# define BOOST_NO_CXX11_VARIADIC_MACROS
+#endif
+
+#endif // #include guard
+
diff --git a/src/boost/libs/scope_exit/test/same_line.cpp b/src/boost/libs/scope_exit/test/same_line.cpp
new file mode 100644
index 000000000..6a7ff1fff
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/same_line.cpp
@@ -0,0 +1,79 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_CXX11_VARIADIC_MACROS
+# error "variadic macros required"
+#else
+
+#include <boost/scope_exit.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//[same_line
+#define SCOPE_EXIT_INC_DEC(variable, offset) \
+ BOOST_SCOPE_EXIT_ID(BOOST_PP_CAT(inc, __LINE__), /* unique ID */ \
+ &variable, offset) { \
+ variable += offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(inc, __LINE__)) \
+ \
+ BOOST_SCOPE_EXIT_ID(BOOST_PP_CAT(dec, __LINE__), \
+ &variable, offset) { \
+ variable -= offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(dec, __LINE__))
+
+#define SCOPE_EXIT_INC_DEC_TPL(variable, offset) \
+ BOOST_SCOPE_EXIT_ID_TPL(BOOST_PP_CAT(inc, __LINE__), \
+ &variable, offset) { \
+ variable += offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(inc, __LINE__)) \
+ \
+ BOOST_SCOPE_EXIT_ID_TPL(BOOST_PP_CAT(dec, __LINE__), \
+ &variable, offset) { \
+ variable -= offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(dec, __LINE__))
+
+#define SCOPE_EXIT_ALL_INC_DEC(variable, offset) \
+ BOOST_SCOPE_EXIT_ALL_ID(BOOST_PP_CAT(inc, __LINE__), \
+ =, &variable) { \
+ variable += offset; \
+ }; \
+ BOOST_SCOPE_EXIT_ALL_ID(BOOST_PP_CAT(dec, __LINE__), \
+ =, &variable) { \
+ variable -= offset; \
+ };
+
+template<typename T>
+void f(T& x, T& delta) {
+ SCOPE_EXIT_INC_DEC_TPL(x, delta) // Multiple scope exits on same line.
+ BOOST_TEST(x == 0);
+}
+
+int main(void) {
+ int x = 0, delta = 10;
+
+ {
+ SCOPE_EXIT_INC_DEC(x, delta) // Multiple scope exits on same line.
+ }
+ BOOST_TEST(x == 0);
+
+ f(x, delta);
+
+#ifndef BOOST_NO_CXX11_LAMBDAS
+ {
+ SCOPE_EXIT_ALL_INC_DEC(x, delta) // Multiple scope exits on same line.
+ }
+ BOOST_TEST(x == 0);
+#endif // LAMBDAS
+
+ return boost::report_errors();
+}
+//]
+
+#endif // variadic macros
+
diff --git a/src/boost/libs/scope_exit/test/same_line_seq.cpp b/src/boost/libs/scope_exit/test/same_line_seq.cpp
new file mode 100644
index 000000000..aa177f732
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/same_line_seq.cpp
@@ -0,0 +1,71 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#define SCOPE_EXIT_INC_DEC(variable, offset) \
+ BOOST_SCOPE_EXIT_ID(BOOST_PP_CAT(inc, __LINE__), /* unique ID */ \
+ (&variable) (offset) ) { \
+ variable += offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(inc, __LINE__)) \
+ \
+ BOOST_SCOPE_EXIT_ID(BOOST_PP_CAT(dec, __LINE__), \
+ (&variable) (offset) ) { \
+ variable -= offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(dec, __LINE__))
+
+#define SCOPE_EXIT_INC_DEC_TPL(variable, offset) \
+ BOOST_SCOPE_EXIT_ID_TPL(BOOST_PP_CAT(inc, __LINE__), \
+ (&variable) (offset) ) { \
+ variable += offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(inc, __LINE__)) \
+ \
+ BOOST_SCOPE_EXIT_ID_TPL(BOOST_PP_CAT(dec, __LINE__), \
+ (&variable) (offset) ) { \
+ variable -= offset; \
+ } BOOST_SCOPE_EXIT_END_ID(BOOST_PP_CAT(dec, __LINE__))
+
+#define SCOPE_EXIT_ALL_INC_DEC(variable, offset) \
+ BOOST_SCOPE_EXIT_ALL_ID(BOOST_PP_CAT(inc, __LINE__), \
+ (=) (&variable) ) { \
+ variable += offset; \
+ }; \
+ BOOST_SCOPE_EXIT_ALL_ID(BOOST_PP_CAT(dec, __LINE__), \
+ (=) (&variable) ) { \
+ variable -= offset; \
+ };
+
+template<typename T>
+void f(T& x, T& delta) {
+ SCOPE_EXIT_INC_DEC_TPL(x, delta)
+ BOOST_TEST(x == 0);
+}
+
+int main(void) {
+ int x = 0, delta = 10;
+
+ {
+ SCOPE_EXIT_INC_DEC(x, delta)
+ }
+ BOOST_TEST(x == 0);
+
+ f(x, delta);
+
+#ifndef BOOST_NO_CXX11_LAMBDAS
+ {
+ SCOPE_EXIT_ALL_INC_DEC(x, delta)
+ }
+ BOOST_TEST(x == 0);
+#endif // LAMBDAS
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/same_line_seq_nova.cpp b/src/boost/libs/scope_exit/test/same_line_seq_nova.cpp
new file mode 100644
index 000000000..ca45697bc
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/same_line_seq_nova.cpp
@@ -0,0 +1,10 @@
+
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "nova.hpp"
+#include "same_line_seq.cpp"
+
diff --git a/src/boost/libs/scope_exit/test/tu_test.hpp b/src/boost/libs/scope_exit/test/tu_test.hpp
new file mode 100644
index 000000000..25b9a1c6a
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/tu_test.hpp
@@ -0,0 +1,48 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+// No #include guard for this header.
+
+#include <boost/scope_exit.hpp>
+#include <boost/config.hpp>
+
+int tu1(void);
+int tu2(void);
+
+inline int inline_f(void) {
+ int i = 99;
+ {
+ BOOST_SCOPE_EXIT( (&i) ) {
+ i = -1;
+ } BOOST_SCOPE_EXIT_END
+ }
+ return i;
+}
+
+#if !defined(BOOST_INTEL) && defined(__GNUC__) && \
+ (__GNUC__ * 100 + __GNUC_MINOR__) >= 304
+template<class Int>
+Int template_f(Int i) {
+ {
+ BOOST_SCOPE_EXIT_TPL( (&i) ) {
+ ++i;
+ } BOOST_SCOPE_EXIT_END
+ }
+ return i;
+}
+#else
+inline int template_f(int i) {
+ {
+ BOOST_SCOPE_EXIT( (&i) ) {
+ ++i;
+ } BOOST_SCOPE_EXIT_END
+ }
+ return i;
+}
+#endif
+
diff --git a/src/boost/libs/scope_exit/test/world.cpp b/src/boost/libs/scope_exit/test/world.cpp
new file mode 100644
index 000000000..2d6b1ca60
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world.cpp
@@ -0,0 +1,58 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_CXX11_VARIADIC_MACROS
+# error "variadic macros required"
+#else
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+struct person {};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ void add_person(person const& a_person);
+ size_t population(void) const { return persons_.size(); }
+
+private:
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+//[world
+void world::add_person(person const& a_person) {
+ bool commit = false;
+
+ persons_.push_back(a_person); // (1) direct action
+ // Following block is executed when the enclosing scope exits.
+ BOOST_SCOPE_EXIT(&commit, &persons_) {
+ if(!commit) persons_.pop_back(); // (2) rollback action
+ } BOOST_SCOPE_EXIT_END
+
+ // ... // (3) other operations
+
+ commit = true; // (4) disable rollback actions
+}
+//]
+
+int main(void) {
+ world w;
+ person p;
+ w.add_person(p);
+ BOOST_TEST(w.population() == 1);
+ return boost::report_errors();
+}
+
+#endif // variadic macros
+
diff --git a/src/boost/libs/scope_exit/test/world_checkpoint.cpp b/src/boost/libs/scope_exit/test/world_checkpoint.cpp
new file mode 100644
index 000000000..dd101e9f0
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_checkpoint.cpp
@@ -0,0 +1,112 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_CXX11_VARIADIC_MACROS
+# error "variadic macros required"
+#else
+
+#include <boost/scope_exit.hpp>
+#include <boost/foreach.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+#include <iostream>
+#include <sstream>
+
+struct person {
+ typedef unsigned int id_t;
+ typedef unsigned int evolution_t;
+
+ id_t id;
+ evolution_t evolution;
+
+ person(void) : id(0), evolution(0) {}
+
+ friend std::ostream& operator<<(std::ostream& o, person const& p) {
+ return o << "person(" << p.id << ", " << p.evolution << ")";
+ }
+};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ world(void) : next_id_(1) {}
+ void add_person(person const& a_person);
+
+ friend std::ostream& operator<<(std::ostream& o, world const& w) {
+ o << "world(" << w.next_id_ << ", {";
+ BOOST_FOREACH(person const& p, w.persons_) {
+ o << " " << p << ", ";
+ }
+ return o << "})";
+ }
+
+private:
+ person::id_t next_id_;
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+//[world_checkpoint
+void world::add_person(person const& a_person) {
+ persons_.push_back(a_person);
+
+ // This block must be no-throw.
+ person& p = persons_.back();
+ person::evolution_t checkpoint = p.evolution;
+ BOOST_SCOPE_EXIT(checkpoint, &p, &persons_) {
+ if(checkpoint == p.evolution) persons_.pop_back();
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ checkpoint = ++p.evolution;
+
+ // Assign new identifier to the person.
+ person::id_t const prev_id = p.id;
+ p.id = next_id_++;
+ BOOST_SCOPE_EXIT(checkpoint, &p, &next_id_, prev_id) {
+ if(checkpoint == p.evolution) {
+ next_id_ = p.id;
+ p.id = prev_id;
+ }
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ checkpoint = ++p.evolution;
+}
+//]
+
+int main(void) {
+ person adam, eva;
+ std::ostringstream oss;
+ oss << adam;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ oss.str("");
+ oss << eva;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ world w;
+ w.add_person(adam);
+ w.add_person(eva);
+ oss.str("");
+ oss << w;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "world(3, { person(1, 2), person(2, 2), })");
+
+ return boost::report_errors();
+}
+
+#endif // variadic macros
+
diff --git a/src/boost/libs/scope_exit/test/world_checkpoint_all.cpp b/src/boost/libs/scope_exit/test/world_checkpoint_all.cpp
new file mode 100644
index 000000000..c5e547261
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_checkpoint_all.cpp
@@ -0,0 +1,116 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/config.hpp>
+#if defined(BOOST_NO_CXX11_LAMBDAS)
+# error "lambda functions required"
+#elif defined(BOOST_NO_CXX11_VARIADIC_MACROS)
+# error "variadic macros required"
+#else
+
+#include <boost/scope_exit.hpp>
+#include <boost/foreach.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+#include <iostream>
+#include <sstream>
+
+struct person {
+ typedef unsigned int id_t;
+ typedef unsigned int evolution_t;
+
+ id_t id;
+ evolution_t evolution;
+
+ person(void) : id(0), evolution(0) {}
+
+ friend std::ostream& operator<<(std::ostream& o, person const& p) {
+ return o << "person(" << p.id << ", " << p.evolution << ")";
+ }
+};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ world(void) : next_id_(1) {}
+ void add_person(person const& a_person);
+
+ friend std::ostream& operator<<(std::ostream& o, world const& w) {
+ o << "world(" << w.next_id_ << ", {";
+ BOOST_FOREACH(person const& p, w.persons_) {
+ o << " " << p << ", ";
+ }
+ return o << "})";
+ }
+
+private:
+ person::id_t next_id_;
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+//[world_checkpoint_all
+void world::add_person(person const& a_person) {
+ persons_.push_back(a_person);
+
+ // This block must be no-throw.
+ person& p = persons_.back();
+ person::evolution_t checkpoint = p.evolution;
+ // Capture all by reference `&`, but `checkpoint` and `this` (C++11 only).
+ BOOST_SCOPE_EXIT_ALL(&, checkpoint, this) { // Use `this` (not `this_`).
+ if(checkpoint == p.evolution) this->persons_.pop_back();
+ }; // Use `;` (not `SCOPE_EXIT_END`).
+
+ // ...
+
+ checkpoint = ++p.evolution;
+
+ // Assign new identifier to the person.
+ person::id_t const prev_id = p.id;
+ p.id = next_id_++;
+ // Capture all by value `=`, but `p` (C++11 only).
+ BOOST_SCOPE_EXIT_ALL(=, &p) {
+ if(checkpoint == p.evolution) {
+ this->next_id_ = p.id;
+ p.id = prev_id;
+ }
+ };
+
+ // ...
+
+ checkpoint = ++p.evolution;
+}
+//]
+
+int main(void) {
+ person adam, eva;
+ std::ostringstream oss;
+ oss << adam;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ oss.str("");
+ oss << eva;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ world w;
+ w.add_person(adam);
+ w.add_person(eva);
+ oss.str("");
+ oss << w;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "world(3, { person(1, 2), person(2, 2), })");
+
+ return boost::report_errors();
+}
+
+#endif // lambda functions and variadic macros
+
diff --git a/src/boost/libs/scope_exit/test/world_checkpoint_all_seq.cpp b/src/boost/libs/scope_exit/test/world_checkpoint_all_seq.cpp
new file mode 100644
index 000000000..cd5ee5774
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_checkpoint_all_seq.cpp
@@ -0,0 +1,110 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_CXX11_LAMBDAS
+# error "lambda functions required"
+#else
+
+#include <boost/scope_exit.hpp>
+#include <boost/foreach.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+#include <iostream>
+#include <sstream>
+
+struct person {
+ typedef unsigned int id_t;
+ typedef unsigned int evolution_t;
+
+ id_t id;
+ evolution_t evolution;
+
+ person(void) : id(0), evolution(0) {}
+
+ friend std::ostream& operator<<(std::ostream& o, person const& p) {
+ return o << "person(" << p.id << ", " << p.evolution << ")";
+ }
+};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ world(void) : next_id_(1) {}
+ void add_person(person const& a_person);
+
+ friend std::ostream& operator<<(std::ostream& o, world const& w) {
+ o << "world(" << w.next_id_ << ", {";
+ BOOST_FOREACH(person const& p, w.persons_) {
+ o << " " << p << ", ";
+ }
+ return o << "})";
+ }
+
+private:
+ person::id_t next_id_;
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+void world::add_person(person const& a_person) {
+ persons_.push_back(a_person);
+
+ // This block must be no-throw.
+ person& p = persons_.back();
+ person::evolution_t checkpoint = p.evolution;
+ BOOST_SCOPE_EXIT_ALL( (&) (checkpoint) (this) ) {
+ if(checkpoint == p.evolution) this->persons_.pop_back();
+ };
+
+ // ...
+
+ checkpoint = ++p.evolution;
+
+ // Assign new identifier to the person.
+ person::id_t const prev_id = p.id;
+ p.id = next_id_++;
+ BOOST_SCOPE_EXIT_ALL( (=) (&p) ) {
+ if(checkpoint == p.evolution) {
+ this->next_id_ = p.id;
+ p.id = prev_id;
+ }
+ };
+
+ // ...
+
+ checkpoint = ++p.evolution;
+}
+
+int main(void) {
+ person adam, eva;
+ std::ostringstream oss;
+ oss << adam;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ oss.str("");
+ oss << eva;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ world w;
+ w.add_person(adam);
+ w.add_person(eva);
+ oss.str("");
+ oss << w;
+ std::cout << oss.str() << std::endl;
+ BOOST_TEST(oss.str() == "world(3, { person(1, 2), person(2, 2), })");
+
+ return boost::report_errors();
+}
+
+#endif // variadic macros
+
diff --git a/src/boost/libs/scope_exit/test/world_checkpoint_all_seq_nova.cpp b/src/boost/libs/scope_exit/test/world_checkpoint_all_seq_nova.cpp
new file mode 100644
index 000000000..b1be0744f
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_checkpoint_all_seq_nova.cpp
@@ -0,0 +1,10 @@
+
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "nova.hpp"
+#include "world_checkpoint_all_seq.cpp"
+
diff --git a/src/boost/libs/scope_exit/test/world_checkpoint_seq.cpp b/src/boost/libs/scope_exit/test/world_checkpoint_seq.cpp
new file mode 100644
index 000000000..1537036e0
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_checkpoint_seq.cpp
@@ -0,0 +1,99 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/foreach.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+#include <sstream>
+
+struct person {
+ typedef unsigned int id_t;
+ typedef unsigned int evolution_t;
+
+ id_t id;
+ evolution_t evolution;
+
+ person(void) : id(0), evolution(0) {}
+
+ friend std::ostream& operator<<(std::ostream& o, person const& p) {
+ return o << "person(" << p.id << ", " << p.evolution << ")";
+ }
+};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ world(void) : next_id_(1) {}
+ void add_person(person const& a_person);
+
+ friend std::ostream& operator<<(std::ostream& o, world const& w) {
+ o << "world(" << w.next_id_ << ", {";
+ BOOST_FOREACH(person const& p, w.persons_) {
+ o << " " << p << ", ";
+ }
+ return o << "})";
+ }
+
+private:
+ person::id_t next_id_;
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+void world::add_person(person const& a_person) {
+ persons_.push_back(a_person);
+
+ // This block must be no-throw.
+ person& p = persons_.back();
+ person::evolution_t checkpoint = p.evolution;
+ BOOST_SCOPE_EXIT( (checkpoint) (&p) (&persons_) ) {
+ if(checkpoint == p.evolution) persons_.pop_back();
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ checkpoint = ++p.evolution;
+
+ // Assign new identifier to the person.
+ person::id_t const prev_id = p.id;
+ p.id = next_id_++;
+ BOOST_SCOPE_EXIT( (checkpoint) (&p) (&next_id_) (prev_id) ) {
+ if(checkpoint == p.evolution) {
+ next_id_ = p.id;
+ p.id = prev_id;
+ }
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ checkpoint = ++p.evolution;
+}
+
+int main(void) {
+ person adam, eva;
+ std::ostringstream oss;
+ oss << adam;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ oss.str("");
+ oss << eva;
+ BOOST_TEST(oss.str() == "person(0, 0)");
+
+ world w;
+ w.add_person(adam);
+ w.add_person(eva);
+ oss.str("");
+ oss << w;
+ BOOST_TEST(oss.str() == "world(3, { person(1, 2), person(2, 2), })");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/world_checkpoint_seq_nova.cpp b/src/boost/libs/scope_exit/test/world_checkpoint_seq_nova.cpp
new file mode 100644
index 000000000..dc6f991a8
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_checkpoint_seq_nova.cpp
@@ -0,0 +1,10 @@
+
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "nova.hpp"
+#include "world_checkpoint_seq.cpp"
+
diff --git a/src/boost/libs/scope_exit/test/world_seq.cpp b/src/boost/libs/scope_exit/test/world_seq.cpp
new file mode 100644
index 000000000..0a7299eef
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_seq.cpp
@@ -0,0 +1,51 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+struct person {};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ void add_person(person const& a_person);
+ size_t population(void) const { return persons_.size(); }
+
+private:
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+//[world_seq
+void world::add_person(person const& a_person) {
+ bool commit = false;
+
+ persons_.push_back(a_person); // (1) direct action
+ // Following block is executed when the enclosing scope exits.
+ BOOST_SCOPE_EXIT( (&commit) (&persons_) ) {
+ if(!commit) persons_.pop_back(); // (2) rollback action
+ } BOOST_SCOPE_EXIT_END
+
+ // ... // (3) other operations
+
+ commit = true; // (4) disable rollback actions
+}
+//]
+
+int main(void) {
+ world w;
+ person p;
+ w.add_person(p);
+ BOOST_TEST(w.population() == 1);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/world_seq_nova.cpp b/src/boost/libs/scope_exit/test/world_seq_nova.cpp
new file mode 100644
index 000000000..8809f1cce
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_seq_nova.cpp
@@ -0,0 +1,10 @@
+
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "nova.hpp"
+#include "world_seq.cpp"
+
diff --git a/src/boost/libs/scope_exit/test/world_this.cpp b/src/boost/libs/scope_exit/test/world_this.cpp
new file mode 100644
index 000000000..ddb88ac91
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_this.cpp
@@ -0,0 +1,58 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_CXX11_VARIADIC_MACROS
+# error "variadic macros required"
+#else
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/config.hpp>
+#include <vector>
+
+struct person {};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ void add_person(person const& a_person);
+ size_t population(void) const { return persons_.size(); }
+
+private:
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+void world::add_person(person const& a_person) {
+ bool commit = false;
+
+ persons_.push_back(a_person);
+ //[world_this
+ BOOST_SCOPE_EXIT(&commit, this_) { // Capture object `this_`.
+ if(!commit) this_->persons_.pop_back();
+ } BOOST_SCOPE_EXIT_END
+ //]
+
+ // ...
+
+ commit = true;
+}
+
+int main(void) {
+ world w;
+ person p;
+ w.add_person(p);
+ BOOST_TEST(w.population() == 1);
+ return boost::report_errors();
+}
+
+#endif // variadic macros
+
diff --git a/src/boost/libs/scope_exit/test/world_this_seq.cpp b/src/boost/libs/scope_exit/test/world_this_seq.cpp
new file mode 100644
index 000000000..6d7b7cb08
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_this_seq.cpp
@@ -0,0 +1,49 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/config.hpp>
+#include <vector>
+
+struct person {};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world {
+ void add_person(person const& a_person);
+ size_t population(void) const { return persons_.size(); }
+
+private:
+ std::vector<person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TYPE(world)
+
+void world::add_person(person const& a_person) {
+ bool commit = false;
+
+ persons_.push_back(a_person);
+ BOOST_SCOPE_EXIT( (&commit) (this_) ) {
+ if(!commit) this_->persons_.pop_back();
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ commit = true;
+}
+
+int main(void) {
+ world w;
+ person p;
+ w.add_person(p);
+ BOOST_TEST(w.population() == 1);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/world_this_seq_nova.cpp b/src/boost/libs/scope_exit/test/world_this_seq_nova.cpp
new file mode 100644
index 000000000..5fe0bf518
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_this_seq_nova.cpp
@@ -0,0 +1,10 @@
+
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "nova.hpp"
+#include "world_this_seq.cpp"
+
diff --git a/src/boost/libs/scope_exit/test/world_tpl.cpp b/src/boost/libs/scope_exit/test/world_tpl.cpp
new file mode 100644
index 000000000..fe2a117f9
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_tpl.cpp
@@ -0,0 +1,59 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_CXX11_VARIADIC_MACROS
+# error "variadic macro required"
+#else
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+struct person {};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+template<typename Person>
+struct world {
+ void add_person(Person const& a_person);
+ size_t population(void) const { return persons_.size(); }
+
+private:
+ std::vector<Person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TEMPLATE(world, 1)
+
+//[world_tpl
+template<typename Person>
+void world<Person>::add_person(Person const& a_person) {
+ bool commit = false;
+ persons_.push_back(a_person);
+
+ BOOST_SCOPE_EXIT_TPL(&commit, this_) { // Use `_TPL` postfix.
+ if(!commit) this_->persons_.pop_back();
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ commit = true;
+}
+//]
+
+int main(void) {
+ world<person> w;
+ person p;
+ w.add_person(p);
+ BOOST_TEST(w.population() == 1);
+ return boost::report_errors();
+}
+
+#endif // variadic macros
+
diff --git a/src/boost/libs/scope_exit/test/world_tpl_seq.cpp b/src/boost/libs/scope_exit/test/world_tpl_seq.cpp
new file mode 100644
index 000000000..9a890d64a
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_tpl_seq.cpp
@@ -0,0 +1,50 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+struct person {};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+template<typename Person>
+struct world {
+ void add_person(Person const& a_person);
+ size_t population(void) const { return persons_.size(); }
+
+private:
+ std::vector<Person> persons_;
+};
+BOOST_TYPEOF_REGISTER_TEMPLATE(world, 1)
+
+template<typename Person>
+void world<Person>::add_person(Person const& a_person) {
+ bool commit = false;
+ persons_.push_back(a_person);
+
+ BOOST_SCOPE_EXIT_TPL( (&commit) (this_) ) {
+ if(!commit) this_->persons_.pop_back();
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ commit = true;
+}
+
+int main(void) {
+ world<person> w;
+ person p;
+ w.add_person(p);
+ BOOST_TEST(w.population() == 1);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/world_tpl_seq_nova.cpp b/src/boost/libs/scope_exit/test/world_tpl_seq_nova.cpp
new file mode 100644
index 000000000..f25c2d554
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_tpl_seq_nova.cpp
@@ -0,0 +1,10 @@
+
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "nova.hpp"
+#include "world_tpl_seq.cpp"
+
diff --git a/src/boost/libs/scope_exit/test/world_void.cpp b/src/boost/libs/scope_exit/test/world_void.cpp
new file mode 100644
index 000000000..04cf18517
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_void.cpp
@@ -0,0 +1,48 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include <boost/scope_exit.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+struct person {};
+BOOST_TYPEOF_REGISTER_TYPE(person)
+
+struct world_t;
+BOOST_TYPEOF_REGISTER_TYPE(world_t)
+
+//[world_void
+struct world_t {
+ std::vector<person> persons;
+ bool commit;
+} world; // Global variable.
+
+void add_person(person const& a_person) {
+ world.commit = false;
+ world.persons.push_back(a_person);
+
+ BOOST_SCOPE_EXIT(void) { // No captures.
+ if(!world.commit) world.persons.pop_back();
+ } BOOST_SCOPE_EXIT_END
+
+ // ...
+
+ world.commit = true;
+}
+//]
+
+int main(void) {
+ person p;
+ add_person(p);
+ BOOST_TEST(world.persons.size() == 1);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/scope_exit/test/world_void_nova.cpp b/src/boost/libs/scope_exit/test/world_void_nova.cpp
new file mode 100644
index 000000000..777067f86
--- /dev/null
+++ b/src/boost/libs/scope_exit/test/world_void_nova.cpp
@@ -0,0 +1,11 @@
+
+// Copyright (C) 2006-2009, 2012 Alexander Nasonov
+// Copyright (C) 2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/scope_exit
+
+#include "nova.hpp"
+#include "world_void.cpp"
+