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/public_function | |
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/public_function')
68 files changed, 8459 insertions, 0 deletions
diff --git a/src/boost/libs/contract/test/public_function/access.cpp b/src/boost/libs/contract/test/public_function/access.cpp new file mode 100644 index 00000000..5e616773 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/access.cpp @@ -0,0 +1,136 @@ + +// 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/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.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 void f(char ch, boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([&] { + out << "b::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'b'); + }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + ; + out << "b::f::body" << std::endl; + } +}; + +class a + #define BASES public b + : BASES +{ + friend class boost::contract::access; + + // Private base types. + 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; } + + // Private override (always possible even when access is not friend). + BOOST_CONTRACT_OVERRIDE(f) + +public: + virtual void f(char ch, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this, ch) + .precondition([&] { + out << "a::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'a'); + }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + a aa; + out.str(""); + aa.f('a'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::old" << std::endl + << "b::f::post" << std::endl + // No old call here because not a base object. + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + b bb; + out.str(""); + bb.f('b'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + #endif + << "b::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl.hpp b/src/boost/libs/contract/test/public_function/decl.hpp new file mode 100644 index 00000000..9927587f --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl.hpp @@ -0,0 +1,162 @@ + +#ifndef BOOST_CONTRACT_TEST_PUBLIC_FUNCTION_DECL_HPP_ +#define BOOST_CONTRACT_TEST_PUBLIC_FUNCTION_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/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.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_entering_inv = true, c_entry_inv = true, c_exit_inv = true; +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; + if(c_entering_inv) BOOST_CONTRACT_ASSERT(c_entry_inv); + else BOOST_CONTRACT_ASSERT(c_exit_inv); + c_entering_inv = false; + } + #endif + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + #ifndef BOOST_CONTRACT_TEST_NO_C_PRE + .precondition([] { + out << "c::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(c_pre); + }) + #endif + .old([] { out << "c::f::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_C_POST + .postcondition([] { + out << "c::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(c_post); + }) + #endif + ; + out << "c::f::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_entering_inv = true, b_entry_inv = true, b_exit_inv = true; +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; + if(b_entering_inv) BOOST_CONTRACT_ASSERT(b_entry_inv); + else BOOST_CONTRACT_ASSERT(b_exit_inv); + b_entering_inv = false; + } + #endif + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + #ifndef BOOST_CONTRACT_TEST_NO_B_PRE + .precondition([] { + out << "b::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(b_pre); + }) + #endif + .old([] { out << "b::f::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_B_POST + .postcondition([] { + out << "b::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(b_post); + }) + #endif + ; + out << "a::f::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_entering_inv = true, a_entry_inv = true, a_exit_inv = true; +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; + if(a_entering_inv) BOOST_CONTRACT_ASSERT(a_entry_inv); + else BOOST_CONTRACT_ASSERT(a_exit_inv); + a_entering_inv = false; + } + #endif + + virtual void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this) + #ifndef BOOST_CONTRACT_TEST_NO_A_PRE + .precondition([] { + out << "a::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(a_pre); + }) + #endif + .old([] { out << "a::f::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_A_POST + .postcondition([] { + out << "a::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(a_post); + }) + #endif + ; + out << "a::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_inv_all.cpp b/src/boost/libs/contract/test/public_function/decl_entry_inv_all.cpp new file mode 100644 index 00000000..14f01913 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_inv_all.cpp @@ -0,0 +1,185 @@ + +// 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 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed (as all did). + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_inv_ends.cpp b/src/boost/libs/contract/test/public_function/decl_entry_inv_ends.cpp new file mode 100644 index 00000000..21883ee0 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_inv_ends.cpp @@ -0,0 +1,179 @@ + +// 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed (as all did). + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_inv_mid.cpp b/src/boost/libs/contract/test/public_function/decl_entry_inv_mid.cpp new file mode 100644 index 00000000..1dd68516 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_inv_mid.cpp @@ -0,0 +1,172 @@ + +// 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl // Test this fail. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl // Test this failed (as all did). + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_inv_none.cpp b/src/boost/libs/contract/test/public_function/decl_entry_inv_none.cpp new file mode 100644 index 00000000..e89b09a8 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_inv_none.cpp @@ -0,0 +1,105 @@ + +// 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; + ok.str(""); ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::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 aa; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_static_inv_all.cpp b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_all.cpp new file mode 100644 index 00000000..aad1a91d --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_all.cpp @@ -0,0 +1,183 @@ + +// 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_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + 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); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + // Test this failed (as all did). + << "c::static_inv" << std::endl + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_static_inv_ends.cpp b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_ends.cpp new file mode 100644 index 00000000..ade705ce --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_ends.cpp @@ -0,0 +1,198 @@ + +// 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_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + 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); + out.str(""); + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + 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 =true; + out.str(""); + try { + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // Test this failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + // Test this failed (as all did). + << "c::static_inv" << std::endl + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_static_inv_mid.cpp b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_mid.cpp new file mode 100644 index 00000000..d7cb7e9c --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_mid.cpp @@ -0,0 +1,169 @@ + +// 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_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + 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); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + 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 =true; + out.str(""); + try { + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl // Test this fail. + #else + << ok_end() + #endif + ; + 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 =true; + out.str(""); + try { + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + // Test this failed (as all did). + << "b::static_inv" << std::endl + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_entry_static_inv_none.cpp b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_none.cpp new file mode 100644 index 00000000..87a97d60 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_entry_static_inv_none.cpp @@ -0,0 +1,104 @@ + +// 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 + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::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 aa; + + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_inv_all.cpp b/src/boost/libs/contract/test/public_function/decl_exit_inv_all.cpp new file mode 100644 index 00000000..ffbe647d --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_inv_all.cpp @@ -0,0 +1,196 @@ + +// 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 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + a_exit_inv = false; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = false; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = false; + b_exit_inv = false; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed (as all did). + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_inv_ends.cpp b/src/boost/libs/contract/test/public_function/decl_exit_inv_ends.cpp new file mode 100644 index 00000000..b5fd8d1e --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_inv_ends.cpp @@ -0,0 +1,189 @@ + +// 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 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + a_exit_inv = false; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = false; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = false; + b_exit_inv = false; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // Test this failed (as all did). + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_inv_mid.cpp b/src/boost/libs/contract/test/public_function/decl_exit_inv_mid.cpp new file mode 100644 index 00000000..c07b299a --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_inv_mid.cpp @@ -0,0 +1,187 @@ + +// 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 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + a_exit_inv = false; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + // Test no failure here. + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = false; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = false; + b_exit_inv = false; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl // Test this failed (as all did). + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_inv_none.cpp b/src/boost/libs/contract/test/public_function/decl_exit_inv_none.cpp new file mode 100644 index 00000000..5f7aa61c --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_inv_none.cpp @@ -0,0 +1,110 @@ + +// 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 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/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + ok.str(""); ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + // No invariants. + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "b::static_inv" << std::endl + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + a aa; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_exit_inv = false; + b_exit_inv = true; + c_exit_inv = true; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_exit_inv = true; + b_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_exit_inv = false; + b_exit_inv = false; + c_exit_inv = false; + a_entering_inv = b_entering_inv = c_entering_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_static_inv_all.cpp b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_all.cpp new file mode 100644 index 00000000..5547b2f3 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_all.cpp @@ -0,0 +1,195 @@ + +// 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_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + 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); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + // Test this failed (as all did). + << "c::static_inv" << std::endl + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_static_inv_ends.cpp b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_ends.cpp new file mode 100644 index 00000000..3853e346 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_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 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_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + 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); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + // Test no failure here. + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + // Test this failed (as all did). + << "c::static_inv" << std::endl + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_static_inv_mid.cpp b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_mid.cpp new file mode 100644 index 00000000..c723ddf7 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_mid.cpp @@ -0,0 +1,190 @@ + +// 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_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #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 aa; + + 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); + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + 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); + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + // Test no failure here. + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "b::static_inv" << std::endl // Test this failed. + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + 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); + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + // Test no failure here. + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + 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); + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + // Test this failed (as all did). + << "b::static_inv" << std::endl + #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_exit_static_inv_none.cpp b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_none.cpp new file mode 100644 index 00000000..65c78ca7 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_exit_static_inv_none.cpp @@ -0,0 +1,110 @@ + +// 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> + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + // No static invariants. + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + + boost::contract::set_exit_invariant_failure( + [] (boost::contract::from) { throw err(); }); + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a aa; + + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + 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); + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_post_all.cpp b/src/boost/libs/contract/test/public_function/decl_post_all.cpp new file mode 100644 index 00000000..18c52873 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_post_all.cpp @@ -0,0 +1,163 @@ + +// 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_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a aa; + + a_post = true; + b_post = true; + c_post = true; + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_post = false; + b_post = true; + c_post = true; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl // Test this failed. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl // Test this failed. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl // Test this failed. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl // Test this failed (as all did). + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_post_ends.cpp b/src/boost/libs/contract/test/public_function/decl_post_ends.cpp new file mode 100644 index 00000000..6785aa8a --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_post_ends.cpp @@ -0,0 +1,158 @@ + +// 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_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a aa; + + a_post = true; + b_post = true; + c_post = true; + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_post = false; + b_post = true; + c_post = true; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "a::f::post" << std::endl // Test this failed. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + // Test no failure here. + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl // Test this failed. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl // Test this failed (as all did). + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_post_mid.cpp b/src/boost/libs/contract/test/public_function/decl_post_mid.cpp new file mode 100644 index 00000000..eaa71b16 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_post_mid.cpp @@ -0,0 +1,154 @@ + +// 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_begin() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a aa; + + a_post = true; + b_post = true; + c_post = true; + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_post = false; + b_post = true; + c_post = true; + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + // Test no failure here. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl // Test this failed. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + out.str(""); + try { + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + // Test no failure here. + << "b::f::old" << std::endl + << "b::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl // Test this failed (as all did). + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_post_none.cpp b/src/boost/libs/contract/test/public_function/decl_post_none.cpp new file mode 100644 index 00000000..26a42494 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_post_none.cpp @@ -0,0 +1,90 @@ + +// 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 + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // No postconditions. + << "c::f::old" << std::endl + << "b::f::old" << std::endl + #endif + ; + + a aa; + + a_post = true; + b_post = true; + c_post = true; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_post = false; + b_post = true; + c_post = true; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_post = true; + b_post = false; + c_post = true; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_post = true; + b_post = true; + c_post = false; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_post = false; + b_post = false; + c_post = false; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_pre_all.cpp b/src/boost/libs/contract/test/public_function/decl_pre_all.cpp new file mode 100644 index 00000000..fb8600fb --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_pre_all.cpp @@ -0,0 +1,154 @@ + +// 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 preconditions. + +#undef BOOST_CONTRACT_TEST_NO_A_PRE +#undef BOOST_CONTRACT_TEST_NO_B_PRE +#undef BOOST_CONTRACT_TEST_NO_C_PRE +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_begin() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl // Old only if post (or except) run. + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a aa; + + a_pre = true; + b_pre = true; + c_pre = true; + out.str(""); + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl // Test only c::f::pre checked. + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + a_pre = true; + b_pre = false; + c_pre = false; + out.str(""); + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + << "a::f::pre" << std::endl // Test all pre checked. + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + a_pre = false; + b_pre = true; + c_pre = false; + out.str(""); + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + // Test only a::f::pre not checked. + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + a_pre = false; + b_pre = false; + c_pre = true; + out.str(""); + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl // Test only c::f::pre checked. + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_pre = false; + b_pre = false; + c_pre = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + << "a::f::pre" << std::endl // Test all pre checked and failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_pre_ends.cpp b/src/boost/libs/contract/test/public_function/decl_pre_ends.cpp new file mode 100644 index 00000000..dc6b1958 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_pre_ends.cpp @@ -0,0 +1,159 @@ + +// 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 preconditions. + +#undef BOOST_CONTRACT_TEST_NO_A_PRE +#define BOOST_CONTRACT_TEST_NO_B_PRE +#undef BOOST_CONTRACT_TEST_NO_C_PRE +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_begin() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl // Old only if post (or except) run. + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a aa; + + a_pre = true; + b_pre = true; + c_pre = true; + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl // Test only c pre checked. + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + a_pre = true; + b_pre = false; + c_pre = false; + out.str(""); + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + // Test b's pre not checked. + << "a::f::pre" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + a_pre = false; + b_pre = false; + c_pre = true; + out.str(""); + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl // Test only c pre checked. + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_pre = false; + b_pre = true; + c_pre = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "a::f::pre" << std::endl // Only ends pre checked and failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = false; + b_pre = false; + c_pre = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "a::f::pre" << std::endl // Only ends pre checked and failed. + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_pre_mid.cpp b/src/boost/libs/contract/test/public_function/decl_pre_mid.cpp new file mode 100644 index 00000000..f0939ca8 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_pre_mid.cpp @@ -0,0 +1,166 @@ + +// 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 preconditions. + +#define BOOST_CONTRACT_TEST_NO_A_PRE +#undef BOOST_CONTRACT_TEST_NO_B_PRE +#define BOOST_CONTRACT_TEST_NO_C_PRE +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_begin() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl // Old only if post (or except) run. + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a aa; + + a_pre = true; + b_pre = true; + c_pre = true; + out.str(""); + aa.f(); + ok.str(""); ok // Test nothing failed. + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + a_pre = false; + b_pre = true; + c_pre = false; + out.str(""); + aa.f(); + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + // Test only middle pre checked and no fail. + << "b::f::pre" << std::endl + #endif + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_pre = true; + b_pre = false; + c_pre = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + // Test only middle pre checked and failed. + << "b::f::pre" << std::endl + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = false; + b_pre = false; + c_pre = true; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + // Test only middle pre checked and failed. + << "b::f::pre" << std::endl + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = false; + b_pre = false; + c_pre = false; + out.str(""); + try { + aa.f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_begin() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + // Test only middle pre checked and failed. + << "b::f::pre" << std::endl + #else + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/decl_pre_none.cpp b/src/boost/libs/contract/test/public_function/decl_pre_none.cpp new file mode 100644 index 00000000..71ace3e4 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/decl_pre_none.cpp @@ -0,0 +1,90 @@ + +// 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 preconditions. + +#define BOOST_CONTRACT_TEST_NO_A_PRE +#define BOOST_CONTRACT_TEST_NO_B_PRE +#define BOOST_CONTRACT_TEST_NO_C_PRE +#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 + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + // No preconditions here. + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl // Old only if post (or except) run. + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + + a aa; + + a_pre = true; + b_pre = true; + c_pre = true; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_pre = true; + b_pre = false; + c_pre = false; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_pre = false; + b_pre = true; + c_pre = false; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_pre = false; + b_pre = false; + c_pre = true; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + a_pre = false; + b_pre = false; + c_pre = false; + out.str(""); + aa.f(); + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/friend.cpp b/src/boost/libs/contract/test/public_function/friend.cpp new file mode 100644 index 00000000..d5fc6359 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/friend.cpp @@ -0,0 +1,107 @@ + +// 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 friend functions (also forcing them to check invariants). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +class y; +class z; + +class x { +public: + void invariant() const { + out << "x::inv" << std::endl; + BOOST_CONTRACT_ASSERT(get() >= 0); + } + + x() : value_(0) {} + int get() const { return value_; } + + friend void f(x&, y&, int value); + +private: + int value_; +}; + +class y { +public: + void invariant() const { + out << "y::inv" << std::endl; + BOOST_CONTRACT_ASSERT(get() >= 0); + } + + y() : value_(0) {} + int get() const { return value_; } + + friend void f(x&, y&, int value); + +private: + int value_; +}; + +void f(x& a, y& b, int value) { + boost::contract::check post = boost::contract::function() + .postcondition([&] { + out << "f::post" << std::endl; + BOOST_CONTRACT_ASSERT(a.get() == value); + BOOST_CONTRACT_ASSERT(b.get() == value); + }) + ; + boost::contract::check inv_b = boost::contract::public_function(&b); + boost::contract::check inv_a = boost::contract::public_function(&a); + boost::contract::check pre = boost::contract::function() + .precondition([&] { + out << "f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(value > 0); + }) + ; + + out << "f::body" << std::endl; + a.value_ = b.value_ = value; +} + +int main() { + std::ostringstream ok; + + x a; + y b; + + out.str(""); + f(a, b, 123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "y::inv" << std::endl + << "x::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "x::inv" << std::endl + << "y::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + BOOST_TEST_EQ(a.get(), 123); + BOOST_TEST_EQ(b.get(), 123); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/ifdef.cpp b/src/boost/libs/contract/test/public_function/ifdef.cpp new file mode 100644 index 00000000..2ab7d3ac --- /dev/null +++ b/src/boost/libs/contract/test/public_function/ifdef.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 contract compilation on/off. + +#include "../detail/oteststream.hpp" +#include <boost/contract/core/config.hpp> +#include <boost/contract/core/virtual.hpp> +#ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + #include <boost/contract/public_function.hpp> + #include <boost/contract/base_types.hpp> + #include <boost/contract/override.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 void f(int x, boost::contract::virtual_* v = 0) = 0; +}; + +void b::f(int x, boost::contract::virtual_* v) { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(v, x); + #endif + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + boost::contract::check c = boost::contract::public_function(v, this) + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + .precondition([] { out << "b::f::pre" << std::endl; }) + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + #endif + ; + #endif + out << "b::f::body" << std::endl; +} + +struct a + #define BASES public b + : BASES +{ + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + BOOST_CONTRACT_OVERRIDE(f) + #endif + + #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 void f(int x, boost::contract::virtual_* v = 0) { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(v, x); + #endif + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + boost::contract::check c = boost::contract::public_function< + override_f>(v, &a::f, this, x) + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + .precondition([] { out << "a::f::pre" << std::endl; }) + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + #endif + ; + #endif + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + a aa; + out.str(""); + aa.f(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/ifdef_macro.cpp b/src/boost/libs/contract/test/public_function/ifdef_macro.cpp new file mode 100644 index 00000000..ab552de7 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/ifdef_macro.cpp @@ -0,0 +1,171 @@ + +// 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/core/virtual.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 void f(int x, boost::contract::virtual_* v = 0) = 0; +}; + +void b::f(int x, boost::contract::virtual_* v) { + BOOST_CONTRACT_OLD_PTR( + boost::contract::test::detail::unprotected_commas<int, void, void>:: + type1 + )( + (boost::contract::test::detail::unprotected_commas<void, void, void>:: + same(v)), + old_x, + (boost::contract::test::detail::unprotected_commas<void, void, void>:: + same(x)) + ); + BOOST_CONTRACT_PUBLIC_FUNCTION( + boost::contract::test::detail::unprotected_commas<void, void, void>:: + same(v), + boost::contract::test::detail::unprotected_commas<void, void, void>:: + same(this) + ) + BOOST_CONTRACT_PRECONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "b::f::pre" << std::endl; + }) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "b::f::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "b::f::post" << std::endl; + }) + ; + out << "b::f::body" << std::endl; +} + +struct a + #define BASES public boost::contract::test::detail::unprotected_commas< \ + b, void, void>::type1 + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + BOOST_CONTRACT_OVERRIDE(f) + + 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 void f(int x, boost::contract::virtual_* v = 0) { + BOOST_CONTRACT_OLD_PTR( + boost::contract::test::detail::unprotected_commas<int, void, void>:: + type1 + )( + (boost::contract::test::detail::unprotected_commas<void, void, + void>::same(v)), + old_x, + (boost::contract::test::detail::unprotected_commas<void, void, + void>::same(x)) + ); + BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE( + boost::contract::test::detail::unprotected_commas<override_f, void, + void>::type1 + )( + boost::contract::test::detail::unprotected_commas<void, void, void> + ::same(v), + &a::f, + boost::contract::test::detail::unprotected_commas<void, void, void> + ::same(this), + boost::contract::test::detail::unprotected_commas<void, void, void> + ::same(x) + ) + BOOST_CONTRACT_PRECONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::f::pre" << std::endl; + }) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::f::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::f::post" << std::endl; + }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + a aa; + out.str(""); + aa.f(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::old" << std::endl // Called by post (so under NO_POST). + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/max_args.cpp b/src/boost/libs/contract/test/public_function/max_args.cpp new file mode 100644 index 00000000..d01e8281 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args.cpp @@ -0,0 +1,10 @@ + +// 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 default max argument number (leave MAX_ARGS #undef). + +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_args.hpp b/src/boost/libs/contract/test/public_function/max_args.hpp new file mode 100644 index 00000000..210f730d --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args.hpp @@ -0,0 +1,209 @@ + +// 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 max argument number for public function (with and without result). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/preprocessor/repetition/repeat.hpp> +#include <boost/preprocessor/arithmetic/inc.hpp> +#include <boost/preprocessor/control/expr_iif.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/stringize.hpp> +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +#if defined(BOOST_GCC) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-parameter" // aN from macros. +#elif defined(BOOST_CLANG) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunused-parameter" // aN from macros. +#endif + +#define BOOST_CONTRACT_TEST_MAX_ARGS_PARAM_COMMA_(z, n, unused) \ + int BOOST_PP_CAT(a, n) , + +#define BOOST_CONTRACT_TEST_MAX_ARGS_COMMA_ARG_(z, n, unused) \ + , BOOST_PP_CAT(a, n) + +#define BOOST_CONTRACT_TEST_MAX_ARGS_N_(z, n, unused) \ + n + +struct b { + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + #define BOOST_CONTRACT_TEST_MAX_ARGS_B_F_(z, n, unused) \ + virtual int BOOST_PP_CAT(f, n)( \ + BOOST_PP_REPEAT_ ## z( \ + n, BOOST_CONTRACT_TEST_MAX_ARGS_PARAM_COMMA_, ~) \ + boost::contract::virtual_* v = 0 \ + ) { \ + int result = 0; \ + boost::contract::check c = boost::contract::public_function( \ + v, result, this) \ + .precondition([] { \ + out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::pre" << std::endl; \ + }) \ + .old([] { \ + out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::old" << std::endl; \ + }) \ + .postcondition([] (int result) { \ + out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::post" << std::endl; \ + }) \ + ; \ + out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::body" << std::endl; \ + return result; \ + } + + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), + BOOST_CONTRACT_TEST_MAX_ARGS_B_F_, ~) +}; + +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; } + + #define BOOST_CONTRACT_TEST_MAX_ARGS_A_F_(z, n, unused) \ + int BOOST_PP_CAT(f, n)( \ + BOOST_PP_REPEAT_ ## z( \ + n, BOOST_CONTRACT_TEST_MAX_ARGS_PARAM_COMMA_, ~) \ + boost::contract::virtual_* v = 0 \ + ) /* override */ { \ + int result = 0; \ + boost::contract::check c = boost::contract::public_function< \ + BOOST_PP_CAT(override_, BOOST_PP_CAT(f, n)) \ + >( \ + v, result, &a::BOOST_PP_CAT(f, n), this \ + BOOST_PP_REPEAT_ ## z( \ + n, BOOST_CONTRACT_TEST_MAX_ARGS_COMMA_ARG_, ~) \ + ) \ + .precondition([] { \ + out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::pre" << std::endl; \ + }) \ + .old([] { \ + out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::old" << std::endl; \ + }) \ + .postcondition([] (int result) { \ + out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::post" << std::endl; \ + }) \ + ; \ + out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::body" << std::endl; \ + return result; \ + } \ + BOOST_CONTRACT_OVERRIDE(BOOST_PP_CAT(f, n)) + + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), + BOOST_CONTRACT_TEST_MAX_ARGS_A_F_, ~) +}; + +#if defined(BOOST_GCC) + #pragma GCC diagnostic pop +#elif defined(BOOST_CLANG) + #pragma clang diagnostic pop +#endif + +int main() { + std::ostringstream ok; + a aa; + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 1 + #else + #define BOOST_CONTRACT_TEST_entry_inv 0 + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + #define BOOST_CONTRACT_TEST_pre 1 + #else + #define BOOST_CONTRACT_TEST_pre 0 + #endif + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #define BOOST_CONTRACT_TEST_exit_inv 1 + #else + #define BOOST_CONTRACT_TEST_exit_inv 0 + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + #define BOOST_CONTRACT_TEST_post 1 + #else + #define BOOST_CONTRACT_TEST_post 0 + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + #define BOOST_CONTRACT_TEST_old 1 + #else + #define BOOST_CONTRACT_TEST_old 0 + #endif + + #define BOOST_CONTRACT_TEST_MAX_ARGS_TEST_(z, n, unused) \ + out.str(""); \ + aa.BOOST_PP_CAT(f, n)(BOOST_PP_ENUM_ ## z( \ + n, BOOST_CONTRACT_TEST_MAX_ARGS_N_, ~)); \ + ok.str(""); ok \ + BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_entry_inv, \ + << "b::static_inv\n" \ + << "b::inv\n"\ + << "a::static_inv\n" \ + << "a::inv\n" \ + ) \ + BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_pre, \ + << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::pre\n" \ + ) \ + BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_old, \ + << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::old\n" \ + << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::old\n" \ + ) \ + << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << "::body\n" \ + BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_exit_inv, \ + << "b::static_inv\n" \ + << "b::inv\n"\ + << "a::static_inv\n" \ + << "a::inv\n" \ + ) \ + BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_post, \ + << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::old\n" \ + << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::post\n" \ + << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \ + "::post\n" \ + ) \ + ; \ + BOOST_TEST(out.eq(ok.str())); + + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), + BOOST_CONTRACT_TEST_MAX_ARGS_TEST_, ~) + + #undef BOOST_CONTRACT_TEST_entry_inv + #undef BOOST_CONTRACT_TEST_pre + #undef BOOST_CONTRACT_TEST_exit_inv + #undef BOOST_CONTRACT_TEST_post + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/max_args0.cpp b/src/boost/libs/contract/test/public_function/max_args0.cpp new file mode 100644 index 00000000..5f6a4062 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args0.cpp @@ -0,0 +1,13 @@ + +// 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 max argument number set to 0. + +#if !defined(BOOST_CONTRACT_MAX_ARGS) || BOOST_CONTRACT_MAX_ARGS != 0 + #error "build must define MAX_ARGS=0" +#endif +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_args0_no_tva.cpp b/src/boost/libs/contract/test/public_function/max_args0_no_tva.cpp new file mode 100644 index 00000000..c2b24b92 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args0_no_tva.cpp @@ -0,0 +1,16 @@ + +// 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 max argument number set to 0 and no variadic templates. + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES + #error "build must define BOOST_NO_CXX11_VARIADIC_TEMPLATES" +#endif +#if !defined(BOOST_CONTRACT_MAX_ARGS) || BOOST_CONTRACT_MAX_ARGS != 0 + #error "build must define MAX_ARGS=0" +#endif +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_args1.cpp b/src/boost/libs/contract/test/public_function/max_args1.cpp new file mode 100644 index 00000000..eea52026 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args1.cpp @@ -0,0 +1,13 @@ + +// 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 max argument number set to 1. + +#if !defined(BOOST_CONTRACT_MAX_ARGS) || BOOST_CONTRACT_MAX_ARGS != 1 + #error "build must define MAX_ARGS=1" +#endif +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_args1_no_tva.cpp b/src/boost/libs/contract/test/public_function/max_args1_no_tva.cpp new file mode 100644 index 00000000..303fc3ed --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args1_no_tva.cpp @@ -0,0 +1,16 @@ + +// 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 max argument number set to 1 and no variadic templates. + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES + #error "build must define BOOST_NO_CXX11_VARIADIC_TEMPLATES" +#endif +#if !defined(BOOST_CONTRACT_MAX_ARGS) || BOOST_CONTRACT_MAX_ARGS != 1 + #error "build must define MAX_ARGS=1" +#endif +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_args2.cpp b/src/boost/libs/contract/test/public_function/max_args2.cpp new file mode 100644 index 00000000..771fcc1c --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args2.cpp @@ -0,0 +1,13 @@ + +// 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 max argument number set to 2. + +#if !defined(BOOST_CONTRACT_MAX_ARGS) || BOOST_CONTRACT_MAX_ARGS != 2 + #error "build must define MAX_ARGS=2" +#endif +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_args2_no_tva.cpp b/src/boost/libs/contract/test/public_function/max_args2_no_tva.cpp new file mode 100644 index 00000000..4ddf0bce --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args2_no_tva.cpp @@ -0,0 +1,16 @@ + +// 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 max argument number set to 2 and no variadic templates. + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES + #error "build must define BOOST_NO_CXX11_VARIADIC_TEMPLATES" +#endif +#if !defined(BOOST_CONTRACT_MAX_ARGS) || BOOST_CONTRACT_MAX_ARGS != 2 + #error "build must define MAX_ARGS=2" +#endif +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_args_no_tva.cpp b/src/boost/libs/contract/test/public_function/max_args_no_tva.cpp new file mode 100644 index 00000000..e0e1c558 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_args_no_tva.cpp @@ -0,0 +1,13 @@ + +// 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 default max arg number (leave MAX_ARGS #undef) and no variadic tpl. + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES + #error "build must define BOOST_NO_CXX11_VARIADIC_TEMPLATES" +#endif +#include "max_args.hpp" + diff --git a/src/boost/libs/contract/test/public_function/max_bases.cpp b/src/boost/libs/contract/test/public_function/max_bases.cpp new file mode 100644 index 00000000..4d8d1a8a --- /dev/null +++ b/src/boost/libs/contract/test/public_function/max_bases.cpp @@ -0,0 +1,59 @@ + +// 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 max possible number of bases. + +#include <boost/contract/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/override.hpp> +#include <boost/preprocessor/repetition/repeat.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/cat.hpp> + +// Limited by max size of current impl of Boost.MPL vector. +#ifndef BOOST_CONTRACT_TEST_CONFIG_MAX_BASES + #define BOOST_CONTRACT_TEST_CONFIG_MAX_BASES 20 +#endif + +#define BOOST_CONTRACT_TEST_base_decl(z, n, unused) \ + struct BOOST_PP_CAT(b, n) { \ + virtual void f(boost::contract::virtual_* v = 0) { \ + boost::contract::check c = boost::contract::public_function( \ + v, this); \ + } \ + }; + +BOOST_PP_REPEAT(BOOST_CONTRACT_TEST_CONFIG_MAX_BASES, + BOOST_CONTRACT_TEST_base_decl, ~) + +#define BOOST_CONTRACT_TEST_public_base(z, n, unused) public BOOST_PP_CAT(b, n) + +struct a + #define BASES \ + BOOST_PP_ENUM(BOOST_CONTRACT_TEST_CONFIG_MAX_BASES, \ + BOOST_CONTRACT_TEST_public_base, ~) + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this); + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + a aa; + aa.f(); + return 0; +} + +#undef BOOST_CONTRACT_TEST_base_decl +#undef BOOST_CONTRACT_TEST_public_base + diff --git a/src/boost/libs/contract/test/public_function/old_virtual.cpp b/src/boost/libs/contract/test/public_function/old_virtual.cpp new file mode 100644 index 00000000..ed6dcebd --- /dev/null +++ b/src/boost/libs/contract/test/public_function/old_virtual.cpp @@ -0,0 +1,214 @@ + +// 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 old inits/ftors and of mixed types up inheritance tree. + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/override.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +boost::contract::test::detail::oteststream out; + +struct num { + static num make(int i) { // Test no ctor (not even explicit) but for copy. + num n; + n.value(i); + return n; + } + + num(num const& other) : value_(other.value_) {} + + void value(int i) { value_ = boost::lexical_cast<std::string>(i); } + int value() const { return boost::lexical_cast<int>(value_); } + + num operator+(int left) { + num n; + n.value(value() + left); + return n; + } + +private: + num() {} // Test no visible default ctor (only copy ctor). + num& operator=(num const&); // Test no copy operator (only copy ctor). + + std::string value_; // Test this size-of != from other old type `int` below. +}; + +struct c { + virtual void f(int& i, num& n, boost::contract::virtual_* v = 0) { + boost::contract::old_ptr<int> old_a = BOOST_CONTRACT_OLDOF(v, i + 1); + boost::contract::old_ptr<num> old_b = BOOST_CONTRACT_OLDOF(v, n + 2); + boost::contract::old_ptr<int> old_x; + boost::contract::old_ptr<num> old_y; + boost::contract::check c = boost::contract::public_function(v, this) + .old([&] { + out << "c::f::old" << std::endl; + old_x = BOOST_CONTRACT_OLDOF(v, i + 3); + old_y = BOOST_CONTRACT_OLDOF(v, n + 4); + }) + .postcondition([&] { + out << "c::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(*old_a == n.value() + 1); + BOOST_CONTRACT_ASSERT(old_b->value() == i + 2); + BOOST_CONTRACT_ASSERT(*old_x == n.value() + 3); + BOOST_CONTRACT_ASSERT(old_y->value() == i + 4); + }) + ; + out << "c::f::body" << std::endl; + int tmp = i; + i = n.value(); + n.value(tmp); + } +}; + +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + virtual void f(int& i, num& n, boost::contract::virtual_* v = 0) + /* override */ { + boost::contract::old_ptr<int> old_a = BOOST_CONTRACT_OLDOF(v, i + 1); + boost::contract::old_ptr<num> old_b = BOOST_CONTRACT_OLDOF(v, n + 2); + boost::contract::old_ptr<int> old_x; + boost::contract::old_ptr<num> old_y; + boost::contract::check c = boost::contract::public_function< + override_f>(v, &c::f, this, i, n) + .old([&] { + out << "b::f::old" << std::endl; + old_x = BOOST_CONTRACT_OLDOF(v, i + 3); + old_y = BOOST_CONTRACT_OLDOF(v, n + 4); + }) + .postcondition([&] { + out << "b::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(*old_a == n.value() + 1); + BOOST_CONTRACT_ASSERT(old_b->value() == i + 2); + BOOST_CONTRACT_ASSERT(*old_x == n.value() + 3); + BOOST_CONTRACT_ASSERT(old_y->value() == i + 4); + }) + ; + out << "b::f::body" << std::endl; + int tmp = i; + i = n.value(); + n.value(tmp); + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + virtual void f(int& i, num& n, boost::contract::virtual_* v = 0) + /* override */ { + boost::contract::old_ptr<int> old_a = BOOST_CONTRACT_OLDOF(v, i + 1); + boost::contract::old_ptr<num> old_b = BOOST_CONTRACT_OLDOF(v, n + 2); + boost::contract::old_ptr<int> old_x; + boost::contract::old_ptr<num> old_y; + boost::contract::check c = boost::contract::public_function< + override_f>(v, &c::f, this, i, n) + .old([&] { + out << "a::f::old" << std::endl; + old_x = BOOST_CONTRACT_OLDOF(v, i + 3); + old_y = BOOST_CONTRACT_OLDOF(v, n + 4); + }) + .postcondition([&] { + out << "a::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(*old_a == n.value() + 1); + BOOST_CONTRACT_ASSERT(old_b->value() == i + 2); + BOOST_CONTRACT_ASSERT(*old_x == n.value() + 3); + BOOST_CONTRACT_ASSERT(old_y->value() == i + 4); + }) + ; + out << "a::f::body" << std::endl; + int tmp = i; + i = n.value(); + n.value(tmp); + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + std::ostringstream ok; + int i = 0; + num n = num::make(0); + + i = 123; + n.value(-123); + a aa; // Test virtual call with 2 bases. + out.str(""); + aa.f(i, n); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + // No old call here because not a base object. + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + i = 456; + n.value(-456); + b bb; // Test virtual call with 1 base. + out.str(""); + bb.f(i, n); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + #endif + << "b::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + // No old call here because not a base object. + << "b::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + i = 789; + n.value(-789); + c cc; // Test virtual call with no bases. + out.str(""); + cc.f(i, n); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + #endif + << "c::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // No old call here because not a base object. + << "c::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/overload.cpp b/src/boost/libs/contract/test/public_function/overload.cpp new file mode 100644 index 00000000..64101d26 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/overload.cpp @@ -0,0 +1,10 @@ + +// 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 public function overloads (with variadic templates if supported). + +#include "overload.hpp" + diff --git a/src/boost/libs/contract/test/public_function/overload.hpp b/src/boost/libs/contract/test/public_function/overload.hpp new file mode 100644 index 00000000..46abdd56 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/overload.hpp @@ -0,0 +1,343 @@ + +// 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 public function overloads. + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +boost::contract::test::detail::oteststream out; + +struct b { + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + virtual void f(int /* x */, boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "b::f(int)::pre" << std::endl; }) + .old([] { out << "b::f(int)::old" << std::endl; }) + .postcondition([] { out << "b::f(int)::post" << std::endl; }) + ; + out << "b::f(int)::body" << std::endl; + } + + virtual void f(char const* /* x */, boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "b::f(char const*)::pre" << std::endl; }) + .old([] { out << "b::f(char const*)::old" << std::endl; }) + .postcondition( + [] { out << "b::f(char const*)::post" << std::endl; }) + ; + out << "b::f(char const*)::body" << std::endl; + } + + virtual void f(int /* x */, int /* y */, boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "b::f(int, int)::pre" << std::endl; }) + .old([] { out << "b::f(int, int)::old" << std::endl; }) + .postcondition([] { out << "b::f(int, int)::post" << std::endl; }) + ; + out << "b::f(int, int)::body" << std::endl; + } + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "b::f()::pre" << std::endl; }) + .old([] { out << "b::f()::old" << std::endl; }) + .postcondition([] { out << "b::f()::post" << std::endl; }) + ; + out << "b::f()::body" << std::endl; + } + + void f(int /* x */[2][3], boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "b::f(int[2][3])::pre" << std::endl; }) + .old([] { out << "b::f(int[2][3])::old" << std::endl; }) + .postcondition([] { out << "b::f(int[2][3])::post" << std::endl; }) + ; + out << "b::f(int[2][3])::body" << std::endl; + } + + void f(void (* /* x */)(int), boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition( + [] { out << "b::f(void (*)(int))::pre" << std::endl; }) + .old( + [] { out << "b::f(void (*)(int))::old" << std::endl; }) + .postcondition( + [] { out << "b::f(void (*)(int))::post" << std::endl; }) + ; + out << "b::f(void (*)(int))::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; } + + void f(int x, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, + static_cast<void (a::*)(int, boost::contract::virtual_*)>(&a::f), + this, x + ) + .precondition([] { out << "a::f(int)::pre" << std::endl; }) + .old([] { out << "a::f(int)::old" << std::endl; }) + .postcondition([] { out << "a::f(int)::post" << std::endl; }) + ; + out << "a::f(int)::body" << std::endl; + } + + // Test overload via argument type. + void f(char const* x, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, + static_cast<void (a::*)(char const*, boost::contract::virtual_*)>( + &a::f), + this, x + ) + .precondition([] { out << "a::f(char const*)::pre" << std::endl; }) + .old([] { out << "a::f(char const*)::old" << std::endl; }) + .postcondition( + [] { out << "a::f(char const*)::post" << std::endl; }) + ; + out << "a::f(char const*)::body" << std::endl; + } + + // Test overload via argument count. + void f(int x, int y, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, + static_cast<void (a::*)(int, int, boost::contract::virtual_*)>( + &a::f), + this, x, y + ) + .precondition([] { out << "a::f(int, int)::pre" << std::endl; }) + .old([] { out << "a::f(int, int)::old" << std::endl; }) + .postcondition([] { out << "a::f(int, int)::post" << std::endl; }) + ; + out << "a::f(int, int)::body" << std::endl; + } + + // Test overload via template argument type. + template<typename T> + void f(T /* x */) { // Template cannot be virtual (or override) in C++. + boost::contract::check c = boost::contract::public_function(this) + .precondition([] { out << "a::f(T)::pre" << std::endl; }) + .old([] { out << "a::f(T)::old" << std::endl; }) + .postcondition([] { out << "a::f(T)::post" << std::endl; }) + ; + out << "a::f(T)::body" << std::endl; + } + + // Test no overload ambiguity in public_function called by these two cases. + + // NOTE: In *all* other cases, public_function is always called with a + // different number of arguments so there cannot be ambiguity either + // (0 args for static, 1 arg for non-virtual, 2 or 3 args for virtual, + // >= 3 for override, so only in cases below of 3 args for virtual and 3 + // for override there could be ambiguity but there is not because of + // presence or absence of override_... template parameter). + + typedef void (a::* f0_ptr)(boost::contract::virtual_*); + + void f(boost::contract::virtual_* v = 0) /* override */ { + f0_ptr f0 = static_cast<f0_ptr>(&a::f); + // Test this and public_function call in func below both take same 3 + // args but they are ambiguous because of presence override_f. + boost::contract::check c = boost::contract::public_function<override_f>( + v, f0, this) + .precondition([] { out << "a::f()::pre" << std::endl; }) + .old([] { out << "a::f()::old" << std::endl; }) + .postcondition([] { out << "a::f()::post" << std::endl; }) + ; + out << "a::f()::body" << std::endl; + } + + virtual f0_ptr f(bool /* x */, boost::contract::virtual_* v = 0) + /* not an override */ { + f0_ptr f0 = static_cast<f0_ptr>(&a::f); + // Test this and public_function call in func above both take same 3 + // args but they are ambiguous because of lack of override_f. + boost::contract::check c = boost::contract::public_function( + v, f0, this) + .precondition([] { out << "a::f(bool)::pre" << std::endl; }) + .old([] { out << "a::f(bool)::old" << std::endl; }) + .postcondition([] (f0_ptr const&) { + out << "a::f(bool)::post" << std::endl; }) + ; + out << "a::f(bool)::body" << std::endl; + return f0; + } + + // Test overload with array parameter. + void f(int x[2][3], boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, + static_cast<void (a::*)(int[2][3], boost::contract::virtual_*)>( + &a::f), + this, x + ) + .precondition([] { out << "a::f(int[2][3])::pre" << std::endl; }) + .old([] { out << "a::f(int[2][3])::old" << std::endl; }) + .postcondition([] { out << "a::f(int[2][3])::post" << std::endl; }) + ; + out << "a::f(int[2][3])::body" << std::endl; + } + + // Test overload with function pointer parameter. + void f(void (*x)(int), boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, + static_cast<void (a::*)(void (*)(int), boost::contract::virtual_*)>( + &a::f), + this, x + ) + .precondition( + [] { out << "a::f(void (*)(int))::pre" << std::endl; }) + .old( + [] { out << "a::f(void (*)(int))::old" << std::endl; }) + .postcondition( + [] { out << "a::f(void (*)(int))::post" << std::endl; }) + ; + out << "a::f(void (*)(int))::body" << std::endl; + } + + BOOST_CONTRACT_OVERRIDE(f) +}; + +void g(int) {} + +std::string ok_args(std::string const& args) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f(" << args << ")::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f(" << args << ")::old" << std::endl + << "a::f(" << args << ")::old" << std::endl + #endif + << "a::f(" << args << ")::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f(" << args << ")::old" << std::endl + << "b::f(" << args << ")::post" << std::endl + << "a::f(" << args << ")::post" << std::endl + #endif + ; + return ok.str(); +} + +int main() { + std::ostringstream ok; + a aa; + + out.str(""); + aa.f(123); + ok.str(""); ok << ok_args("int"); + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.f("abc"); + ok.str(""); ok << ok_args("char const*"); + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.f(123, 456); + ok.str(""); ok << ok_args("int, int"); + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + struct {} zz; + aa.f(zz); // Call template (so no override because no virtual). + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f(T)::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f(T)::old" << std::endl + #endif + << "a::f(T)::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f(T)::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.f(); + ok.str(""); ok << ok_args(""); + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.f(true); // This does not override (public_function ambiguity testing). + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f(bool)::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f(bool)::old" << std::endl + #endif + << "a::f(bool)::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f(bool)::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + int i[2][3]; + aa.f(i); + ok.str(""); ok << ok_args("int[2][3]"); + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.f(&g); + ok.str(""); ok << ok_args("void (*)(int)"); + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/overload_no_tva.cpp b/src/boost/libs/contract/test/public_function/overload_no_tva.cpp new file mode 100644 index 00000000..328d4efe --- /dev/null +++ b/src/boost/libs/contract/test/public_function/overload_no_tva.cpp @@ -0,0 +1,13 @@ + +// 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 public function overloads (always without variadic templates). + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES + #error "build must define BOOST_NO_CXX11_VARIADIC_TEMPLATES" +#endif +#include "overload.hpp" + diff --git a/src/boost/libs/contract/test/public_function/override.hpp b/src/boost/libs/contract/test/public_function/override.hpp new file mode 100644 index 00000000..c25757a4 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/override.hpp @@ -0,0 +1,41 @@ + +// no #include guard + +// 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 error if override func does not actually override (unless PERMISSIVE). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> + +struct b { + virtual void g(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this); + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + virtual void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function< + override_f>(v, &a::f, this); + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/public_function/override_error.cpp b/src/boost/libs/contract/test/public_function/override_error.cpp new file mode 100644 index 00000000..1dd233ab --- /dev/null +++ b/src/boost/libs/contract/test/public_function/override_error.cpp @@ -0,0 +1,14 @@ + +// 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 error if override func does not actually override. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "override.hpp" +#ifdef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + #error "Forcing error even when public functions not checked" +#endif + diff --git a/src/boost/libs/contract/test/public_function/override_permissive.cpp b/src/boost/libs/contract/test/public_function/override_permissive.cpp new file mode 100644 index 00000000..e3a2be5b --- /dev/null +++ b/src/boost/libs/contract/test/public_function/override_permissive.cpp @@ -0,0 +1,13 @@ + +// 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 no error if permissive even when override f does not actually override. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "override.hpp" + diff --git a/src/boost/libs/contract/test/public_function/protected.cpp b/src/boost/libs/contract/test/public_function/protected.cpp new file mode 100644 index 00000000..8ec7e7d7 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/protected.cpp @@ -0,0 +1,88 @@ + +// 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 overriding function never overrides protected function contract. + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/public_function.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; + +struct b { + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + +protected: + // NOTE: This is the correct way of programming contracts for overridden + // protected and overriding public functions: Both must use virtual_ + // (otherwise C++ won't override because mismatching parameters), but + // overridden protected does not use public_function. + virtual void f(boost::contract::virtual_* /* v */ = 0) { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "b::f::pre" << std::endl; }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + ; + out << "b::f::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; } + + void f(boost::contract::virtual_* v = 0) /* not override */ { + // C++ func a::f overrides b::f, but contracts don't (so no override_f). + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + a aa; + out.str(""); + aa.f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/protected_error.cpp b/src/boost/libs/contract/test/public_function/protected_error.cpp new file mode 100644 index 00000000..f7e01d2f --- /dev/null +++ b/src/boost/libs/contract/test/public_function/protected_error.cpp @@ -0,0 +1,52 @@ + +// 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 a public function contract cannot override from a protected one. + +#include <boost/contract/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> + +struct b { +protected: + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this); + } + + friend class boost::contract::access; // Test this cannot prevent error. +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this); // Error (override cannot access b::f). + #ifdef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + #error "Forcing error even when public functions not checked" + #endif + } + + // Correctly, GCC and CLang cannot even see b::f as part of overloaded bases + // because it is protected. MSVC also fails compilation but only when + // override_f below tries to call b::f (because it is protected so it cannot + // be seen from within override_f). + BOOST_CONTRACT_OVERRIDE(f) + + friend class boost::contract::access; // Test this cannot prevent error. +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/public_function/smoke.cpp b/src/boost/libs/contract/test/public_function/smoke.cpp new file mode 100644 index 00000000..7463d047 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/smoke.cpp @@ -0,0 +1,104 @@ + +// 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 public member function subcontracting. + +#include "smoke.hpp" +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; + + a aa; // Test call to derived out-most leaf. + s_type s; s.value = "A"; + out.str(""); + result_type& r = aa.f(s); + + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + << "e::f::pre" << std::endl + << "c::f::pre" << std::endl + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "e::f::old" << std::endl + << "c::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::f::old" << std::endl + << "d::f::post" << std::endl + << "e::f::old" << std::endl + << "e::f::post" << std::endl + << "c::f::old" << std::endl + << "c::f::post" << std::endl + // No old call here because not a base object. + << "a::f::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 + + BOOST_TEST_EQ(r.value, "A"); + BOOST_TEST_EQ(s.value, "acde"); + BOOST_TEST_EQ(s.copies(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.evals(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 for local var. + + BOOST_TEST_EQ(aa.x.value, "aA"); + BOOST_TEST_EQ(aa.x.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.ctors(), aa.x.dtors() + 1); // 1 for member var. + + BOOST_TEST_EQ(aa.y.value, "cA"); + BOOST_TEST_EQ(aa.y.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.y.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.y.ctors(), aa.y.dtors() + 1); // 1 for member var. + + BOOST_TEST_EQ(aa.t<'d'>::z.value, "dA"); + BOOST_TEST_EQ(aa.t<'d'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'d'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'d'>::z.ctors(), aa.t<'d'>::z.dtors() + 1); // 1 member. + + BOOST_TEST_EQ(aa.t<'e'>::z.value, "eA"); + BOOST_TEST_EQ(aa.t<'e'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'e'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'e'>::z.ctors(), aa.t<'e'>::z.dtors() + 1); // 1 member. + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/smoke.hpp b/src/boost/libs/contract/test/public_function/smoke.hpp new file mode 100644 index 00000000..8ebec1bd --- /dev/null +++ b/src/boost/libs/contract/test/public_function/smoke.hpp @@ -0,0 +1,278 @@ + +#ifndef BOOST_CONTRACT_TEST_PUBLIC_FUNCTION_CONTRACTS_HPP_ +#define BOOST_CONTRACT_TEST_PUBLIC_FUNCTION_CONTRACTS_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 public member function subcontracting (also with old and return values). + +#include "../detail/oteststream.hpp" +#include "../detail/counter.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/override.hpp> +#include <boost/config.hpp> +#include <string> + +boost::contract::test::detail::oteststream out; + +struct s_tag; +typedef boost::contract::test::detail::counter<s_tag, std::string> s_type; + +struct except_error {}; + +struct result_type { + std::string value; + explicit result_type(std::string const& s) : value(s) {} + +private: // Test non-copyable and non-default-constructible result. + result_type(); + result_type(result_type const&); + result_type& operator=(result_type const&); +}; + +// Test base without additional bases and pure virtual. +template<char Id> +struct t { + static void static_invariant() { out << Id << "::static_inv" << std::endl; } + + void invariant() const { + out << Id << "::inv" << std::endl; + BOOST_CONTRACT_ASSERT(z.value != ""); + } + + struct z_tag; + typedef boost::contract::test::detail::counter<z_tag, std::string> z_type; + z_type z; + + t() { z.value.push_back(Id); } + + virtual result_type& f(s_type& s, boost::contract::virtual_* v = 0) = 0; +}; + +template<char Id> // Requires: Only pass lower case Id so it'll never be 'X'. +result_type& t<Id>::f(s_type& s, boost::contract::virtual_* v) { + std::ostringstream r; r << "none-" << Id; + static result_type result(r.str()); + boost::contract::old_ptr<z_type> old_z = + BOOST_CONTRACT_OLDOF(v, z_type::eval(z)); + boost::contract::old_ptr<s_type> old_s; + boost::contract::check c = boost::contract::public_function(v, result, this) + .precondition([&] { + out << Id << "::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(s.value[0] == Id || s.value[0] == 'X'); + }) + .old([&] { + out << Id << "::f::old" << std::endl; + old_s = BOOST_CONTRACT_OLDOF(v, s_type::eval(s)); + }) + .postcondition([&] (result_type const& result) { + out << Id << "::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(z.value == old_z->value + old_s->value); + BOOST_CONTRACT_ASSERT(s.value.find(old_z->value) != + std::string::npos); + BOOST_CONTRACT_ASSERT(result.value == old_s->value); + }) + .except([&] { + out << Id << "::f::except" << std::endl; + BOOST_CONTRACT_ASSERT(z.value == old_z->value); + BOOST_CONTRACT_ASSERT(s.value == old_s->value); + }) + ; + out << "t<" << Id << ">::f::body" << std::endl; + if(s.value == "X") throw except_error(); + return result; +} + +// Test base with other bases, multiple inheritance, and no subcontracting from +// protected and private bases (even if fully contracted). +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; } + + void invariant() const { + out << "c::inv" << std::endl; + BOOST_CONTRACT_ASSERT(y.value != ""); + } + + struct y_tag; + typedef boost::contract::test::detail::counter<y_tag, std::string> y_type; + y_type y; + + c() { y.value = "c"; } + + virtual result_type& f(s_type& s, boost::contract::virtual_* v = 0) + /* override */ { + static result_type result("none-c"); + boost::contract::old_ptr<y_type> old_y = + BOOST_CONTRACT_OLDOF(v, y_type::eval(y)); + boost::contract::old_ptr<s_type> old_s; + boost::contract::check c = boost::contract::public_function< + override_f>(v, result, &c::f, this, s) + .precondition([&] { + out << "c::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(s.value == "C" || s.value == "X"); + }) + .old([&] { + out << "c::f::old" << std::endl; + old_s = BOOST_CONTRACT_OLDOF(v, s_type::eval(s)); + }) + .postcondition([&] (result_type const& result) { + out << "c::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(y.value == old_y->value + old_s->value); + BOOST_CONTRACT_ASSERT(s.value.find(old_y->value) != + std::string::npos); + BOOST_CONTRACT_ASSERT(result.value == old_s->value); + }) + .except([&] { + out << "c::f::except" << std::endl; + BOOST_CONTRACT_ASSERT(y.value == old_y->value); + BOOST_CONTRACT_ASSERT(s.value == old_s->value); + }) + ; + + out << "c::f::body" << std::endl; + if(s.value == "X") throw except_error(); + std::string save_s = s.value; + + std::string save = y.value; + y.value += save_s; + s.value = save; + + save = t<'d'>::z.value; + t<'d'>::z.value += save_s; + s.value += save; + + save = t<'e'>::z.value; + t<'e'>::z.value += save_s; + s.value += save; + + result.value = save_s; + return result; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +// Test no subcontracting from not (fully) contracted base. +struct b { + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + virtual ~b() {} + + // No contract (no virtual_ so this is not actually overridden by a::f). + virtual result_type& f(s_type& s) { + static result_type result("none-b"); + out << "b::f::body" << std::endl; + result.value = s.value; + return result; + } +}; + +// Test public function 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; } + + void invariant() const { + out << "a::inv" << std::endl; + BOOST_CONTRACT_ASSERT(x.value != ""); + } + + struct x_tag; + typedef boost::contract::test::detail::counter<x_tag, std::string> x_type; + x_type x; + + a() { x.value = "a"; } + + #if defined(BOOST_GCC) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Woverloaded-virtual" // For a::f. + #elif defined(BOOST_CLANG) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Woverloaded-virtual" // For a::f. + #endif + + // Must use virtual_ even if no longer decl virtual for correct overloading. + // NOTE: This intentionally hides but does not override `b::f` (it overrides + // `c::f` instead). This generates warnings on some compilers (Clang, etc.). + result_type& f(s_type& s, boost::contract::virtual_* v = 0) + /* override */ { + static result_type result("none-a"); + boost::contract::old_ptr<x_type> old_x = + BOOST_CONTRACT_OLDOF(v, x_type::eval(x)); + boost::contract::old_ptr<s_type> old_s; + boost::contract::check c = boost::contract::public_function< + override_f>(v, result, &a::f, this, s) + .precondition([&] { + out << "a::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(s.value == "A" || s.value == "X"); + }) + .old([&] { + out << "a::f::old" << std::endl; + old_s = BOOST_CONTRACT_OLDOF(v, s_type::eval(s)); + }) + .postcondition([&] (result_type const& result) { + out << "a::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(x.value == old_x->value + old_s->value); + BOOST_CONTRACT_ASSERT(s.value.find(old_x->value) != + std::string::npos); + BOOST_CONTRACT_ASSERT(result.value == old_s->value); + }) + .except([&] { + out << "a::f::except" << std::endl; + BOOST_CONTRACT_ASSERT(x.value == old_x->value); + BOOST_CONTRACT_ASSERT(s.value == old_s->value); + }) + ; + + out << "a::f::body" << std::endl; + if(s.value == "X") throw except_error(); + std::string save_s = s.value; + + std::string save = x.value; + x.value += save_s; + s.value = save; + + save = y.value; + y.value += save_s; + s.value += save; + + save = t<'d'>::z.value; + t<'d'>::z.value += save_s; + s.value += save; + + save = t<'e'>::z.value; + t<'e'>::z.value += save_s; + s.value += save; + + result.value = save_s; + return result; + } + BOOST_CONTRACT_OVERRIDE(f) + + #if defined(BOOST_GCC) + #pragma GCC diagnostic pop + #elif defined(BOOST_CLANG) + #pragma clang diagnostic pop + #endif +}; + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/public_function/static.cpp b/src/boost/libs/contract/test/public_function/static.cpp new file mode 100644 index 00000000..010c965f --- /dev/null +++ b/src/boost/libs/contract/test/public_function/static.cpp @@ -0,0 +1,82 @@ + +// 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 public static member function contracts. + +#include "../detail/oteststream.hpp" +#include <boost/contract/base_types.hpp> +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct b { + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + static void f() { + boost::contract::check c = boost::contract::public_function<b>() + .precondition([] { out << "b::f::pre" << std::endl; }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + ; + out << "b::f::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; } + + static void f() { + boost::contract::check c = boost::contract::public_function<a>() + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + out.str(""); + a::f(); + ok.str(""); ok + // Static so no object thus only static inv, plus never virtual so subst + // principle does not apply and no subcontracting. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // No old call here because not base object. + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/static_ifdef.cpp b/src/boost/libs/contract/test/public_function/static_ifdef.cpp new file mode 100644 index 00000000..03212950 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/static_ifdef.cpp @@ -0,0 +1,74 @@ + +// 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 public static member function contract compilation on/off. + +#include "../detail/oteststream.hpp" +#include <boost/contract/core/config.hpp> +#ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + #include <boost/contract/public_function.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 a { + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + #endif + + static void f(int x) { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); + #endif + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + boost::contract::check c = boost::contract::public_function<a>() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + .precondition([] { out << "a::f::pre" << std::endl; }) + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + #endif + ; + #endif + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + out.str(""); + a::f(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + // Test no post (but still static inv) because body threw. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/static_ifdef_macro.cpp b/src/boost/libs/contract/test/public_function/static_ifdef_macro.cpp new file mode 100644 index 00000000..9f03cf21 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/static_ifdef_macro.cpp @@ -0,0 +1,90 @@ + +// 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 public static member function contract compilation on/off (w/ macros). + +#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 a { + 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; + }) + + static void f(int x) { + 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_STATIC_PUBLIC_FUNCTION(boost::contract::test::detail:: + unprotected_commas<a, void, void>::type1) + BOOST_CONTRACT_PRECONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::f::pre" << std::endl; + }) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::f::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::f::post" << std::endl; + }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + out.str(""); + a::f(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + // Test no post (but still static inv) because body threw. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/static_throwing_body.cpp b/src/boost/libs/contract/test/public_function/static_throwing_body.cpp new file mode 100644 index 00000000..37c0354f --- /dev/null +++ b/src/boost/libs/contract/test/public_function/static_throwing_body.cpp @@ -0,0 +1,67 @@ + +// 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 public static member function throwing. + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct a_err {}; // Global decl so visible in MSVC10 lambdas. + +struct a { + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + static void f() { + boost::contract::check c = boost::contract::public_function<a>() + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + .except([] { out << "a::f::except" << std::endl; }) + ; + out << "a::f::body" << std::endl; + throw a_err(); // Test this throws. + } +}; + +int main() { + std::ostringstream ok; + + try { + out.str(""); + a::f(); + BOOST_TEST(false); + } catch(a_err const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl // Test this threw. + // Test no post (but still static inv) because body threw. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "a::f::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/public_function/static_throwing_old.cpp b/src/boost/libs/contract/test/public_function/static_throwing_old.cpp new file mode 100644 index 00000000..04e96359 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/static_throwing_old.cpp @@ -0,0 +1,71 @@ + +// 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 public static member function .old(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct a_err {}; // Global decl so visible in MSVC10 lambdas. + +struct a { + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + static void f() { + boost::contract::check c = boost::contract::public_function<a>() + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { + out << "a::f::old" << std::endl; + throw a_err(); // Test this throws. + }) + .postcondition([] { out << "a::f::post" << std::endl; }) + .except([] { out << "a::f::except" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_old_failure([] (boost::contract::from) { throw; }); + + try { + out.str(""); + a::f(); + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(false); + } catch(a_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl // Test this threw. + #else + << "a::f::body" << std::endl + // Test no post (but still static inv) because .old() threw. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << 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/public_function/static_throwing_post.cpp b/src/boost/libs/contract/test/public_function/static_throwing_post.cpp new file mode 100644 index 00000000..b8414f8a --- /dev/null +++ b/src/boost/libs/contract/test/public_function/static_throwing_post.cpp @@ -0,0 +1,73 @@ + +// 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 public static member function .post(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct a_err {}; // Global decl so visible in MSVC10 lambdas. + +struct a { + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + static void f() { + boost::contract::check c = boost::contract::public_function<a>() + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { + out << "a::f::post" << std::endl; + throw a_err(); // Test this throws. + }) + .except([] { out << "a::f::except" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw; }); + + try { + out.str(""); + a::f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(a_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f::post" << std::endl // Test this threw. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/static_throwing_pre.cpp b/src/boost/libs/contract/test/public_function/static_throwing_pre.cpp new file mode 100644 index 00000000..79c38af0 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/static_throwing_pre.cpp @@ -0,0 +1,74 @@ + +// 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 public static member function .pre(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct a_err {}; // Global decl so visible in MSVC10 lambdas. + +struct a { + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + static void f() { + boost::contract::check c = boost::contract::public_function<a>() + .precondition([] { + out << "a::f::pre" << std::endl; + throw a_err(); // Test this throws. + }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + .except([] { out << "a::f::except" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw; }); + + try { + out.str(""); + a::f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(a_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::f::pre" << std::endl // Test this threw. + #else + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f::post" << 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/public_function/throwing_body.cpp b/src/boost/libs/contract/test/public_function/throwing_body.cpp new file mode 100644 index 00000000..40684a5a --- /dev/null +++ b/src/boost/libs/contract/test/public_function/throwing_body.cpp @@ -0,0 +1,106 @@ + +// 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 public member function body throws with subcontracting. + +#include "smoke.hpp" +#include <boost/optional.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; + + a aa; // Test call to derived out-most leaf. + s_type s; s.value = "X"; // So body will throw. + out.str(""); + boost::optional<result_type&> r; + try { + r = aa.f(s); + BOOST_TEST(false); + } catch(except_error const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "e::f::old" << std::endl + << "c::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "d::f::old" << std::endl + << "d::f::except" << std::endl + << "e::f::old" << std::endl + << "e::f::except" << std::endl + << "c::f::old" << std::endl + << "c::f::except" << std::endl + // No old call here because not a base object. + << "a::f::except" << 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 + + BOOST_TEST(!r); // Boost.Optional result not init (as body threw). + BOOST_TEST_EQ(s.value, "X"); + BOOST_TEST_EQ(s.copies(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.evals(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 for local var. + + BOOST_TEST_EQ(aa.x.value, "a"); + BOOST_TEST_EQ(aa.x.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.ctors(), aa.x.dtors() + 1); // 1 for member var. + + BOOST_TEST_EQ(aa.y.value, "c"); + BOOST_TEST_EQ(aa.y.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.y.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.y.ctors(), aa.y.dtors() + 1); // 1 for member var. + + BOOST_TEST_EQ(aa.t<'d'>::z.value, "d"); + BOOST_TEST_EQ(aa.t<'d'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'d'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'d'>::z.ctors(), aa.t<'d'>::z.dtors() + 1); // 1 mem. + + BOOST_TEST_EQ(aa.t<'e'>::z.value, "e"); + BOOST_TEST_EQ(aa.t<'e'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'e'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.t<'e'>::z.ctors(), aa.t<'e'>::z.dtors() + 1); // 1 mem. + + #undef BOOST_CONTRACT_TEST_old + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/throwing_body_virtual.cpp b/src/boost/libs/contract/test/public_function/throwing_body_virtual.cpp new file mode 100644 index 00000000..57d9acdd --- /dev/null +++ b/src/boost/libs/contract/test/public_function/throwing_body_virtual.cpp @@ -0,0 +1,108 @@ + +// 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 virtual public member function body throws with subcontracting. + +#include "smoke.hpp" +#include <boost/optional.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; + + a aa; // Test call to derived out-most leaf. + c& ca = aa; // Test polymorphic virtual call (via reference to base c). + s_type s; s.value = "X"; // So body will throw. + out.str(""); + boost::optional<result_type&> r; + try { + r = ca.f(s); + BOOST_TEST(false); + } catch(except_error const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "e::f::old" << std::endl + << "c::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "d::f::old" << std::endl + << "d::f::except" << std::endl + << "e::f::old" << std::endl + << "e::f::except" << std::endl + << "c::f::old" << std::endl + << "c::f::except" << std::endl + // No old call here because not a base object. + << "a::f::except" << 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 + + BOOST_TEST(!r); // Boost.Optional result not init (as body threw). + BOOST_TEST_EQ(s.value, "X"); + BOOST_TEST_EQ(s.copies(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.evals(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 for local var. + + // Cannot access x via ca, but only via aa. + BOOST_TEST_EQ(aa.x.value, "a"); + BOOST_TEST_EQ(aa.x.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.ctors(), aa.x.dtors() + 1); // 1 for member var. + + BOOST_TEST_EQ(ca.y.value, "c"); + BOOST_TEST_EQ(ca.y.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.y.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.y.ctors(), aa.y.dtors() + 1); // 1 for member var. + + BOOST_TEST_EQ(ca.t<'d'>::z.value, "d"); + BOOST_TEST_EQ(ca.t<'d'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'d'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'d'>::z.ctors(), aa.t<'d'>::z.dtors() + 1); // 1 mem. + + BOOST_TEST_EQ(ca.t<'e'>::z.value, "e"); + BOOST_TEST_EQ(ca.t<'e'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'e'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'e'>::z.ctors(), aa.t<'e'>::z.dtors() + 1); // 1 mem. + + #undef BOOST_CONTRACT_TEST_old + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/throwing_body_virtual_branch.cpp b/src/boost/libs/contract/test/public_function/throwing_body_virtual_branch.cpp new file mode 100644 index 00000000..dccc18d3 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/throwing_body_virtual_branch.cpp @@ -0,0 +1,94 @@ + +// 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 virt pub func body throws with subcontr from middle of inheritance tree. + +#include "smoke.hpp" +#include <boost/optional.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; + + c cc; // Test call to class at mid- inheritance tree (as base with bases). + s_type s; s.value = "X"; // So body will throw. + out.str(""); + boost::optional<result_type&> r; + try { + r = cc.f(s); + BOOST_TEST(false); + } catch(except_error const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "e::f::old" << std::endl + << "c::f::old" << std::endl + #endif + << "c::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "d::f::old" << std::endl + << "d::f::except" << std::endl + << "e::f::old" << std::endl + << "e::f::except" << std::endl + // No old call here because not a base object. + << "c::f::except" << 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 + + BOOST_TEST(!r); // Boost.Optional result not init (as body threw). + BOOST_TEST_EQ(s.value, "X"); + BOOST_TEST_EQ(s.copies(), BOOST_CONTRACT_TEST_old * 3); + BOOST_TEST_EQ(s.evals(), BOOST_CONTRACT_TEST_old * 3); + BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 for local var. + + BOOST_TEST_EQ(cc.y.value, "c"); + BOOST_TEST_EQ(cc.y.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.y.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.y.ctors(), cc.y.dtors() + 1); // 1 for member var. + + BOOST_TEST_EQ(cc.t<'d'>::z.value, "d"); + BOOST_TEST_EQ(cc.t<'d'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'d'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'d'>::z.ctors(), cc.t<'d'>::z.dtors() + 1); // 1 mem. + + BOOST_TEST_EQ(cc.t<'e'>::z.value, "e"); + BOOST_TEST_EQ(cc.t<'e'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'e'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'e'>::z.ctors(), cc.t<'e'>::z.dtors() + 1); // 1 mem. + + #undef BOOST_CONTRACT_TEST_old + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/throwing_old.cpp b/src/boost/libs/contract/test/public_function/throwing_old.cpp new file mode 100644 index 00000000..aec127fa --- /dev/null +++ b/src/boost/libs/contract/test/public_function/throwing_old.cpp @@ -0,0 +1,149 @@ + +// 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 public function (derived and bases) .old(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c_err {}; // Global decl so visible in MSVC10 lambdas. + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { + out << "c::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(false); // To check derived pre. + }) + .old([] { + out << "c::f::old" << std::endl; + throw c_err(); // Test this throws. + }) + .postcondition([] { out << "c::f::post" << std::endl; }) + .except([] { out << "c::f::except" << std::endl; }) + ; + out << "c::f::body" << std::endl; + } +}; + +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; } + + virtual void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &b::f, this) + .precondition([] { + out << "b::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(false); // To check derived pre. + }) + .old([] { + out << "b::f::old" << std::endl; + throw b_err(); // Test this throws. + }) + .postcondition([] { out << "b::f::post" << std::endl; }) + .except([] { out << "b::f::except" << std::endl; }) + ; + out << "b::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +struct a_err {}; // Global decl so visible in MSVC10 lambdas. + +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; } + + void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this) + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { + out << "a::f::old" << std::endl; + throw a_err(); // Test this throws. + }) + .postcondition([] { out << "a::f::post" << std::endl; }) + .except([] { out << "a::f::except" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_old_failure([] (boost::contract::from) { throw; }); + + a aa; + b& ba = aa; // Test as virtual call via polymorphism. + try { + out.str(""); + ba.f(); + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(false); + } catch(c_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl // Test this threw. + #else + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << 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/public_function/throwing_post.cpp b/src/boost/libs/contract/test/public_function/throwing_post.cpp new file mode 100644 index 00000000..038b0954 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/throwing_post.cpp @@ -0,0 +1,157 @@ + +// 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 public function (derived and bases) .post(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c_err {}; // Global decl so visible in MSVC10 lambdas. + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { + out << "c::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(false); // To check derived pre. + }) + .old([] { out << "c::f::old" << std::endl; }) + .postcondition([] { + out << "c::f::post" << std::endl; + // Test derived will throw. + }) + .except([] { out << "c::f::except" << std::endl; }) + ; + out << "c::f::body" << std::endl; + } +}; + +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; } + + virtual void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &b::f, this) + .precondition([] { + out << "b::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(false); // To check derived pre. + }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { + out << "b::f::post" << std::endl; + throw b_err(); // Test this (both derived and base) throws. + }) + .except([] { out << "b::f::except" << std::endl; }) + ; + out << "b::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +struct a_err {}; // Global decl so visible in MSVC10 lambdas. + +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; } + + void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this) + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { + out << "a::f::post" << std::endl; + throw a_err(); // Test base already threw. + }) + .except([] { out << "a::f::except" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw; }); + + a aa; + b& ba = aa; // Test as virtual call via polymorphism. + try { + out.str(""); + ba.f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(b_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl // Test this threw. + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/throwing_pre.cpp b/src/boost/libs/contract/test/public_function/throwing_pre.cpp new file mode 100644 index 00000000..23729121 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/throwing_pre.cpp @@ -0,0 +1,154 @@ + +// 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 public function (derived and bases) .pre(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c_err {}; // Global decl so visible in MSVC10 lambdas. + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { + out << "c::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(false); // To check derived pre. + }) + .old([] { out << "c::f::old" << std::endl; }) + .postcondition([] { out << "c::f::post" << std::endl; }) + .except([] { out << "c::f::except" << std::endl; }) + ; + out << "c::f::body" << std::endl; + } +}; + +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; } + + virtual void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &b::f, this) + .precondition([] { + out << "b::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(false); // To check derived pre. + }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + .except([] { out << "b::f::except" << std::endl; }) + ; + out << "b::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +struct a_err {}; // Global decl so visible in MSVC10 lambdas. + +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; } + + void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this) + .precondition([] { + out << "a::f::pre" << std::endl; + throw a_err(); // Test this throws. + }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + .except([] { out << "a::f::except" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw; }); + + a aa; + b& ba = aa; // Test as virtual call via polymorphism. + try { + out.str(""); + ba.f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(a_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + << "a::f::pre" << std::endl // Test this threw. + #else + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + // No old call here because not a base object. + << "a::f::post" << 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/public_function/virtual.cpp b/src/boost/libs/contract/test/public_function/virtual.cpp new file mode 100644 index 00000000..766182ae --- /dev/null +++ b/src/boost/libs/contract/test/public_function/virtual.cpp @@ -0,0 +1,106 @@ + +// 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 public function subcontracting via virtual functions. + +#include "smoke.hpp" +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; + + a aa; + c& ca = aa; // Test polymorphic virtual call (via reference to base c). + s_type s; s.value = "A"; + out.str(""); + result_type& r = ca.f(s); + + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + << "e::f::pre" << std::endl + << "c::f::pre" << std::endl + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "e::f::old" << std::endl + << "c::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::f::old" << std::endl + << "d::f::post" << std::endl + << "e::f::old" << std::endl + << "e::f::post" << std::endl + << "c::f::old" << std::endl + << "c::f::post" << std::endl + // No old call here because not a base object. + << "a::f::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 + + BOOST_TEST_EQ(r.value, "A"); + BOOST_TEST_EQ(s.value, "acde"); + BOOST_TEST_EQ(s.copies(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.evals(), BOOST_CONTRACT_TEST_old * 4); + BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 local var. + + // Cannot access x via ca, but only via aa. + BOOST_TEST_EQ(aa.x.value, "aA"); + BOOST_TEST_EQ(aa.x.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(aa.x.ctors(), aa.x.dtors() + 1); // 1 data member. + + BOOST_TEST_EQ(ca.y.value, "cA"); + BOOST_TEST_EQ(ca.y.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.y.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.y.ctors(), ca.y.dtors() + 1); // 1 data member. + + BOOST_TEST_EQ(ca.t<'d'>::z.value, "dA"); + BOOST_TEST_EQ(ca.t<'d'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'d'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'d'>::z.ctors(), ca.t<'d'>::z.dtors() + 1); // 1 member. + + BOOST_TEST_EQ(ca.t<'e'>::z.value, "eA"); + BOOST_TEST_EQ(ca.t<'e'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'e'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(ca.t<'e'>::z.ctors(), ca.t<'e'>::z.dtors() + 1); // 1 member. + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/virtual_access.cpp b/src/boost/libs/contract/test/public_function/virtual_access.cpp new file mode 100644 index 00000000..a83296a9 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/virtual_access.cpp @@ -0,0 +1,220 @@ + +// 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 overrides with mixed access level from (single) base. + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct b { // Test all access levels (public, protected, and private). + friend void call(b& me) { // Test polymorphic calls (object by &). + me.f(); + me.g(); + me.h(); + } + + static void statci_inv() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "b::f::pre" << std::endl; }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + ; + out << "b::f::body" << std::endl; + } + + // NOTE: Both protected and private virtual members must declare + // extra `virtual_* = 0` parameter (otherwise they cannot be overridden in + // derived classes with contracts because C++ uses also default parameters + // to match signature of overriding functions). + +protected: + virtual void g(boost::contract::virtual_* /* v */= 0) { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "b::g::pre" << std::endl; }) + .old([] { out << "b::g::old" << std::endl; }) + .postcondition([] { out << "b::g::post" << std::endl; }) + ; + out << "b::g::body" << std::endl; + } + +private: + virtual void h(boost::contract::virtual_* /* v */ = 0) { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "b::h::pre" << std::endl; }) + .old([] { out << "b::h::old" << std::endl; }) + .postcondition([] { out << "b::h::post" << std::endl; }) + ; + out << "b::h::body" << std::endl; + } +}; + +struct a // Test overrides with mixed access levels from base. + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void statci_inv() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this) + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDES(f) + + // Following do not override public members so no `override_...` param and + // they do not actually subcontract. + + virtual void g(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "a::g::pre" << std::endl; }) + .old([] { out << "a::g::old" << std::endl; }) + .postcondition([] { out << "a::g::post" << std::endl; }) + ; + out << "a::g::body" << std::endl; + } + + virtual void h(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "a::h::pre" << std::endl; }) + .old([] { out << "a::h::old" << std::endl; }) + .postcondition([] { out << "a::h::post" << std::endl; }) + ; + out << "a::h::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + b bb; + out.str(""); + call(bb); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + #endif + << "b::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::g::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::g::old" << std::endl + #endif + << "b::g::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::g::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::h::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::h::old" << std::endl + #endif + << "b::h::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::h::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + a aa; + out.str(""); + call(aa); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "a::f::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::g::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::g::old" << std::endl + #endif + << "a::g::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::g::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::h::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::h::old" << std::endl + #endif + << "a::h::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::h::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/virtual_access_multi.cpp b/src/boost/libs/contract/test/public_function/virtual_access_multi.cpp new file mode 100644 index 00000000..70bebad4 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/virtual_access_multi.cpp @@ -0,0 +1,283 @@ + +// 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 overrides with mixed access levels from different (multiple) bases. + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + +// WARNING: MSVC (at least up to VS 2015) gives a compile-time error if SFINAE +// cannot introspect a member because of its private or protected access level. +// That is incorrect, SFINAE should fail in these cases without generating +// compile-time errors like GCC and CLang do. Therefore, currently it is not +// possible to override a member that is public in one base but private or +// protected in other base using this library on MSVC (that can be done instead +// using this library on GCC or CLang). +int main() { return 0; } // This test trivially passes on MSVC. + +#else + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c { // Test public access different from base `b`'s access below. + static void statci_inv() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "c::f::pre" << std::endl; }) + .old([] { out << "c::f::old" << std::endl; }) + .postcondition([] { out << "c::f::post" << std::endl; }) + ; + out << "c::f::body" << std::endl; + } + + virtual void g(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "c::g::pre" << std::endl; }) + .old([] { out << "c::g::old" << std::endl; }) + .postcondition([] { out << "c::g::post" << std::endl; }) + ; + out << "c::g::body" << std::endl; + } + + virtual void h(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "c::h::pre" << std::endl; }) + .old([] { out << "c::h::old" << std::endl; }) + .postcondition([] { out << "c::h::post" << std::endl; }) + ; + out << "c::h::body" << std::endl; + } +}; + +struct b { // Test all access levels (public, protected, and private). + friend void call(b& me) { // Test polymorphic calls (object by &). + me.f(); + me.g(); + me.h(); + } + + static void statci_inv() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([] { out << "b::f::pre" << std::endl; }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + ; + out << "b::f::body" << std::endl; + } + + // NOTE: Both protected and private virtual members must declare + // extra `virtual_* = 0` parameter (otherwise they cannot be overridden in + // derived classes with contracts because C++ uses also default parameters + // to match signature of overriding functions). + +protected: + virtual void g(boost::contract::virtual_* /* v */ = 0) { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "b::g::pre" << std::endl; }) + .old([] { out << "b::g::old" << std::endl; }) + .postcondition([] { out << "b::g::post" << std::endl; }) + ; + out << "b::g::body" << std::endl; + } + +private: + virtual void h(boost::contract::virtual_* /* v */ = 0) { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "b::h::pre" << std::endl; }) + .old([] { out << "b::h::old" << std::endl; }) + .postcondition([] { out << "b::h::post" << std::endl; }) + ; + out << "b::h::body" << std::endl; + } +}; + +struct a // Test overrides with mixed access levels from different bases. + #define BASES public b, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void statci_inv() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + virtual void f(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_f>( + v, &a::f, this) + .precondition([] { out << "a::f::pre" << std::endl; }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } + + virtual void g(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_g>( + v, &a::g, this) + .precondition([] { out << "a::g::pre" << std::endl; }) + .old([] { out << "a::g::old" << std::endl; }) + .postcondition([] { out << "a::g::post" << std::endl; }) + ; + out << "a::g::body" << std::endl; + } + + virtual void h(boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function<override_h>( + v, &a::h, this) + .precondition([] { out << "a::h::pre" << std::endl; }) + .old([] { out << "a::h::old" << std::endl; }) + .postcondition([] { out << "a::h::post" << std::endl; }) + ; + out << "a::h::body" << std::endl; + } + + BOOST_CONTRACT_OVERRIDES(f, g, h) +}; + +int main() { + std::ostringstream ok; + + b bb; + out.str(""); + call(bb); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + #endif + << "b::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::g::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::g::old" << std::endl + #endif + << "b::g::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::g::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::h::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::h::old" << std::endl + #endif + << "b::h::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::h::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + a aa; + out.str(""); + call(aa); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + << "c::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + << "c::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + << "c::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "a::f::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::g::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::g::old" << std::endl + << "a::g::old" << std::endl + #endif + << "a::g::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::g::old" << std::endl + << "c::g::post" << std::endl + << "a::g::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::h::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::h::old" << std::endl + << "a::h::old" << std::endl + #endif + << "a::h::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::h::old" << std::endl + << "c::h::post" << std::endl + << "a::h::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + +#endif // MSVC + diff --git a/src/boost/libs/contract/test/public_function/virtual_branch.cpp b/src/boost/libs/contract/test/public_function/virtual_branch.cpp new file mode 100644 index 00000000..b3c47351 --- /dev/null +++ b/src/boost/libs/contract/test/public_function/virtual_branch.cpp @@ -0,0 +1,90 @@ + +// 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 public function subcontracting from middle branch of inheritance tree. + +#include "smoke.hpp" +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; + + c cc; // Test call to class at mid- inheritance tree (a base with bases). + s_type s; s.value = "C"; + out.str(""); + result_type& r = cc.f(s); + + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + << "e::f::pre" << std::endl + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "e::f::old" << std::endl + << "c::f::old" << std::endl + #endif + << "c::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::f::old" << std::endl + << "d::f::post" << std::endl + << "e::f::old" << std::endl + << "e::f::post" << std::endl + // No old call here because not a base object. + << "c::f::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 + + BOOST_TEST_EQ(r.value, "C"); + BOOST_TEST_EQ(s.value, "cde"); + BOOST_TEST_EQ(s.copies(), BOOST_CONTRACT_TEST_old * 3); + BOOST_TEST_EQ(s.evals(), BOOST_CONTRACT_TEST_old * 3); + BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 local var. + + BOOST_TEST_EQ(cc.y.value, "cC"); + BOOST_TEST_EQ(cc.y.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.y.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.y.ctors(), cc.y.dtors() + 1); // 1 data member. + + BOOST_TEST_EQ(cc.t<'d'>::z.value, "dC"); + BOOST_TEST_EQ(cc.t<'d'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'d'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'d'>::z.ctors(), cc.t<'d'>::z.dtors() + 1); // 1 member. + + BOOST_TEST_EQ(cc.t<'e'>::z.value, "eC"); + BOOST_TEST_EQ(cc.t<'e'>::z.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'e'>::z.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(cc.t<'e'>::z.ctors(), cc.t<'e'>::z.dtors() + 1); // 1 member. + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/public_function/virtual_sparse.cpp b/src/boost/libs/contract/test/public_function/virtual_sparse.cpp new file mode 100644 index 00000000..09d76d6f --- /dev/null +++ b/src/boost/libs/contract/test/public_function/virtual_sparse.cpp @@ -0,0 +1,418 @@ + +// 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 subcontracting with sparse and complex inheritance graph. + +#include "../detail/oteststream.hpp" +#include <boost/contract/public_function.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct j { + static void static_invariant() { out << "j::static_inv" << std::endl; } + void invariant() const { out << "j::inv" << std::endl; } + + virtual void f(char ch, boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([&] { + out << "j::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'j'); + }) + .old([] { out << "j::f::old" << std::endl; }) + .postcondition([] { out << "j::f::post" << std::endl; }) + ; + out << "j::f::body" << std::endl; + } +}; + +struct i { + static void static_invariant() { out << "i::static_inv" << std::endl; } + void invariant() const { out << "i::inv" << std::endl; } + + virtual void f(char ch, boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([&] { + out << "i::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'i'); + }) + .old([] { out << "i::f::old" << std::endl; }) + .postcondition([] { out << "i::f::post" << std::endl; }) + ; + out << "i::f::body" << std::endl; + } +}; + +struct k {}; + +struct h + #define BASES public j + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "h::static_inv" << std::endl; } + void invariant() const { out << "h::inv" << std::endl; } + + virtual void f(char ch, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function< + override_f>(v, &h::f, this, ch) + .precondition([&] { + out << "h::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'h'); + }) + .old([] { out << "h::f::old" << std::endl; }) + .postcondition([] { out << "h::f::post" << std::endl; }) + ; + out << "h::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +struct e + #define BASES public virtual i + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "e::static_inv" << std::endl; } + void invariant() const { out << "e::inv" << std::endl; } + + virtual void f(char ch, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function< + override_f>(v, &e::f, this, ch) + .precondition([&] { + out << "e::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'e'); + }) + .old([] { out << "e::f::old" << std::endl; }) + .postcondition([] { out << "e::f::post" << std::endl; }) + ; + out << "e::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +struct d + #define BASES public k, virtual public i + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "d::static_inv" << std::endl; } + void invariant() const { out << "d::inv" << std::endl; } +}; + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + virtual void f(char ch, boost::contract::virtual_* v = 0) { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([&] { + out << "c::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'c'); + }) + .old([] { out << "c::f::old" << std::endl; }) + .postcondition([] { out << "c::f::post" << std::endl; }) + ; + out << "c::f::body" << std::endl; + } +}; + +struct b + #define BASES public c, public d + : 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; } +}; + +struct x {}; +struct y {}; +struct z {}; + +struct a + #define BASES public b, public x, public e, protected y, public h, \ + private z + : 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; } + + virtual void f(char ch, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function< + override_f>(v, &a::f, this, ch) + .precondition([&] { + out << "a::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch == 'a'); + }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + std::ostringstream ok; + + a aa; + out.str(""); + aa.f('a'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "i::static_inv" << std::endl + << "i::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "j::static_inv" << std::endl + << "j::inv" << std::endl + << "h::static_inv" << std::endl + << "h::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + << "i::f::pre" << std::endl + << "e::f::pre" << std::endl + << "j::f::pre" << std::endl + << "h::f::pre" << std::endl + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + << "i::f::old" << std::endl + << "e::f::old" << std::endl + << "j::f::old" << std::endl + << "h::f::old" << std::endl + << "a::f::old" << std::endl + #endif + << "a::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "i::static_inv" << std::endl + << "i::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + << "j::static_inv" << std::endl + << "j::inv" << std::endl + << "h::static_inv" << std::endl + << "h::inv" << std::endl + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "i::f::old" << std::endl + << "i::f::post" << std::endl + << "e::f::old" << std::endl + << "e::f::post" << std::endl + << "j::f::old" << std::endl + << "j::f::post" << std::endl + << "h::f::old" << std::endl + << "h::f::post" << std::endl + // No old call here because not a base object. + << "a::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + c cc; + out.str(""); + cc.f('c'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::f::old" << std::endl + #endif + << "c::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // No old call here because not a base object. + << "c::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + d dd; + out.str(""); + dd.f('i'); // d's f inherited from i. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "i::static_inv" << std::endl + << "i::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "i::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "i::f::old" << std::endl + #endif + << "i::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "i::static_inv" << std::endl + << "i::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // No old call here because not a base object. + << "i::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + e ee; + out.str(""); + ee.f('e'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "i::static_inv" << std::endl + << "i::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "i::f::pre" << std::endl + << "e::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "i::f::old" << std::endl + << "e::f::old" << std::endl + #endif + << "e::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "i::static_inv" << std::endl + << "i::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "i::f::old" << std::endl + << "i::f::post" << std::endl + // No old call here because not a base object. + << "e::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + i ii; + out.str(""); + ii.f('i'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "i::static_inv" << std::endl + << "i::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "i::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "i::f::old" << std::endl + #endif + << "i::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "i::static_inv" << std::endl + << "i::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // No old call here because not a base object. + << "i::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + h hh; + out.str(""); + hh.f('h'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "j::static_inv" << std::endl + << "j::inv" << std::endl + << "h::static_inv" << std::endl + << "h::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "j::f::pre" << std::endl + << "h::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "j::f::old" << std::endl + << "h::f::old" << std::endl + #endif + << "h::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "j::static_inv" << std::endl + << "j::inv" << std::endl + << "h::static_inv" << std::endl + << "h::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "j::f::old" << std::endl + << "j::f::post" << std::endl + // No old call here because not a base object. + << "h::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + j jj; + out.str(""); + jj.f('j'); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "j::static_inv" << std::endl + << "j::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "j::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "j::f::old" << std::endl + #endif + << "j::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "j::static_inv" << std::endl + << "j::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // No old call here because not a base object. + << "j::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + |