diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/contract/test/destructor | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/contract/test/destructor')
25 files changed, 4226 insertions, 0 deletions
diff --git a/src/boost/libs/contract/test/destructor/access.cpp b/src/boost/libs/contract/test/destructor/access.cpp new file mode 100644 index 00000000..757248e6 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/access.cpp @@ -0,0 +1,122 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test making all contract extra declarations (base types, inv, etc.) private. + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +class b { + friend class boost::contract::access; + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + +public: + virtual ~b() { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + } +}; + +class a + #define BASES public b + : BASES +{ + friend class boost::contract::access; + + // Private base types (always OK because never used by dtors). + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + // Private invariants. + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + +public: + virtual ~a() { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + { + a aa; + out.str(""); + } // Call aa's destructor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + { + b bb; + out.str(""); + } // Call bb's destructor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl.hpp b/src/boost/libs/contract/test/destructor/decl.hpp new file mode 100644 index 00000000..8fdc8c3d --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl.hpp @@ -0,0 +1,145 @@ + +#ifndef BOOST_CONTRACT_TEST_DESTRUCTOR_DECL_HPP_ +#define BOOST_CONTRACT_TEST_DESTRUCTOR_DECL_HPP_ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test with and without pre, post, and inv declarations. + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/config.hpp> + +boost::contract::test::detail::oteststream out; + +bool c_pre = true, c_post = true; +bool c_entering_static_inv = true, c_entry_static_inv = true, + c_exit_static_inv = true; +bool c_entry_inv = true; // Only entry non-static inv for dtors. +struct c { + #ifndef BOOST_CONTRACT_TEST_NO_C_STATIC_INV + static void static_invariant() { + out << "c::static_inv" << std::endl; + if(c_entering_static_inv) BOOST_CONTRACT_ASSERT(c_entry_static_inv); + else BOOST_CONTRACT_ASSERT(c_exit_static_inv); + c_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_C_INV + void invariant() const { + out << "c::inv" << std::endl; + BOOST_CONTRACT_ASSERT(c_entry_inv); + } + #endif + + virtual ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + #ifdef BOOST_CONTRACT_TEST_NO_C_PRE + #error "destructors cannot have preconditions" + #endif + .old([] { out << "c::dtor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_C_POST + .postcondition([] { + out << "c::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(c_post); + }) + #endif + ; + out << "c::dtor::body" << std::endl; + } +}; + +bool b_pre = true, b_post = true; +bool b_entering_static_inv = true, b_entry_static_inv = true, + b_exit_static_inv = true; +bool b_entry_inv = true; // Only entry non-static inv for dtors. +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + #ifndef BOOST_CONTRACT_TEST_NO_B_STATIC_INV + static void static_invariant() { + out << "b::static_inv" << std::endl; + if(b_entering_static_inv) BOOST_CONTRACT_ASSERT(b_entry_static_inv); + else BOOST_CONTRACT_ASSERT(b_exit_static_inv); + b_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_B_INV + void invariant() const { + out << "b::inv" << std::endl; + BOOST_CONTRACT_ASSERT(b_entry_inv); + } + #endif + + virtual ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + #ifdef BOOST_CONTRACT_TEST_NO_B_PRE + #error "destructors cannot have preconditions" + #endif + .old([] { out << "b::dtor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_B_POST + .postcondition([] { + out << "b::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(b_post); + }) + #endif + ; + out << "b::dtor::body" << std::endl; + } +}; + +bool a_pre = true, a_post = true; +bool a_entering_static_inv = true, a_entry_static_inv = true, + a_exit_static_inv = true; +bool a_entry_inv = true; // Only entry non-static inv for dtors. +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + #ifndef BOOST_CONTRACT_TEST_NO_A_STATIC_INV + static void static_invariant() { + out << "a::static_inv" << std::endl; + if(a_entering_static_inv) BOOST_CONTRACT_ASSERT(a_entry_static_inv); + else BOOST_CONTRACT_ASSERT(a_exit_static_inv); + a_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_A_INV + void invariant() const { + out << "a::inv" << std::endl; + BOOST_CONTRACT_ASSERT(a_entry_inv); + } + #endif + + virtual ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + #ifdef BOOST_CONTRACT_TEST_NO_A_PRE + #error "destructors cannot have preconditions" + #endif + .old([] { out << "a::dtor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_A_POST + .postcondition([] { + out << "a::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(a_post); + }) + #endif + ; + out << "a::dtor::body" << std::endl; + } +}; + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_all.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_all.cpp new file mode 100644 index 00000000..39395c7a --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_all.cpp @@ -0,0 +1,222 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with entry static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_INV +#undef BOOST_CONTRACT_TEST_NO_B_INV +#undef BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl // This can fail. + #endif + ; + if(!failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_b(checked check = passed) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl // This can fail. + #endif + ; + if(check != failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (check == threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // This can fail. + #endif + ; + if(check != failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + // Test entry a::inv failed... + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test entry b::inv failed... + << ok_b(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test entry c::inv failed... + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple except, + // just ignore failure and continue test program (for testing only). + }); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test entry a::inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::dtor::body" << std::endl + #endif + + // Test entry b::inv failed (as all did). + << ok_b(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::dtor::body" << std::endl + #endif + + // Test entry c::inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::dtor::body" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_ends.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_ends.cpp new file mode 100644 index 00000000..f7cee609 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_ends.cpp @@ -0,0 +1,206 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with entry invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_INV +#define BOOST_CONTRACT_TEST_NO_B_INV +#undef BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl // This can fail. + #endif + ; + if(!failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + // No b::inv here (not even when threw). + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // This can fail. + #endif + ; + if(check != failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // for testing (as dtors should never throw anyways). + }); + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + // Test entry a::inv failed... + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv) + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no entry b::inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test entry c::inv failed... + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test entry a::inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::dtor::body" << std::endl + #endif + + << ok_b() // Test no entry b::inv so no failure here. + + // Test entry c::inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::dtor::body" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_mid.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_mid.cpp new file mode 100644 index 00000000..247d68ce --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_mid.cpp @@ -0,0 +1,194 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with entry invariants. + +#define BOOST_CONTRACT_TEST_NO_A_INV +#undef BOOST_CONTRACT_TEST_NO_B_INV +#define BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool failed = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl // This can fail. + #endif + ; + if(!failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + // No b::inv here (not even when threw). + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // for testing (as dtors should never throw anyways). + }); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no entry a::inv so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 2 + #endif + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test entry b::inv failed... + << ok_b(bool(BOOST_CONTRACT_TEST_entry_inv)) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(bool(BOOST_CONTRACT_TEST_entry_inv)) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test no entry c::inv so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no entry a::inv so no failure here. + + // Test entry b::inv failed (as all did). + << ok_b(bool(BOOST_CONTRACT_TEST_entry_inv)) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::dtor::body" << std::endl + #endif + + << ok_c() // Test no entry c::inv so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_none.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_none.cpp new file mode 100644 index 00000000..342a7893 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_none.cpp @@ -0,0 +1,109 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without entry invariants. + +#define BOOST_CONTRACT_TEST_NO_A_INV +#define BOOST_CONTRACT_TEST_NO_B_INV +#define BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + ; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_all.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_all.cpp new file mode 100644 index 00000000..34476bb8 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_all.cpp @@ -0,0 +1,231 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with entry static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed... + #else + << ok_a() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv) + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl // Test this failed... + #else + << ok_b() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // Test this failed... + #else + << ok_c() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed (as all did)... + << "a::dtor::body" << std::endl + + << "b::static_inv" << std::endl // Test this failed (as all did)... + << "b::dtor::body" << std::endl + + << "c::static_inv" << std::endl // Test this failed (as all did)... + << "c::dtor::body" << std::endl + #else + << ok_a() + << ok_b() + << ok_c() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_ends.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_ends.cpp new file mode 100644 index 00000000..11bb1ced --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_ends.cpp @@ -0,0 +1,216 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with entry static inv. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed... + #else + << ok_a() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv) + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no b::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // Test this failed... + #else + << ok_c() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program. + }); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed (as all did). + << "a::dtor::body" << std::endl + + << ok_b() // Test no b::static_inv so no failure here. + + << "c::static_inv" << std::endl // Test this failed (as all did). + << "c::dtor::body" << std::endl + #else + << ok_a() + << ok_b() + << ok_c() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_mid.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_mid.cpp new file mode 100644 index 00000000..6f813212 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_mid.cpp @@ -0,0 +1,203 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with entry static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no a::static_inv so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl // Test this failed... + #else + << ok_b() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test no c::static_inv so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_a() // Test no a::static_inv so no failure here. + + << "b::static_inv" << std::endl // Test this failed (as all did)... + << "b::dtor::body" << std::endl + + << ok_c() // Test no c::static_inv so no failure here. + #else + << ok_a() + << ok_b() + << ok_c() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_none.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_none.cpp new file mode 100644 index 00000000..acc7b682 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_none.cpp @@ -0,0 +1,118 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without entry static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + ; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_all.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_all.cpp new file mode 100644 index 00000000..4cb68fea --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_all.cpp @@ -0,0 +1,222 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with exit static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl // This can fail. + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!failed ? "a::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_b(checked check = passed) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl // This can fail. + << (check == threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // This can fail. + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #define BOOST_CONTRACT_TEST_exit_inv 0 + #else + #define BOOST_CONTRACT_TEST_exit_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (as dtors should not throw otherwise). + }); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + // Test a::static_inv failed... + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test b::static_inv failed... + << ok_b(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test exit c::static_inv failed. + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ... then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_exit_invariant_failure([] (boost::contract::from) { + // Testing multiple failures but dtors must not throw multiple except, + // just ignore failure and continue test program (for testing only). + }); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test exit a::static_inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + // Test exit b::static_inv failed (as all did). + << ok_b(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + // Test exit c::static_inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + #undef BOOST_CONTRACT_TEST_exit_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_ends.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_ends.cpp new file mode 100644 index 00000000..cbce7514 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_ends.cpp @@ -0,0 +1,211 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with exit static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl // This can fail. + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!failed ? "a::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // This can fail. + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #define BOOST_CONTRACT_TEST_exit_inv 0 + #else + #define BOOST_CONTRACT_TEST_exit_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (as dtors should not throw otherwise). + }); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + // Test a::static_inv failed... + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_exit_inv) + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no exit b::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test c::static_inv failed... + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_exit_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test a::static_inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + // Test no exit b::static_inv so no failure here. + << ok_b() + // Test c::static_inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + #undef BOOST_CONTRACT_TEST_exit_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_mid.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_mid.cpp new file mode 100644 index 00000000..bd5cce64 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_mid.cpp @@ -0,0 +1,203 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with exit static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool failed = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl // This can fail. + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!failed ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #define BOOST_CONTRACT_TEST_exit_inv 0 + #else + #define BOOST_CONTRACT_TEST_exit_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (as dtors should not throw otherwise). + }); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no exit a::static_inv so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test exit b::static_inv failed... + << ok_b(BOOST_CONTRACT_TEST_exit_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_exit_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + // Test no exit c::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_exit_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple except, + // just ignore failure and continue test program (for testing only). + }); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test no exit a::static_inv so no faliure here. + << ok_a() + // Test exit b::static_inv failed (as all did). + << ok_b(BOOST_CONTRACT_TEST_exit_inv) + // Test no exit c::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + #undef BOOST_CONTRACT_TEST_exit_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_none.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_none.cpp new file mode 100644 index 00000000..0d572adb --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_none.cpp @@ -0,0 +1,118 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without exit static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + ; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_all.cpp b/src/boost/libs/contract/test/destructor/decl_post_all.cpp new file mode 100644 index 00000000..8617b478 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_all.cpp @@ -0,0 +1,200 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with postconditions. + +#undef BOOST_CONTRACT_TEST_NO_A_POST +#undef BOOST_CONTRACT_TEST_NO_B_POST +#undef BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") // This can fail. + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // for testing (as dtors should never throw anyways). + }); + + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + #define BOOST_CONTRACT_TEST_post 0 + #else + #define BOOST_CONTRACT_TEST_post 1 + #endif + + a_post = false; + b_post = true; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() // Test b::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test c::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_post + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_ends.cpp b/src/boost/libs/contract/test/destructor/decl_post_ends.cpp new file mode 100644 index 00000000..942d2ed9 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_ends.cpp @@ -0,0 +1,191 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with postconditions. + +#undef BOOST_CONTRACT_TEST_NO_A_POST +#define BOOST_CONTRACT_TEST_NO_B_POST +#undef BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (threw ? "b::inv\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") // This can fail. + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // ... for testing (as dtors should never throw anyways). + }); + + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + #define BOOST_CONTRACT_TEST_post 0 + #else + #define BOOST_CONTRACT_TEST_post 1 + #endif + + a_post = false; + b_post = true; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no b::dtor::post so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test c::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ... then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_post + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_mid.cpp b/src/boost/libs/contract/test/destructor/decl_post_mid.cpp new file mode 100644 index 00000000..54197b1a --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_mid.cpp @@ -0,0 +1,182 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with postconditions. + +#define BOOST_CONTRACT_TEST_NO_A_POST +#undef BOOST_CONTRACT_TEST_NO_B_POST +#define BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // ... for testing (as dtors should never throw anyways). + }); + + a_post = false; + b_post = true; + c_post = true; + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no a::dtor::post so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + #define BOOST_CONTRACT_TEST_post 0 + #else + #define BOOST_CONTRACT_TEST_post 1 + #endif + + a_post = true; + b_post = false; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() // Test b::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test no c::dtor::post so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() // Test b::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_post + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_none.cpp b/src/boost/libs/contract/test/destructor/decl_post_none.cpp new file mode 100644 index 00000000..9b3eb4df --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_none.cpp @@ -0,0 +1,103 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without postconditions. + +#define BOOST_CONTRACT_TEST_NO_A_POST +#define BOOST_CONTRACT_TEST_NO_B_POST +#define BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + ; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = false; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = true; + b_post = false; + c_post = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = true; + b_post = true; + c_post = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = false; + b_post = false; + c_post = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/ifdef.cpp b/src/boost/libs/contract/test/destructor/ifdef.cpp new file mode 100644 index 00000000..53c4c89d --- /dev/null +++ b/src/boost/libs/contract/test/destructor/ifdef.cpp @@ -0,0 +1,111 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test contract compilation on/off. + +#include "../detail/oteststream.hpp" +#include <boost/contract/core/config.hpp> +#ifndef BOOST_CONTRACT_NO_DESTRUCTORS + #include <boost/contract/destructor.hpp> + #include <boost/contract/check.hpp> + #include <boost/contract/old.hpp> +#endif +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct b { + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + #endif + + virtual ~b() { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_y = BOOST_CONTRACT_OLDOF(y); + #endif + #ifndef BOOST_CONTRACT_NO_DESTRUCTORS + boost::contract::check c = boost::contract::destructor(this) + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + #endif + ; + #endif + out << "b::dtor::body" << std::endl; + } + + static int y; +}; +int b::y = 0; + +struct a : public b { + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + #endif + + virtual ~a() { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); + #endif + #ifndef BOOST_CONTRACT_NO_DESTRUCTORS + boost::contract::check c = boost::contract::destructor(this) + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + #endif + ; + #endif + out << "a::dtor::body" << std::endl; + } + + static int x; +}; +int a::x = 0; + +int main() { + std::ostringstream ok; + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/ifdef_macro.cpp b/src/boost/libs/contract/test/destructor/ifdef_macro.cpp new file mode 100644 index 00000000..cc14b469 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/ifdef_macro.cpp @@ -0,0 +1,142 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test contract compilation on/off (using macro interface). + +#include "../detail/oteststream.hpp" +#include "../detail/unprotected_commas.hpp" +#include <boost/contract/core/config.hpp> +#include <boost/contract_macro.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct b { + BOOST_CONTRACT_STATIC_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "b::static_inv" << std::endl; + }) + + BOOST_CONTRACT_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "b::inv" << std::endl; + }) + + virtual ~b() { + BOOST_CONTRACT_OLD_PTR( + boost::contract::test::detail::unprotected_commas<int, void, + void>::type1 + )( + old_y, + (boost::contract::test::detail::unprotected_commas<void, void, + void>::same(y)) + ); + BOOST_CONTRACT_DESTRUCTOR(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "b::dtor::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "b::dtor::post" << std::endl; + }) + ; + out << "b::dtor::body" << std::endl; + } + + static int y; +}; +int b::y = 0; + +struct a : public b { + BOOST_CONTRACT_STATIC_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::static_inv" << std::endl; + }) + + BOOST_CONTRACT_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::inv" << std::endl; + }) + + virtual ~a() { + BOOST_CONTRACT_OLD_PTR( + boost::contract::test::detail::unprotected_commas<int, void, void>:: + type1 + )( + old_x, + (boost::contract::test::detail::unprotected_commas<void, void, + void>::same(x)) + ); + BOOST_CONTRACT_DESTRUCTOR(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::dtor::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::dtor::post" << std::endl; + }) + ; + out << "a::dtor::body" << std::endl; + } + + static int x; +}; +int a::x = 0; + +int main() { + std::ostringstream ok; + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/pre_error.cpp b/src/boost/libs/contract/test/destructor/pre_error.cpp new file mode 100644 index 00000000..49b49e79 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/pre_error.cpp @@ -0,0 +1,24 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test destructor cannot use `.precondition(...)`. + +#include <boost/contract/destructor.hpp> +#include <boost/contract/check.hpp> + +struct a { + ~a() { + boost::contract::check c = boost::contract::destructor(this) + .precondition([] {}) // Error (no dtor func arg so never pre). + ; + } +}; + +int main() { + a aa; + return 0; +} + diff --git a/src/boost/libs/contract/test/destructor/smoke.cpp b/src/boost/libs/contract/test/destructor/smoke.cpp new file mode 100644 index 00000000..d1a9e18a --- /dev/null +++ b/src/boost/libs/contract/test/destructor/smoke.cpp @@ -0,0 +1,306 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test destructor subcontracting. + +#include "../detail/oteststream.hpp" +#include "../detail/counter.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +template<char Id> +struct t { + static void static_invariant() { + out << Id << "::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(l.value >= 0); + } + + void invariant() const { + out << Id << "::inv" << std::endl; + BOOST_CONTRACT_ASSERT(k_ < 0); + } + + struct l_tag; + typedef boost::contract::test::detail::counter<l_tag, int> l_type; + static l_type l; + + explicit t() : k_(-1) { ++l.value; } + + virtual ~t() { + boost::contract::old_ptr<l_type> old_l; + boost::contract::check c = boost::contract::destructor(this) + .old([&] { + out << Id << "::dtor::old" << std::endl; + old_l = BOOST_CONTRACT_OLDOF(l_type::eval(l)); + }) + .postcondition([&old_l] { + out << Id << "::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(t<Id>::l.value == old_l->value - 1); + }) + ; + out << Id << "::dtor::body" << std::endl; + --l.value; + } + +private: + int k_; +}; +template<char Id> typename t<Id>::l_type t<Id>::l; + +// Test deep inheritance (2 vertical levels), multiple inheritance (4 +// horizontal levels), and that all public/protected/private part of +// subcontracting for destructors (not just public, because all access levels +// are part of C++ object destruction mechanism). +struct c + #define BASES public t<'d'>, protected t<'p'>, private t<'q'>, public t<'e'> + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { + out << "c::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(m.value >= 0); + } + + void invariant() const { + out << "c::inv" << std::endl; + BOOST_CONTRACT_ASSERT(j_ < 0); + } + + struct m_tag; + typedef boost::contract::test::detail::counter<m_tag, int> m_type; + static m_type m; + + explicit c() : j_(-1) { ++m.value; } + + virtual ~c() { + boost::contract::old_ptr<m_type> old_m = + BOOST_CONTRACT_OLDOF(m_type::eval(m)); + boost::contract::check c = boost::contract::destructor(this) + .old([] { + out << "c::dtor::old" << std::endl; + // Test old-of assignment above instead. + }) + .postcondition([&old_m] { + out << "c::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(c::m.value == old_m->value - 1); + }) + ; + out << "c::dtor::body" << std::endl; + --m.value; + } + +private: + int j_; +}; +c::m_type c::m; + +// Test not (fully) contracted base is not part of destructor subcontracting. +struct b { + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + explicit b() {} + virtual ~b() {} // No contract. +}; + +struct a_n_tag; // Global decl so visible in MSVC10 lambdas. +typedef boost::contract::test::detail::counter<a_n_tag, int> a_n_type; + +// Test destructor with both non-contracted and contracted bases. +struct a + #define BASES public b, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { + out << "a::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(n.value >= 0); + } + + void invariant() const { + out << "a::inv" << std::endl; + BOOST_CONTRACT_ASSERT(i_ < 0); + } + + static a_n_type n; + + explicit a() : i_(-1) { + ++i_; --i_; // To avoid a warning when all contracts off. + ++n.value; + } + + virtual ~a() { + boost::contract::old_ptr<a_n_type> old_n; + boost::contract::check c = boost::contract::destructor(this) + .old([&] { + out << "a::dtor::old" << std::endl; + old_n = BOOST_CONTRACT_OLDOF(a_n_type::eval(n)); + }) + .postcondition([&old_n] { + out << "a::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(a::n.value == old_n->value - 1); + }) + ; + out << "a::dtor::body" << std::endl; + --n.value; + } + +private: + int i_; +}; +a_n_type a::n; + +int main() { + std::ostringstream ok; + + { + a aa; + out.str(""); + } // Call aa's destructor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + // Test static inv, but not const inv, checked after destructor body. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "e::static_inv" << std::endl + << "e::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "e::dtor::old" << std::endl + #endif + << "e::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "e::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "e::dtor::post" << std::endl + #endif + + // Test check also private bases (because part of C++ destruction). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "q::static_inv" << std::endl + << "q::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "q::dtor::old" << std::endl + #endif + << "q::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "q::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "q::dtor::post" << std::endl + #endif + + // Test check also protected bases (because part of C++ destruction). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "p::static_inv" << std::endl + << "p::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "p::dtor::old" << std::endl + #endif + << "p::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "p::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "p::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::dtor::old" << std::endl + #endif + << "d::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #ifndef BOOST_CONTRACT_NO_OLDS + #define BOOST_CONTRACT_TEST_old 1u + #else + #define BOOST_CONTRACT_TEST_old 0u + #endif + + // Followings destroy only copies (actual objects are static data members). + + BOOST_TEST_EQ(a_n_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a_n_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a_n_type::copies(), a_n_type::dtors()); // No leak. + + BOOST_TEST_EQ(c::m_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::m_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::m_type::copies(), c::m_type::dtors()); // No leak. + + BOOST_TEST_EQ(t<'d'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'d'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'d'>::l_type::copies(), t<'d'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'p'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'p'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'p'>::l_type::copies(), t<'p'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'q'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'q'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'q'>::l_type::copies(), t<'q'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'e'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::copies(), t<'e'>::l_type::dtors()); // No leak + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/throwing_body.cpp b/src/boost/libs/contract/test/destructor/throwing_body.cpp new file mode 100644 index 00000000..f14612ed --- /dev/null +++ b/src/boost/libs/contract/test/destructor/throwing_body.cpp @@ -0,0 +1,144 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test throw from destructor body (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "c::dtor::old" << std::endl; }) + .postcondition([] { out << "c::dtor::post" << std::endl; }) + .except([] { out << "c::dtor::except" << std::endl; }) + ; + out << "c::dtor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + .except([] { out << "b::dtor::except" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + throw b_err(); // Test body throw (from inheritance mid branch). + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + .except([] { out << "a::dtor::except" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + try { + { + a aa; + out.str(""); + } + BOOST_TEST(false); + } catch(b_err const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + // Test a destructed (so only static_inv and post, but no inv). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl // Test this threw. + // Test b not destructed (so static_inv, inv, and except, no post). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "b::dtor::except" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + // Test c not destructed (so static_inv, inv, and except, no post). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "c::dtor::except" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/throwing_old.cpp b/src/boost/libs/contract/test/destructor/throwing_old.cpp new file mode 100644 index 00000000..cdfc13bc --- /dev/null +++ b/src/boost/libs/contract/test/destructor/throwing_old.cpp @@ -0,0 +1,150 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test throw from destructor .old() (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "c::dtor::old" << std::endl; }) + .postcondition([] { out << "c::dtor::post" << std::endl; }) + .except([] { out << "c::dtor::except" << std::endl; }) + ; + out << "c::dtor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { + out << "b::dtor::old" << std::endl; + throw b_err(); // Test this throws (from mid branch). + }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + .except([] { out << "b::dtor::except" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + .except([] { out << "a::dtor::except" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_old_failure([] (boost::contract::from) { throw; }); + + try { + { + a aa; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(false); + } catch(b_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + // Test a destructed (so only static_inv and post, but no inv). + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl // Test this threw. + #else + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + // Test c not destructed (so both inv and except). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "c::dtor::except" << std::endl + #endif + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/throwing_post.cpp b/src/boost/libs/contract/test/destructor/throwing_post.cpp new file mode 100644 index 00000000..83186493 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/throwing_post.cpp @@ -0,0 +1,153 @@ + +// Copyright (C) 2008-2018 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). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test throw from destructor .post() (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "c::dtor::old" << std::endl; }) + .postcondition([] { out << "c::dtor::post" << std::endl; }) + .except([] { out << "c::dtor::except" << std::endl; }) + ; + out << "c::dtor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { + out << "b::dtor::post" << std::endl; + throw b_err(); // Test this throws (from mid branch). + }) + .except([] { out << "b::dtor::except" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + .except([] { out << "a::dtor::except" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw; }); + + try { + { + a aa; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(b_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + // Test a destructed (so only static_inv and post, but no inv). + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl // Test this threw. + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // Test c not destructed (so both inv and except). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "c::dtor::except" << std::endl + #endif + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + |