diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/scope_exit | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/scope_exit')
43 files changed, 1950 insertions, 0 deletions
diff --git a/src/boost/libs/scope_exit/example/Jamfile.v2 b/src/boost/libs/scope_exit/example/Jamfile.v2 new file mode 100644 index 000000000..82db03a52 --- /dev/null +++ b/src/boost/libs/scope_exit/example/Jamfile.v2 @@ -0,0 +1,23 @@ + +# 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 ; + +# Sun does not automatically detect type-of emulation mode (force it). +project : requirements <toolset>sun:<define>BOOST_TYPEOF_EMULATION ; + +run try_catch.cpp ; +run try_catch_seq.cpp ; +run try_catch_seq_nova.cpp ; + +run scope_guard.cpp ; +run scope_guard_seq.cpp ; +run scope_guard_seq_nova.cpp ; + +run world_cxx11_lambda.cpp ; + diff --git a/src/boost/libs/scope_exit/example/nova.hpp b/src/boost/libs/scope_exit/example/nova.hpp new file mode 100644 index 000000000..ceef87eed --- /dev/null +++ b/src/boost/libs/scope_exit/example/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/example/scope_guard.cpp b/src/boost/libs/scope_exit/example/scope_guard.cpp new file mode 100644 index 000000000..1371c5e99 --- /dev/null +++ b/src/boost/libs/scope_exit/example/scope_guard.cpp @@ -0,0 +1,46 @@ + +// 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/std/string.hpp> +#include <boost/typeof/std/map.hpp> +#include <map> +#include <string> +#include <utility> + +int main(void) { + //[scope_guard_decl + bool commit = false; + std::string currency("EUR"); + double rate = 1.3326; + std::map<std::string, double> rates; + bool currency_rate_inserted = + rates.insert(std::make_pair(currency, rate)).second; + // Transaction... + //] + + //[scope_guard_exit + BOOST_SCOPE_EXIT(currency_rate_inserted, &commit, &rates, ¤cy) { + if(currency_rate_inserted && !commit) rates.erase(currency); + } BOOST_SCOPE_EXIT_END + + // ... + + commit = true; + //] + + return 0; +} + +#endif // variadic macros + diff --git a/src/boost/libs/scope_exit/example/scope_guard_seq.cpp b/src/boost/libs/scope_exit/example/scope_guard_seq.cpp new file mode 100644 index 000000000..167cd719c --- /dev/null +++ b/src/boost/libs/scope_exit/example/scope_guard_seq.cpp @@ -0,0 +1,35 @@ + +// 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/std/string.hpp> +#include <boost/typeof/std/map.hpp> +#include <map> +#include <string> +#include <utility> + +int main(void) { + bool commit = false; + std::string currency("EUR"); + double rate = 1.3326; + std::map<std::string, double> rates; + bool currency_rate_inserted = + rates.insert(std::make_pair(currency, rate)).second; + + BOOST_SCOPE_EXIT( (currency_rate_inserted) (&commit) (&rates) + (¤cy) ) { + if(currency_rate_inserted && !commit) rates.erase(currency); + } BOOST_SCOPE_EXIT_END + + // ... + + commit = true; + + return 0; +} + diff --git a/src/boost/libs/scope_exit/example/scope_guard_seq_nova.cpp b/src/boost/libs/scope_exit/example/scope_guard_seq_nova.cpp new file mode 100644 index 000000000..2289a932c --- /dev/null +++ b/src/boost/libs/scope_exit/example/scope_guard_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 "scope_guard_seq.cpp" + diff --git a/src/boost/libs/scope_exit/example/try_catch.cpp b/src/boost/libs/scope_exit/example/try_catch.cpp new file mode 100644 index 000000000..4d0023281 --- /dev/null +++ b/src/boost/libs/scope_exit/example/try_catch.cpp @@ -0,0 +1,68 @@ + +// 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_INCREMENT_REGISTRATION_GROUP() +#include <iostream> + +struct file { + file(void) : open_(false) {} + file(char const* path) : open_(false) { open(path); } + + void open(char const* path) { open_ = true; } + void close(void) { open_ = false; } + bool is_open(void) const { return open_; } + +private: + bool open_; +}; +BOOST_TYPEOF_REGISTER_TYPE(file) + +void bad(void) { + //[try_catch_bad + file passwd; + try { + passwd.open("/etc/passwd"); + // ... + passwd.close(); + } catch(...) { + std::clog << "could not get user info" << std::endl; + if(passwd.is_open()) passwd.close(); + throw; + } + //] +} + +void good(void) { + //[try_catch_good + try { + file passwd("/etc/passwd"); + BOOST_SCOPE_EXIT(&passwd) { + passwd.close(); + } BOOST_SCOPE_EXIT_END + } catch(...) { + std::clog << "could not get user info" << std::endl; + throw; + } + //] +} + +int main(void) { + bad(); + good(); + return 0; +} + +#endif // variadic macros + diff --git a/src/boost/libs/scope_exit/example/try_catch_seq.cpp b/src/boost/libs/scope_exit/example/try_catch_seq.cpp new file mode 100644 index 000000000..8ff7ea5f5 --- /dev/null +++ b/src/boost/libs/scope_exit/example/try_catch_seq.cpp @@ -0,0 +1,61 @@ + +// 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_INCREMENT_REGISTRATION_GROUP() +#include <iostream> + +struct file { + file(void) : open_(false) {} + file(char const* path) : open_(false) { open(path); } + + void open(char const* path) { open_ = true; } + void close(void) { open_ = false; } + bool is_open(void) const { return open_; } + +private: + bool open_; +}; +BOOST_TYPEOF_REGISTER_TYPE(file) + +void bad(void) { + //[try_catch_bad_seq + file passwd; + try { + passwd.open("/etc/passwd"); + // ... + passwd.close(); + } catch(...) { + std::clog << "could not get user info" << std::endl; + if(passwd.is_open()) passwd.close(); + throw; + } + //] +} + +void good(void) { + //[try_catch_good_seq + try { + file passwd("/etc/passwd"); + BOOST_SCOPE_EXIT( (&passwd) ) { + passwd.close(); + } BOOST_SCOPE_EXIT_END + } catch(...) { + std::clog << "could not get user info" << std::endl; + throw; + } + //] +} + +int main(void) { + bad(); + good(); + return 0; +} + diff --git a/src/boost/libs/scope_exit/example/try_catch_seq_nova.cpp b/src/boost/libs/scope_exit/example/try_catch_seq_nova.cpp new file mode 100644 index 000000000..70f0043a4 --- /dev/null +++ b/src/boost/libs/scope_exit/example/try_catch_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 "try_catch_seq.cpp" + diff --git a/src/boost/libs/scope_exit/example/world_cxx11_lambda.cpp b/src/boost/libs/scope_exit/example/world_cxx11_lambda.cpp new file mode 100644 index 000000000..c8e23d5ee --- /dev/null +++ b/src/boost/libs/scope_exit/example/world_cxx11_lambda.cpp @@ -0,0 +1,57 @@ + +// 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/detail/lightweight_test.hpp> +#include <vector> + +struct person {}; + +struct world { + void add_person(person const& a_person); + std::vector<person> persons_; +}; + +//[world_cxx11_lambda +#include <functional> + +struct scope_exit { + scope_exit(std::function<void (void)> f) : f_(f) {} + ~scope_exit(void) { f_(); } +private: + std::function<void (void)> f_; +}; + +void world::add_person(person const& a_person) { + bool commit = false; + + persons_.push_back(a_person); + scope_exit on_exit1([&commit, this](void) { // Use C++11 lambda. + if(!commit) persons_.pop_back(); // `persons_` via captured `this`. + }); + + // ... + + commit = true; +} +//] + +int main(void) { + world w; + person p; + w.add_person(p); + BOOST_TEST(w.persons_.size() == 1); + return boost::report_errors(); +} + +#endif // LAMBDAS + diff --git a/src/boost/libs/scope_exit/index.html b/src/boost/libs/scope_exit/index.html new file mode 100644 index 000000000..c28485bd7 --- /dev/null +++ b/src/boost/libs/scope_exit/index.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <meta http-equiv="refresh" content="0; URL=doc/html/index.html"> + </head> + <body> + Automatic redirection failed, click this + <a href="doc/html/index.html">link</a> <hr> + <p>© Copyright Alexander Nasonov, Lorenzo Caminiti, 2006-2012</p> + <p>Distributed under the Boost Software License, Version 1.0 (see + accompanying file <a href="../../LICENSE_1_0.txt"> + LICENSE_1_0.txt</a> or a copy at + <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> + </body> +</html> diff --git a/src/boost/libs/scope_exit/meta/libraries.json b/src/boost/libs/scope_exit/meta/libraries.json new file mode 100644 index 000000000..8b8fa9156 --- /dev/null +++ b/src/boost/libs/scope_exit/meta/libraries.json @@ -0,0 +1,15 @@ +{ + "key": "scope_exit", + "name": "Scope Exit", + "authors": [ + "Alexander Nasonov" + ], + "description": "Execute arbitrary code at scope exit.", + "category": [ + "Emulation" + ], + "maintainers": [ + "Alexander Nasonov <alexander.nasonov -at- gmail.com>", + "Lorenzo Caminiti <lorcaminiti -at- gmail.com>" + ] +} 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" + |